summaryrefslogtreecommitdiff
path: root/AppPkg
diff options
context:
space:
mode:
authorDaryl McDaniel <edk2-lists@mc2research.org>2015-11-07 19:29:24 +0000
committerdarylm503 <darylm503@Edk2>2015-11-07 19:29:24 +0000
commit53b2ba5790b57b3dcdfbb9fa5835a979d94908fa (patch)
tree7ede18cf681440da2da531e693d26e3cee6359db /AppPkg
parent7eb75bccb5dacb658c63db1a9a980950c3d54d42 (diff)
downloadedk2-platforms-53b2ba5790b57b3dcdfbb9fa5835a979d94908fa.tar.xz
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 3/5.
The Objects directory from the cPython 2.7.10 distribution, along with the LICENSE and README files. These files are unchanged and set the baseline for subsequent commits. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daryl McDaniel <edk2-lists@mc2research.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18739 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'AppPkg')
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/LICENSE254
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/abstract.c3109
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/boolobject.c202
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/bufferobject.c878
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/bytearrayobject.c3052
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/bytes_methods.c398
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/capsule.c324
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/cellobject.c145
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/classobject.c2696
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/cobject.c172
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/codeobject.c581
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/complexobject.c1357
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/descrobject.c1440
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/dictnotes.txt270
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/dictobject.c3248
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/enumobject.c381
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/exceptions.c2231
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/fileobject.c2889
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/floatobject.c2708
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/frameobject.c984
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/funcobject.c895
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/genobject.c417
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/intobject.c1581
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/iterobject.c230
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c3045
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/listsort.txt755
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/lnotab_notes.txt124
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c842
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/methodobject.c427
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/moduleobject.c262
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/object.c2513
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/obmalloc.c1937
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/rangeobject.c347
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/setobject.c2514
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/sliceobject.c362
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/README.txt40
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/count.h30
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/ctype.h109
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/fastsearch.h160
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/find.h175
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/formatter.h1539
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/partition.h110
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/split.h394
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/string_format.h1361
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/stringdefs.h33
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/transmogrify.h264
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/unicodedefs.h37
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/stringobject.c4847
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/structseq.c540
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/tupleobject.c1040
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/typeobject.c6748
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/unicodectype.c215
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/unicodeobject.c8994
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/unicodetype_db.h3337
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/Objects/weakrefobject.c981
-rw-r--r--AppPkg/Applications/Python/Python-2.7.10/README1236
56 files changed, 75760 insertions, 0 deletions
diff --git a/AppPkg/Applications/Python/Python-2.7.10/LICENSE b/AppPkg/Applications/Python/Python-2.7.10/LICENSE
new file mode 100644
index 0000000000..d89dbe57c8
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/LICENSE
@@ -0,0 +1,254 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC. Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team. In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com). In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property. Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition). Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+ Release Derived Year Owner GPL-
+ from compatible? (1)
+
+ 0.9.0 thru 1.2 1991-1995 CWI yes
+ 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
+ 1.6 1.5.2 2000 CNRI no
+ 2.0 1.6 2000 BeOpen.com no
+ 1.6.1 1.6 2001 CNRI yes (2)
+ 2.1 2.0+1.6.1 2001 PSF no
+ 2.0.1 2.0+1.6.1 2001 PSF yes
+ 2.1.1 2.1+2.0.1 2001 PSF yes
+ 2.1.2 2.1.1 2002 PSF yes
+ 2.1.3 2.1.2 2002 PSF yes
+ 2.2 and above 2.1.1 2001-now PSF yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+ the GPL. All Python licenses, unlike the GPL, let you distribute
+ a modified version without making your changes open source. The
+ GPL-compatible licenses make it possible to combine Python with
+ other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+ because its license has a choice of law clause. According to
+ CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+ is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
+are retained in Python alone or in any derivative version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee. This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions. Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee. This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party. As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee. Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement. This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013. This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee. This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+ ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands. All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/abstract.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/abstract.c
new file mode 100644
index 0000000000..2a82325241
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/abstract.c
@@ -0,0 +1,3109 @@
+/* Abstract Object Interface (many thanks to Jim Fulton) */
+
+#include "Python.h"
+#include <ctype.h>
+#include "structmember.h" /* we need the offsetof() macro from there */
+#include "longintrepr.h"
+
+#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
+ Py_TPFLAGS_CHECKTYPES)
+
+
+/* Shorthands to return certain errors */
+
+static PyObject *
+type_error(const char *msg, PyObject *obj)
+{
+ PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+null_error(void)
+{
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError,
+ "null argument to internal routine");
+ return NULL;
+}
+
+/* Operations on any object */
+
+int
+PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
+{
+ int r;
+
+ if (o1 == NULL || o2 == NULL) {
+ null_error();
+ return -1;
+ }
+ r = PyObject_Compare(o1, o2);
+ if (PyErr_Occurred())
+ return -1;
+ *result = r;
+ return 0;
+}
+
+PyObject *
+PyObject_Type(PyObject *o)
+{
+ PyObject *v;
+
+ if (o == NULL)
+ return null_error();
+ v = (PyObject *)o->ob_type;
+ Py_INCREF(v);
+ return v;
+}
+
+Py_ssize_t
+PyObject_Size(PyObject *o)
+{
+ PySequenceMethods *m;
+
+ if (o == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = o->ob_type->tp_as_sequence;
+ if (m && m->sq_length)
+ return m->sq_length(o);
+
+ return PyMapping_Size(o);
+}
+
+#undef PyObject_Length
+Py_ssize_t
+PyObject_Length(PyObject *o)
+{
+ return PyObject_Size(o);
+}
+#define PyObject_Length PyObject_Size
+
+
+/* The length hint function returns a non-negative value from o.__len__()
+ or o.__length_hint__(). If those methods aren't found or return a negative
+ value, then the defaultvalue is returned. If one of the calls fails,
+ this function returns -1.
+*/
+
+Py_ssize_t
+_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
+{
+ static PyObject *hintstrobj = NULL;
+ PyObject *ro, *hintmeth;
+ Py_ssize_t rv;
+
+ /* try o.__len__() */
+ rv = PyObject_Size(o);
+ if (rv >= 0)
+ return rv;
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
+ !PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ }
+
+ if (PyInstance_Check(o))
+ return defaultvalue;
+ /* try o.__length_hint__() */
+ hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
+ if (hintmeth == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ else
+ return defaultvalue;
+ }
+ ro = PyObject_CallFunctionObjArgs(hintmeth, NULL);
+ Py_DECREF(hintmeth);
+ if (ro == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
+ !PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ return defaultvalue;
+ }
+ rv = PyNumber_Check(ro) ? PyInt_AsSsize_t(ro) : defaultvalue;
+ Py_DECREF(ro);
+ return rv;
+}
+
+PyObject *
+PyObject_GetItem(PyObject *o, PyObject *key)
+{
+ PyMappingMethods *m;
+
+ if (o == NULL || key == NULL)
+ return null_error();
+
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_subscript)
+ return m->mp_subscript(o, key);
+
+ if (o->ob_type->tp_as_sequence) {
+ if (PyIndex_Check(key)) {
+ Py_ssize_t key_value;
+ key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ if (key_value == -1 && PyErr_Occurred())
+ return NULL;
+ return PySequence_GetItem(o, key_value);
+ }
+ else if (o->ob_type->tp_as_sequence->sq_item)
+ return type_error("sequence index must "
+ "be integer, not '%.200s'", key);
+ }
+
+ return type_error("'%.200s' object has no attribute '__getitem__'", o);
+}
+
+int
+PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
+{
+ PyMappingMethods *m;
+
+ if (o == NULL || key == NULL || value == NULL) {
+ null_error();
+ return -1;
+ }
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_ass_subscript)
+ return m->mp_ass_subscript(o, key, value);
+
+ if (o->ob_type->tp_as_sequence) {
+ if (PyIndex_Check(key)) {
+ Py_ssize_t key_value;
+ key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ if (key_value == -1 && PyErr_Occurred())
+ return -1;
+ return PySequence_SetItem(o, key_value, value);
+ }
+ else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+ type_error("sequence index must be "
+ "integer, not '%.200s'", key);
+ return -1;
+ }
+ }
+
+ type_error("'%.200s' object does not support item assignment", o);
+ return -1;
+}
+
+int
+PyObject_DelItem(PyObject *o, PyObject *key)
+{
+ PyMappingMethods *m;
+
+ if (o == NULL || key == NULL) {
+ null_error();
+ return -1;
+ }
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_ass_subscript)
+ return m->mp_ass_subscript(o, key, (PyObject*)NULL);
+
+ if (o->ob_type->tp_as_sequence) {
+ if (PyIndex_Check(key)) {
+ Py_ssize_t key_value;
+ key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ if (key_value == -1 && PyErr_Occurred())
+ return -1;
+ return PySequence_DelItem(o, key_value);
+ }
+ else if (o->ob_type->tp_as_sequence->sq_ass_item) {
+ type_error("sequence index must be "
+ "integer, not '%.200s'", key);
+ return -1;
+ }
+ }
+
+ type_error("'%.200s' object does not support item deletion", o);
+ return -1;
+}
+
+int
+PyObject_DelItemString(PyObject *o, char *key)
+{
+ PyObject *okey;
+ int ret;
+
+ if (o == NULL || key == NULL) {
+ null_error();
+ return -1;
+ }
+ okey = PyString_FromString(key);
+ if (okey == NULL)
+ return -1;
+ ret = PyObject_DelItem(o, okey);
+ Py_DECREF(okey);
+ return ret;
+}
+
+int
+PyObject_AsCharBuffer(PyObject *obj,
+ const char **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ char *pp;
+ Py_ssize_t len;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = obj->ob_type->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getcharbuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a character buffer object");
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(obj,NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a single-segment buffer object");
+ return -1;
+ }
+ len = (*pb->bf_getcharbuffer)(obj, 0, &pp);
+ if (len < 0)
+ return -1;
+ *buffer = pp;
+ *buffer_len = len;
+ return 0;
+}
+
+int
+PyObject_CheckReadBuffer(PyObject *obj)
+{
+ PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
+
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL ||
+ (*pb->bf_getsegcount)(obj, NULL) != 1)
+ return 0;
+ return 1;
+}
+
+int PyObject_AsReadBuffer(PyObject *obj,
+ const void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ void *pp;
+ Py_ssize_t len;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = obj->ob_type->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a readable buffer object");
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a single-segment buffer object");
+ return -1;
+ }
+ len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
+ if (len < 0)
+ return -1;
+ *buffer = pp;
+ *buffer_len = len;
+ return 0;
+}
+
+int PyObject_AsWriteBuffer(PyObject *obj,
+ void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ PyBufferProcs *pb;
+ void*pp;
+ Py_ssize_t len;
+
+ if (obj == NULL || buffer == NULL || buffer_len == NULL) {
+ null_error();
+ return -1;
+ }
+ pb = obj->ob_type->tp_as_buffer;
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a writeable buffer object");
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a single-segment buffer object");
+ return -1;
+ }
+ len = (*pb->bf_getwritebuffer)(obj,0,&pp);
+ if (len < 0)
+ return -1;
+ *buffer = pp;
+ *buffer_len = len;
+ return 0;
+}
+
+/* Buffer C-API for Python 3.0 */
+
+int
+PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
+{
+ if (!PyObject_CheckBuffer(obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "'%100s' does not have the buffer interface",
+ Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+ return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
+}
+
+static int
+_IsFortranContiguous(Py_buffer *view)
+{
+ Py_ssize_t sd, dim;
+ int i;
+
+ if (view->ndim == 0) return 1;
+ if (view->strides == NULL) return (view->ndim == 1);
+
+ sd = view->itemsize;
+ if (view->ndim == 1) return (view->shape[0] == 1 ||
+ sd == view->strides[0]);
+ for (i=0; i<view->ndim; i++) {
+ dim = view->shape[i];
+ if (dim == 0) return 1;
+ if (view->strides[i] != sd) return 0;
+ sd *= dim;
+ }
+ return 1;
+}
+
+static int
+_IsCContiguous(Py_buffer *view)
+{
+ Py_ssize_t sd, dim;
+ int i;
+
+ if (view->ndim == 0) return 1;
+ if (view->strides == NULL) return 1;
+
+ sd = view->itemsize;
+ if (view->ndim == 1) return (view->shape[0] == 1 ||
+ sd == view->strides[0]);
+ for (i=view->ndim-1; i>=0; i--) {
+ dim = view->shape[i];
+ if (dim == 0) return 1;
+ if (view->strides[i] != sd) return 0;
+ sd *= dim;
+ }
+ return 1;
+}
+
+int
+PyBuffer_IsContiguous(Py_buffer *view, char fort)
+{
+
+ if (view->suboffsets != NULL) return 0;
+
+ if (fort == 'C')
+ return _IsCContiguous(view);
+ else if (fort == 'F')
+ return _IsFortranContiguous(view);
+ else if (fort == 'A')
+ return (_IsCContiguous(view) || _IsFortranContiguous(view));
+ return 0;
+}
+
+
+void*
+PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
+{
+ char* pointer;
+ int i;
+ pointer = (char *)view->buf;
+ for (i = 0; i < view->ndim; i++) {
+ pointer += view->strides[i]*indices[i];
+ if ((view->suboffsets != NULL) && (view->suboffsets[i] >= 0)) {
+ pointer = *((char**)pointer) + view->suboffsets[i];
+ }
+ }
+ return (void*)pointer;
+}
+
+
+void
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
+{
+ int k;
+
+ for (k=0; k<nd; k++) {
+ if (index[k] < shape[k]-1) {
+ index[k]++;
+ break;
+ }
+ else {
+ index[k] = 0;
+ }
+ }
+}
+
+void
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
+{
+ int k;
+
+ for (k=nd-1; k>=0; k--) {
+ if (index[k] < shape[k]-1) {
+ index[k]++;
+ break;
+ }
+ else {
+ index[k] = 0;
+ }
+ }
+}
+
+ /* view is not checked for consistency in either of these. It is
+ assumed that the size of the buffer is view->len in
+ view->len / view->itemsize elements.
+ */
+
+int
+PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
+{
+ int k;
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
+ Py_ssize_t *indices, elements;
+ char *dest, *ptr;
+
+ if (len > view->len) {
+ len = view->len;
+ }
+
+ if (PyBuffer_IsContiguous(view, fort)) {
+ /* simplest copy is all that is needed */
+ memcpy(buf, view->buf, len);
+ return 0;
+ }
+
+ /* Otherwise a more elaborate scheme is needed */
+
+ /* view->ndim <= 64 */
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ for (k=0; k<view->ndim;k++) {
+ indices[k] = 0;
+ }
+
+ if (fort == 'F') {
+ addone = _Py_add_one_to_index_F;
+ }
+ else {
+ addone = _Py_add_one_to_index_C;
+ }
+ dest = buf;
+ /* XXX : This is not going to be the fastest code in the world
+ several optimizations are possible.
+ */
+ elements = len / view->itemsize;
+ while (elements--) {
+ ptr = PyBuffer_GetPointer(view, indices);
+ memcpy(dest, ptr, view->itemsize);
+ dest += view->itemsize;
+ addone(view->ndim, indices, view->shape);
+ }
+ PyMem_Free(indices);
+ return 0;
+}
+
+int
+PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
+{
+ int k;
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
+ Py_ssize_t *indices, elements;
+ char *src, *ptr;
+
+ if (len > view->len) {
+ len = view->len;
+ }
+
+ if (PyBuffer_IsContiguous(view, fort)) {
+ /* simplest copy is all that is needed */
+ memcpy(view->buf, buf, len);
+ return 0;
+ }
+
+ /* Otherwise a more elaborate scheme is needed */
+
+ /* view->ndim <= 64 */
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ for (k=0; k<view->ndim;k++) {
+ indices[k] = 0;
+ }
+
+ if (fort == 'F') {
+ addone = _Py_add_one_to_index_F;
+ }
+ else {
+ addone = _Py_add_one_to_index_C;
+ }
+ src = buf;
+ /* XXX : This is not going to be the fastest code in the world
+ several optimizations are possible.
+ */
+ elements = len / view->itemsize;
+ while (elements--) {
+ ptr = PyBuffer_GetPointer(view, indices);
+ memcpy(ptr, src, view->itemsize);
+ src += view->itemsize;
+ addone(view->ndim, indices, view->shape);
+ }
+
+ PyMem_Free(indices);
+ return 0;
+}
+
+int PyObject_CopyData(PyObject *dest, PyObject *src)
+{
+ Py_buffer view_dest, view_src;
+ int k;
+ Py_ssize_t *indices, elements;
+ char *dptr, *sptr;
+
+ if (!PyObject_CheckBuffer(dest) ||
+ !PyObject_CheckBuffer(src)) {
+ PyErr_SetString(PyExc_TypeError,
+ "both destination and source must have the "\
+ "buffer interface");
+ return -1;
+ }
+
+ if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
+ if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
+ PyBuffer_Release(&view_dest);
+ return -1;
+ }
+
+ if (view_dest.len < view_src.len) {
+ PyErr_SetString(PyExc_BufferError,
+ "destination is too small to receive data from source");
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
+ return -1;
+ }
+
+ if ((PyBuffer_IsContiguous(&view_dest, 'C') &&
+ PyBuffer_IsContiguous(&view_src, 'C')) ||
+ (PyBuffer_IsContiguous(&view_dest, 'F') &&
+ PyBuffer_IsContiguous(&view_src, 'F'))) {
+ /* simplest copy is all that is needed */
+ memcpy(view_dest.buf, view_src.buf, view_src.len);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
+ return 0;
+ }
+
+ /* Otherwise a more elaborate copy scheme is needed */
+
+ /* XXX(nnorwitz): need to check for overflow! */
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
+ return -1;
+ }
+ for (k=0; k<view_src.ndim;k++) {
+ indices[k] = 0;
+ }
+ elements = 1;
+ for (k=0; k<view_src.ndim; k++) {
+ /* XXX(nnorwitz): can this overflow? */
+ elements *= view_src.shape[k];
+ }
+ while (elements--) {
+ _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
+ dptr = PyBuffer_GetPointer(&view_dest, indices);
+ sptr = PyBuffer_GetPointer(&view_src, indices);
+ memcpy(dptr, sptr, view_src.itemsize);
+ }
+ PyMem_Free(indices);
+ PyBuffer_Release(&view_dest);
+ PyBuffer_Release(&view_src);
+ return 0;
+}
+
+void
+PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
+ Py_ssize_t *strides, int itemsize,
+ char fort)
+{
+ int k;
+ Py_ssize_t sd;
+
+ sd = itemsize;
+ if (fort == 'F') {
+ for (k=0; k<nd; k++) {
+ strides[k] = sd;
+ sd *= shape[k];
+ }
+ }
+ else {
+ for (k=nd-1; k>=0; k--) {
+ strides[k] = sd;
+ sd *= shape[k];
+ }
+ }
+ return;
+}
+
+int
+PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
+ int readonly, int flags)
+{
+ if (view == NULL) return 0;
+ if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
+ (readonly == 1)) {
+ PyErr_SetString(PyExc_BufferError,
+ "Object is not writable.");
+ return -1;
+ }
+
+ view->obj = obj;
+ if (obj)
+ Py_INCREF(obj);
+ view->buf = buf;
+ view->len = len;
+ view->readonly = readonly;
+ view->itemsize = 1;
+ view->format = NULL;
+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
+ view->format = "B";
+ view->ndim = 1;
+ view->shape = NULL;
+ if ((flags & PyBUF_ND) == PyBUF_ND)
+ view->shape = &(view->len);
+ view->strides = NULL;
+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
+ view->strides = &(view->itemsize);
+ view->suboffsets = NULL;
+ view->internal = NULL;
+ return 0;
+}
+
+void
+PyBuffer_Release(Py_buffer *view)
+{
+ PyObject *obj = view->obj;
+ if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
+ Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
+ Py_XDECREF(obj);
+ view->obj = NULL;
+}
+
+PyObject *
+PyObject_Format(PyObject* obj, PyObject *format_spec)
+{
+ PyObject *empty = NULL;
+ PyObject *result = NULL;
+#ifdef Py_USING_UNICODE
+ int spec_is_unicode;
+ int result_is_unicode;
+#endif
+
+ /* If no format_spec is provided, use an empty string */
+ if (format_spec == NULL) {
+ empty = PyString_FromStringAndSize(NULL, 0);
+ format_spec = empty;
+ }
+
+ /* Check the format_spec type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(format_spec))
+ spec_is_unicode = 1;
+ else if (PyString_Check(format_spec))
+ spec_is_unicode = 0;
+ else {
+#else
+ if (!PyString_Check(format_spec)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "format expects arg 2 to be string "
+ "or unicode, not %.100s", Py_TYPE(format_spec)->tp_name);
+ goto done;
+ }
+
+ /* Check for a __format__ method and call it. */
+ if (PyInstance_Check(obj)) {
+ /* We're an instance of a classic class */
+ PyObject *bound_method = PyObject_GetAttrString(obj, "__format__");
+ if (bound_method != NULL) {
+ result = PyObject_CallFunctionObjArgs(bound_method,
+ format_spec,
+ NULL);
+ Py_DECREF(bound_method);
+ } else {
+ PyObject *self_as_str = NULL;
+ PyObject *format_method = NULL;
+ Py_ssize_t format_len;
+
+ PyErr_Clear();
+ /* Per the PEP, convert to str (or unicode,
+ depending on the type of the format
+ specifier). For new-style classes, this
+ logic is done by object.__format__(). */
+#ifdef Py_USING_UNICODE
+ if (spec_is_unicode) {
+ format_len = PyUnicode_GET_SIZE(format_spec);
+ self_as_str = PyObject_Unicode(obj);
+ } else
+#endif
+ {
+ format_len = PyString_GET_SIZE(format_spec);
+ self_as_str = PyObject_Str(obj);
+ }
+ if (self_as_str == NULL)
+ goto done1;
+
+ if (format_len > 0) {
+ /* See the almost identical code in
+ typeobject.c for new-style
+ classes. */
+ if (PyErr_WarnEx(
+ PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty "
+ "format string is deprecated", 1)
+ < 0) {
+ goto done1;
+ }
+ /* Eventually this will become an
+ error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to "
+ "object.__format__");
+ goto done1;
+ */
+ }
+
+ /* Then call str.__format__ on that result */
+ format_method = PyObject_GetAttrString(self_as_str, "__format__");
+ if (format_method == NULL) {
+ goto done1;
+ }
+ result = PyObject_CallFunctionObjArgs(format_method,
+ format_spec,
+ NULL);
+done1:
+ Py_XDECREF(self_as_str);
+ Py_XDECREF(format_method);
+ if (result == NULL)
+ goto done;
+ }
+ } else {
+ /* Not an instance of a classic class, use the code
+ from py3k */
+ static PyObject *format_cache = NULL;
+
+ /* Find the (unbound!) __format__ method (a borrowed
+ reference) */
+ PyObject *method = _PyObject_LookupSpecial(obj, "__format__",
+ &format_cache);
+ if (method == NULL) {
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_TypeError,
+ "Type %.100s doesn't define __format__",
+ Py_TYPE(obj)->tp_name);
+ goto done;
+ }
+ /* And call it. */
+ result = PyObject_CallFunctionObjArgs(method, format_spec, NULL);
+ Py_DECREF(method);
+ }
+
+ if (result == NULL)
+ goto done;
+
+ /* Check the result type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(result))
+ result_is_unicode = 1;
+ else if (PyString_Check(result))
+ result_is_unicode = 0;
+ else {
+#else
+ if (!PyString_Check(result)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "%.100s.__format__ must return string or "
+ "unicode, not %.100s", Py_TYPE(obj)->tp_name,
+ Py_TYPE(result)->tp_name);
+ Py_DECREF(result);
+ result = NULL;
+ goto done;
+ }
+
+ /* Convert to unicode, if needed. Required if spec is unicode
+ and result is str */
+#ifdef Py_USING_UNICODE
+ if (spec_is_unicode && !result_is_unicode) {
+ PyObject *tmp = PyObject_Unicode(result);
+ /* This logic works whether or not tmp is NULL */
+ Py_DECREF(result);
+ result = tmp;
+ }
+#endif
+
+done:
+ Py_XDECREF(empty);
+ return result;
+}
+
+/* Operations on numbers */
+
+int
+PyNumber_Check(PyObject *o)
+{
+ return o && o->ob_type->tp_as_number &&
+ (o->ob_type->tp_as_number->nb_int ||
+ o->ob_type->tp_as_number->nb_float);
+}
+
+/* Binary operators */
+
+/* New style number protocol support */
+
+#define NB_SLOT(x) offsetof(PyNumberMethods, x)
+#define NB_BINOP(nb_methods, slot) \
+ (*(binaryfunc*)(& ((char*)nb_methods)[slot]))
+#define NB_TERNOP(nb_methods, slot) \
+ (*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
+
+/*
+ Calling scheme used for binary operations:
+
+ v w Action
+ -------------------------------------------------------------------
+ new new w.op(v,w)[*], v.op(v,w), w.op(v,w)
+ new old v.op(v,w), coerce(v,w), v.op(v,w)
+ old new w.op(v,w), coerce(v,w), v.op(v,w)
+ old old coerce(v,w), v.op(v,w)
+
+ [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
+ v->ob_type
+
+ Legend:
+ -------
+ * new == new style number
+ * old == old style number
+ * Action indicates the order in which operations are tried until either
+ a valid result is produced or an error occurs.
+
+ */
+
+static PyObject *
+binary_op1(PyObject *v, PyObject *w, const int op_slot)
+{
+ PyObject *x;
+ binaryfunc slotv = NULL;
+ binaryfunc slotw = NULL;
+
+ if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v))
+ slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
+ if (w->ob_type != v->ob_type &&
+ w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
+ slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
+ if (slotw == slotv)
+ slotw = NULL;
+ }
+ if (slotv) {
+ if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+ x = slotw(v, w);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ slotw = NULL;
+ }
+ x = slotv(v, w);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ }
+ if (slotw) {
+ x = slotw(v, w);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ }
+ if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
+ int err = PyNumber_CoerceEx(&v, &w);
+ if (err < 0) {
+ return NULL;
+ }
+ if (err == 0) {
+ PyNumberMethods *mv = v->ob_type->tp_as_number;
+ if (mv) {
+ binaryfunc slot;
+ slot = NB_BINOP(mv, op_slot);
+ if (slot) {
+ x = slot(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return x;
+ }
+ }
+ /* CoerceEx incremented the reference counts */
+ Py_DECREF(v);
+ Py_DECREF(w);
+ }
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *
+binop_type_error(PyObject *v, PyObject *w, const char *op_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ "unsupported operand type(s) for %.100s: "
+ "'%.100s' and '%.100s'",
+ op_name,
+ v->ob_type->tp_name,
+ w->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
+{
+ PyObject *result = binary_op1(v, w, op_slot);
+ if (result == Py_NotImplemented) {
+ Py_DECREF(result);
+ return binop_type_error(v, w, op_name);
+ }
+ return result;
+}
+
+
+/*
+ Calling scheme used for ternary operations:
+
+ *** In some cases, w.op is called before v.op; see binary_op1. ***
+
+ v w z Action
+ -------------------------------------------------------------------
+ new new new v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
+ new old new v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ old new new w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ old old new z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ new new old v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ new old old v.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ old new old w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
+ old old old coerce(v,w,z), v.op(v,w,z)
+
+ Legend:
+ -------
+ * new == new style number
+ * old == old style number
+ * Action indicates the order in which operations are tried until either
+ a valid result is produced or an error occurs.
+ * coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and
+ only if z != Py_None; if z == Py_None, then it is treated as absent
+ variable and only coerce(v,w) is tried.
+
+ */
+
+static PyObject *
+ternary_op(PyObject *v,
+ PyObject *w,
+ PyObject *z,
+ const int op_slot,
+ const char *op_name)
+{
+ PyNumberMethods *mv, *mw, *mz;
+ PyObject *x = NULL;
+ ternaryfunc slotv = NULL;
+ ternaryfunc slotw = NULL;
+ ternaryfunc slotz = NULL;
+
+ mv = v->ob_type->tp_as_number;
+ mw = w->ob_type->tp_as_number;
+ if (mv != NULL && NEW_STYLE_NUMBER(v))
+ slotv = NB_TERNOP(mv, op_slot);
+ if (w->ob_type != v->ob_type &&
+ mw != NULL && NEW_STYLE_NUMBER(w)) {
+ slotw = NB_TERNOP(mw, op_slot);
+ if (slotw == slotv)
+ slotw = NULL;
+ }
+ if (slotv) {
+ if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
+ x = slotw(v, w, z);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ slotw = NULL;
+ }
+ x = slotv(v, w, z);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ }
+ if (slotw) {
+ x = slotw(v, w, z);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ }
+ mz = z->ob_type->tp_as_number;
+ if (mz != NULL && NEW_STYLE_NUMBER(z)) {
+ slotz = NB_TERNOP(mz, op_slot);
+ if (slotz == slotv || slotz == slotw)
+ slotz = NULL;
+ if (slotz) {
+ x = slotz(v, w, z);
+ if (x != Py_NotImplemented)
+ return x;
+ Py_DECREF(x); /* can't do it */
+ }
+ }
+
+ if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w) ||
+ (z != Py_None && !NEW_STYLE_NUMBER(z))) {
+ /* we have an old style operand, coerce */
+ PyObject *v1, *z1, *w2, *z2;
+ int c;
+
+ c = PyNumber_Coerce(&v, &w);
+ if (c != 0)
+ goto error3;
+
+ /* Special case: if the third argument is None, it is
+ treated as absent argument and not coerced. */
+ if (z == Py_None) {
+ if (v->ob_type->tp_as_number) {
+ slotz = NB_TERNOP(v->ob_type->tp_as_number,
+ op_slot);
+ if (slotz)
+ x = slotz(v, w, z);
+ else
+ c = -1;
+ }
+ else
+ c = -1;
+ goto error2;
+ }
+ v1 = v;
+ z1 = z;
+ c = PyNumber_Coerce(&v1, &z1);
+ if (c != 0)
+ goto error2;
+ w2 = w;
+ z2 = z1;
+ c = PyNumber_Coerce(&w2, &z2);
+ if (c != 0)
+ goto error1;
+
+ if (v1->ob_type->tp_as_number != NULL) {
+ slotv = NB_TERNOP(v1->ob_type->tp_as_number,
+ op_slot);
+ if (slotv)
+ x = slotv(v1, w2, z2);
+ else
+ c = -1;
+ }
+ else
+ c = -1;
+
+ Py_DECREF(w2);
+ Py_DECREF(z2);
+ error1:
+ Py_DECREF(v1);
+ Py_DECREF(z1);
+ error2:
+ Py_DECREF(v);
+ Py_DECREF(w);
+ error3:
+ if (c >= 0)
+ return x;
+ }
+
+ if (z == Py_None)
+ PyErr_Format(
+ PyExc_TypeError,
+ "unsupported operand type(s) for ** or pow(): "
+ "'%.100s' and '%.100s'",
+ v->ob_type->tp_name,
+ w->ob_type->tp_name);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unsupported operand type(s) for pow(): "
+ "'%.100s', '%.100s', '%.100s'",
+ v->ob_type->tp_name,
+ w->ob_type->tp_name,
+ z->ob_type->tp_name);
+ return NULL;
+}
+
+#define BINARY_FUNC(func, op, op_name) \
+ PyObject * \
+ func(PyObject *v, PyObject *w) { \
+ return binary_op(v, w, NB_SLOT(op), op_name); \
+ }
+
+BINARY_FUNC(PyNumber_Or, nb_or, "|")
+BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
+BINARY_FUNC(PyNumber_And, nb_and, "&")
+BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
+BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
+BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
+BINARY_FUNC(PyNumber_Divide, nb_divide, "/")
+BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
+
+PyObject *
+PyNumber_Add(PyObject *v, PyObject *w)
+{
+ PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
+ if (result == Py_NotImplemented) {
+ PySequenceMethods *m = v->ob_type->tp_as_sequence;
+ Py_DECREF(result);
+ if (m && m->sq_concat) {
+ return (*m->sq_concat)(v, w);
+ }
+ result = binop_type_error(v, w, "+");
+ }
+ return result;
+}
+
+static PyObject *
+sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
+{
+ Py_ssize_t count;
+ if (PyIndex_Check(n)) {
+ count = PyNumber_AsSsize_t(n, PyExc_OverflowError);
+ if (count == -1 && PyErr_Occurred())
+ return NULL;
+ }
+ else {
+ return type_error("can't multiply sequence by "
+ "non-int of type '%.200s'", n);
+ }
+ return (*repeatfunc)(seq, count);
+}
+
+PyObject *
+PyNumber_Multiply(PyObject *v, PyObject *w)
+{
+ PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply));
+ if (result == Py_NotImplemented) {
+ PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+ PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+ Py_DECREF(result);
+ if (mv && mv->sq_repeat) {
+ return sequence_repeat(mv->sq_repeat, v, w);
+ }
+ else if (mw && mw->sq_repeat) {
+ return sequence_repeat(mw->sq_repeat, w, v);
+ }
+ result = binop_type_error(v, w, "*");
+ }
+ return result;
+}
+
+PyObject *
+PyNumber_FloorDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
+}
+
+PyObject *
+PyNumber_TrueDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
+}
+
+PyObject *
+PyNumber_Remainder(PyObject *v, PyObject *w)
+{
+ return binary_op(v, w, NB_SLOT(nb_remainder), "%");
+}
+
+PyObject *
+PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
+{
+ return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
+}
+
+/* Binary in-place operators */
+
+/* The in-place operators are defined to fall back to the 'normal',
+ non in-place operations, if the in-place methods are not in place.
+
+ - If the left hand object has the appropriate struct members, and
+ they are filled, call the appropriate function and return the
+ result. No coercion is done on the arguments; the left-hand object
+ is the one the operation is performed on, and it's up to the
+ function to deal with the right-hand object.
+
+ - Otherwise, in-place modification is not supported. Handle it exactly as
+ a non in-place operation of the same kind.
+
+ */
+
+#define HASINPLACE(t) \
+ PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)
+
+static PyObject *
+binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
+{
+ PyNumberMethods *mv = v->ob_type->tp_as_number;
+ if (mv != NULL && HASINPLACE(v)) {
+ binaryfunc slot = NB_BINOP(mv, iop_slot);
+ if (slot) {
+ PyObject *x = (slot)(v, w);
+ if (x != Py_NotImplemented) {
+ return x;
+ }
+ Py_DECREF(x);
+ }
+ }
+ return binary_op1(v, w, op_slot);
+}
+
+static PyObject *
+binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
+ const char *op_name)
+{
+ PyObject *result = binary_iop1(v, w, iop_slot, op_slot);
+ if (result == Py_NotImplemented) {
+ Py_DECREF(result);
+ return binop_type_error(v, w, op_name);
+ }
+ return result;
+}
+
+#define INPLACE_BINOP(func, iop, op, op_name) \
+ PyObject * \
+ func(PyObject *v, PyObject *w) { \
+ return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
+ }
+
+INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
+INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
+INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
+INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
+INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
+INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
+INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")
+
+PyObject *
+PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
+ NB_SLOT(nb_floor_divide), "//=");
+}
+
+PyObject *
+PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
+{
+ /* XXX tp_flags test */
+ return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
+ NB_SLOT(nb_true_divide), "/=");
+}
+
+PyObject *
+PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
+{
+ PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add),
+ NB_SLOT(nb_add));
+ if (result == Py_NotImplemented) {
+ PySequenceMethods *m = v->ob_type->tp_as_sequence;
+ Py_DECREF(result);
+ if (m != NULL) {
+ binaryfunc f = NULL;
+ if (HASINPLACE(v))
+ f = m->sq_inplace_concat;
+ if (f == NULL)
+ f = m->sq_concat;
+ if (f != NULL)
+ return (*f)(v, w);
+ }
+ result = binop_type_error(v, w, "+=");
+ }
+ return result;
+}
+
+PyObject *
+PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
+{
+ PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply),
+ NB_SLOT(nb_multiply));
+ if (result == Py_NotImplemented) {
+ ssizeargfunc f = NULL;
+ PySequenceMethods *mv = v->ob_type->tp_as_sequence;
+ PySequenceMethods *mw = w->ob_type->tp_as_sequence;
+ Py_DECREF(result);
+ if (mv != NULL) {
+ if (HASINPLACE(v))
+ f = mv->sq_inplace_repeat;
+ if (f == NULL)
+ f = mv->sq_repeat;
+ if (f != NULL)
+ return sequence_repeat(f, v, w);
+ }
+ else if (mw != NULL) {
+ /* Note that the right hand operand should not be
+ * mutated in this case so sq_inplace_repeat is not
+ * used. */
+ if (mw->sq_repeat)
+ return sequence_repeat(mw->sq_repeat, w, v);
+ }
+ result = binop_type_error(v, w, "*=");
+ }
+ return result;
+}
+
+PyObject *
+PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
+{
+ return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
+ NB_SLOT(nb_remainder), "%=");
+}
+
+PyObject *
+PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
+{
+ if (HASINPLACE(v) && v->ob_type->tp_as_number &&
+ v->ob_type->tp_as_number->nb_inplace_power != NULL) {
+ return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
+ }
+ else {
+ return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
+ }
+}
+
+
+/* Unary operators and functions */
+
+PyObject *
+PyNumber_Negative(PyObject *o)
+{
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_negative)
+ return (*m->nb_negative)(o);
+
+ return type_error("bad operand type for unary -: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Positive(PyObject *o)
+{
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_positive)
+ return (*m->nb_positive)(o);
+
+ return type_error("bad operand type for unary +: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Invert(PyObject *o)
+{
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_invert)
+ return (*m->nb_invert)(o);
+
+ return type_error("bad operand type for unary ~: '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Absolute(PyObject *o)
+{
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_absolute)
+ return m->nb_absolute(o);
+
+ return type_error("bad operand type for abs(): '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+int_from_string(const char *s, Py_ssize_t len)
+{
+ char *end;
+ PyObject *x;
+
+ x = PyInt_FromString((char*)s, &end, 10);
+ if (x == NULL)
+ return NULL;
+ if (end != s + len) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for int()");
+ Py_DECREF(x);
+ return NULL;
+ }
+ return x;
+}
+
+/* Return a Python Int or Long from the object item
+ Raise TypeError if the result is not an int-or-long
+ or if the object cannot be interpreted as an index.
+*/
+PyObject *
+PyNumber_Index(PyObject *item)
+{
+ PyObject *result = NULL;
+ if (item == NULL)
+ return null_error();
+ if (PyInt_Check(item) || PyLong_Check(item)) {
+ Py_INCREF(item);
+ return item;
+ }
+ if (PyIndex_Check(item)) {
+ result = item->ob_type->tp_as_number->nb_index(item);
+ if (result &&
+ !PyInt_Check(result) && !PyLong_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "__index__ returned non-(int,long) " \
+ "(type %.200s)",
+ result->ob_type->tp_name);
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object cannot be interpreted "
+ "as an index", item->ob_type->tp_name);
+ }
+ return result;
+}
+
+/* Return an error on Overflow only if err is not NULL*/
+
+Py_ssize_t
+PyNumber_AsSsize_t(PyObject *item, PyObject *err)
+{
+ Py_ssize_t result;
+ PyObject *runerr;
+ PyObject *value = PyNumber_Index(item);
+ if (value == NULL)
+ return -1;
+
+ /* We're done if PyInt_AsSsize_t() returns without error. */
+ result = PyInt_AsSsize_t(value);
+ if (result != -1 || !(runerr = PyErr_Occurred()))
+ goto finish;
+
+ /* Error handling code -- only manage OverflowError differently */
+ if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
+ goto finish;
+
+ PyErr_Clear();
+ /* If no error-handling desired then the default clipping
+ is sufficient.
+ */
+ if (!err) {
+ assert(PyLong_Check(value));
+ /* Whether or not it is less than or equal to
+ zero is determined by the sign of ob_size
+ */
+ if (_PyLong_Sign(value) < 0)
+ result = PY_SSIZE_T_MIN;
+ else
+ result = PY_SSIZE_T_MAX;
+ }
+ else {
+ /* Otherwise replace the error with caller's error object. */
+ PyErr_Format(err,
+ "cannot fit '%.200s' into an index-sized integer",
+ item->ob_type->tp_name);
+ }
+
+ finish:
+ Py_DECREF(value);
+ return result;
+}
+
+
+PyObject *
+_PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format)
+{
+ const char *type_name;
+ static PyObject *int_name = NULL;
+ if (int_name == NULL) {
+ int_name = PyString_InternFromString("__int__");
+ if (int_name == NULL)
+ return NULL;
+ }
+
+ if (integral && (!PyInt_Check(integral) &&
+ !PyLong_Check(integral))) {
+ /* Don't go through tp_as_number->nb_int to avoid
+ hitting the classic class fallback to __trunc__. */
+ PyObject *int_func = PyObject_GetAttr(integral, int_name);
+ if (int_func == NULL) {
+ PyErr_Clear(); /* Raise a different error. */
+ goto non_integral_error;
+ }
+ Py_DECREF(integral);
+ integral = PyEval_CallObject(int_func, NULL);
+ Py_DECREF(int_func);
+ if (integral && (!PyInt_Check(integral) &&
+ !PyLong_Check(integral))) {
+ goto non_integral_error;
+ }
+ }
+ return integral;
+
+non_integral_error:
+ if (PyInstance_Check(integral)) {
+ type_name = PyString_AS_STRING(((PyInstanceObject *)integral)
+ ->in_class->cl_name);
+ }
+ else {
+ type_name = integral->ob_type->tp_name;
+ }
+ PyErr_Format(PyExc_TypeError, error_format, type_name);
+ Py_DECREF(integral);
+ return NULL;
+}
+
+
+PyObject *
+PyNumber_Int(PyObject *o)
+{
+ PyNumberMethods *m;
+ static PyObject *trunc_name = NULL;
+ PyObject *trunc_func;
+ const char *buffer;
+ Py_ssize_t buffer_len;
+
+ if (trunc_name == NULL) {
+ trunc_name = PyString_InternFromString("__trunc__");
+ if (trunc_name == NULL)
+ return NULL;
+ }
+
+ if (o == NULL)
+ return null_error();
+ if (PyInt_CheckExact(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_int) { /* This should include subclasses of int */
+ /* Classic classes always take this branch. */
+ PyObject *res = m->nb_int(o);
+ if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+ PyErr_Format(PyExc_TypeError,
+ "__int__ returned non-int (type %.200s)",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+ }
+ if (PyInt_Check(o)) { /* A int subclass without nb_int */
+ PyIntObject *io = (PyIntObject*)o;
+ return PyInt_FromLong(io->ob_ival);
+ }
+ trunc_func = PyObject_GetAttr(o, trunc_name);
+ if (trunc_func) {
+ PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
+ Py_DECREF(trunc_func);
+ /* __trunc__ is specified to return an Integral type, but
+ int() needs to return an int. */
+ return _PyNumber_ConvertIntegralToInt(
+ truncated,
+ "__trunc__ returned non-Integral (type %.200s)");
+ }
+ PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */
+
+ if (PyString_Check(o))
+ return int_from_string(PyString_AS_STRING(o),
+ PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(o))
+ return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
+ PyUnicode_GET_SIZE(o),
+ 10);
+#endif
+ if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+ return int_from_string((char*)buffer, buffer_len);
+
+ return type_error("int() argument must be a string or a "
+ "number, not '%.200s'", o);
+}
+
+/* Add a check for embedded NULL-bytes in the argument. */
+static PyObject *
+long_from_string(const char *s, Py_ssize_t len)
+{
+ char *end;
+ PyObject *x;
+
+ x = PyLong_FromString((char*)s, &end, 10);
+ if (x == NULL)
+ return NULL;
+ if (end != s + len) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for long()");
+ Py_DECREF(x);
+ return NULL;
+ }
+ return x;
+}
+
+PyObject *
+PyNumber_Long(PyObject *o)
+{
+ PyNumberMethods *m;
+ static PyObject *trunc_name = NULL;
+ PyObject *trunc_func;
+ const char *buffer;
+ Py_ssize_t buffer_len;
+
+ if (trunc_name == NULL) {
+ trunc_name = PyString_InternFromString("__trunc__");
+ if (trunc_name == NULL)
+ return NULL;
+ }
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_long) { /* This should include subclasses of long */
+ /* Classic classes always take this branch. */
+ PyObject *res = m->nb_long(o);
+ if (res == NULL)
+ return NULL;
+ if (PyInt_Check(res)) {
+ long value = PyInt_AS_LONG(res);
+ Py_DECREF(res);
+ return PyLong_FromLong(value);
+ }
+ else if (!PyLong_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "__long__ returned non-long (type %.200s)",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+ }
+ if (PyLong_Check(o)) /* A long subclass without nb_long */
+ return _PyLong_Copy((PyLongObject *)o);
+ trunc_func = PyObject_GetAttr(o, trunc_name);
+ if (trunc_func) {
+ PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
+ PyObject *int_instance;
+ Py_DECREF(trunc_func);
+ /* __trunc__ is specified to return an Integral type,
+ but long() needs to return a long. */
+ int_instance = _PyNumber_ConvertIntegralToInt(
+ truncated,
+ "__trunc__ returned non-Integral (type %.200s)");
+ if (int_instance && PyInt_Check(int_instance)) {
+ /* Make sure that long() returns a long instance. */
+ long value = PyInt_AS_LONG(int_instance);
+ Py_DECREF(int_instance);
+ return PyLong_FromLong(value);
+ }
+ return int_instance;
+ }
+ PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */
+
+ if (PyString_Check(o))
+ /* need to do extra error checking that PyLong_FromString()
+ * doesn't do. In particular long('9.5') must raise an
+ * exception, not truncate the float.
+ */
+ return long_from_string(PyString_AS_STRING(o),
+ PyString_GET_SIZE(o));
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(o))
+ /* The above check is done in PyLong_FromUnicode(). */
+ return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
+ PyUnicode_GET_SIZE(o),
+ 10);
+#endif
+ if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
+ return long_from_string(buffer, buffer_len);
+
+ return type_error("long() argument must be a string or a "
+ "number, not '%.200s'", o);
+}
+
+PyObject *
+PyNumber_Float(PyObject *o)
+{
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_float) { /* This should include subclasses of float */
+ PyObject *res = m->nb_float(o);
+ if (res && !PyFloat_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "__float__ returned non-float (type %.200s)",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+ }
+ if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
+ PyFloatObject *po = (PyFloatObject *)o;
+ return PyFloat_FromDouble(po->ob_fval);
+ }
+ return PyFloat_FromString(o, NULL);
+}
+
+PyObject *
+PyNumber_ToBase(PyObject *n, int base)
+{
+ PyObject *res = NULL;
+ PyObject *index = PyNumber_Index(n);
+
+ if (!index)
+ return NULL;
+ if (PyLong_Check(index))
+ res = _PyLong_Format(index, base, 0, 1);
+ else if (PyInt_Check(index))
+ res = _PyInt_Format((PyIntObject*)index, base, 1);
+ else
+ /* It should not be possible to get here, as
+ PyNumber_Index already has a check for the same
+ condition */
+ PyErr_SetString(PyExc_ValueError, "PyNumber_ToBase: index not "
+ "int or long");
+ Py_DECREF(index);
+ return res;
+}
+
+
+/* Operations on sequences */
+
+int
+PySequence_Check(PyObject *s)
+{
+ if (s == NULL)
+ return 0;
+ if (PyInstance_Check(s))
+ return PyObject_HasAttrString(s, "__getitem__");
+ if (PyDict_Check(s))
+ return 0;
+ return s->ob_type->tp_as_sequence &&
+ s->ob_type->tp_as_sequence->sq_item != NULL;
+}
+
+Py_ssize_t
+PySequence_Size(PyObject *s)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_length)
+ return m->sq_length(s);
+
+ type_error("object of type '%.200s' has no len()", s);
+ return -1;
+}
+
+#undef PySequence_Length
+Py_ssize_t
+PySequence_Length(PyObject *s)
+{
+ return PySequence_Size(s);
+}
+#define PySequence_Length PySequence_Size
+
+PyObject *
+PySequence_Concat(PyObject *s, PyObject *o)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL || o == NULL)
+ return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_concat)
+ return m->sq_concat(s, o);
+
+ /* Instances of user classes defining an __add__() method only
+ have an nb_add slot, not an sq_concat slot. So we fall back
+ to nb_add if both arguments appear to be sequences. */
+ if (PySequence_Check(s) && PySequence_Check(o)) {
+ PyObject *result = binary_op1(s, o, NB_SLOT(nb_add));
+ if (result != Py_NotImplemented)
+ return result;
+ Py_DECREF(result);
+ }
+ return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_Repeat(PyObject *o, Py_ssize_t count)
+{
+ PySequenceMethods *m;
+
+ if (o == NULL)
+ return null_error();
+
+ m = o->ob_type->tp_as_sequence;
+ if (m && m->sq_repeat)
+ return m->sq_repeat(o, count);
+
+ /* Instances of user classes defining a __mul__() method only
+ have an nb_multiply slot, not an sq_repeat slot. so we fall back
+ to nb_multiply if o appears to be a sequence. */
+ if (PySequence_Check(o)) {
+ PyObject *n, *result;
+ n = PyInt_FromSsize_t(count);
+ if (n == NULL)
+ return NULL;
+ result = binary_op1(o, n, NB_SLOT(nb_multiply));
+ Py_DECREF(n);
+ if (result != Py_NotImplemented)
+ return result;
+ Py_DECREF(result);
+ }
+ return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_InPlaceConcat(PyObject *s, PyObject *o)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL || o == NULL)
+ return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && HASINPLACE(s) && m->sq_inplace_concat)
+ return m->sq_inplace_concat(s, o);
+ if (m && m->sq_concat)
+ return m->sq_concat(s, o);
+
+ if (PySequence_Check(s) && PySequence_Check(o)) {
+ PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add),
+ NB_SLOT(nb_add));
+ if (result != Py_NotImplemented)
+ return result;
+ Py_DECREF(result);
+ }
+ return type_error("'%.200s' object can't be concatenated", s);
+}
+
+PyObject *
+PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
+{
+ PySequenceMethods *m;
+
+ if (o == NULL)
+ return null_error();
+
+ m = o->ob_type->tp_as_sequence;
+ if (m && HASINPLACE(o) && m->sq_inplace_repeat)
+ return m->sq_inplace_repeat(o, count);
+ if (m && m->sq_repeat)
+ return m->sq_repeat(o, count);
+
+ if (PySequence_Check(o)) {
+ PyObject *n, *result;
+ n = PyInt_FromSsize_t(count);
+ if (n == NULL)
+ return NULL;
+ result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply),
+ NB_SLOT(nb_multiply));
+ Py_DECREF(n);
+ if (result != Py_NotImplemented)
+ return result;
+ Py_DECREF(result);
+ }
+ return type_error("'%.200s' object can't be repeated", o);
+}
+
+PyObject *
+PySequence_GetItem(PyObject *s, Py_ssize_t i)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL)
+ return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ i += l;
+ }
+ }
+ return m->sq_item(s, i);
+ }
+
+ return type_error("'%.200s' object does not support indexing", s);
+}
+
+PyObject *
+PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+ PySequenceMethods *m;
+ PyMappingMethods *mp;
+
+ if (!s) return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_slice(s, i1, i2);
+ } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
+ PyObject *res;
+ PyObject *slice = _PySlice_FromIndices(i1, i2);
+ if (!slice)
+ return NULL;
+ res = mp->mp_subscript(s, slice);
+ Py_DECREF(slice);
+ return res;
+ }
+
+ return type_error("'%.200s' object is unsliceable", s);
+}
+
+int
+PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return -1;
+ i += l;
+ }
+ }
+ return m->sq_ass_item(s, i, o);
+ }
+
+ type_error("'%.200s' object does not support item assignment", s);
+ return -1;
+}
+
+int
+PySequence_DelItem(PyObject *s, Py_ssize_t i)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return -1;
+ i += l;
+ }
+ }
+ return m->sq_ass_item(s, i, (PyObject *)NULL);
+ }
+
+ type_error("'%.200s' object doesn't support item deletion", s);
+ return -1;
+}
+
+int
+PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
+{
+ PySequenceMethods *m;
+ PyMappingMethods *mp;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return -1;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_ass_slice(s, i1, i2, o);
+ } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
+ int res;
+ PyObject *slice = _PySlice_FromIndices(i1, i2);
+ if (!slice)
+ return -1;
+ res = mp->mp_ass_subscript(s, slice, o);
+ Py_DECREF(slice);
+ return res;
+ }
+
+ type_error("'%.200s' object doesn't support slice assignment", s);
+ return -1;
+}
+
+int
+PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
+{
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ Py_ssize_t l = (*m->sq_length)(s);
+ if (l < 0)
+ return -1;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
+ }
+ type_error("'%.200s' object doesn't support slice deletion", s);
+ return -1;
+}
+
+PyObject *
+PySequence_Tuple(PyObject *v)
+{
+ PyObject *it; /* iter(v) */
+ Py_ssize_t n; /* guess for result tuple size */
+ PyObject *result = NULL;
+ Py_ssize_t j;
+
+ if (v == NULL)
+ return null_error();
+
+ /* Special-case the common tuple and list cases, for efficiency. */
+ if (PyTuple_CheckExact(v)) {
+ /* Note that we can't know whether it's safe to return
+ a tuple *subclass* instance as-is, hence the restriction
+ to exact tuples here. In contrast, lists always make
+ a copy, so there's no need for exactness below. */
+ Py_INCREF(v);
+ return v;
+ }
+ if (PyList_Check(v))
+ return PyList_AsTuple(v);
+
+ /* Get iterator. */
+ it = PyObject_GetIter(v);
+ if (it == NULL)
+ return NULL;
+
+ /* Guess result size and allocate space. */
+ n = _PyObject_LengthHint(v, 10);
+ if (n == -1)
+ goto Fail;
+ result = PyTuple_New(n);
+ if (result == NULL)
+ goto Fail;
+
+ /* Fill the tuple. */
+ for (j = 0; ; ++j) {
+ PyObject *item = PyIter_Next(it);
+ if (item == NULL) {
+ if (PyErr_Occurred())
+ goto Fail;
+ break;
+ }
+ if (j >= n) {
+ Py_ssize_t oldn = n;
+ /* The over-allocation strategy can grow a bit faster
+ than for lists because unlike lists the
+ over-allocation isn't permanent -- we reclaim
+ the excess before the end of this routine.
+ So, grow by ten and then add 25%.
+ */
+ n += 10;
+ n += n >> 2;
+ if (n < oldn) {
+ /* Check for overflow */
+ PyErr_NoMemory();
+ Py_DECREF(item);
+ goto Fail;
+ }
+ if (_PyTuple_Resize(&result, n) != 0) {
+ Py_DECREF(item);
+ goto Fail;
+ }
+ }
+ PyTuple_SET_ITEM(result, j, item);
+ }
+
+ /* Cut tuple back if guess was too large. */
+ if (j < n &&
+ _PyTuple_Resize(&result, j) != 0)
+ goto Fail;
+
+ Py_DECREF(it);
+ return result;
+
+Fail:
+ Py_XDECREF(result);
+ Py_DECREF(it);
+ return NULL;
+}
+
+PyObject *
+PySequence_List(PyObject *v)
+{
+ PyObject *result; /* result list */
+ PyObject *rv; /* return value from PyList_Extend */
+
+ if (v == NULL)
+ return null_error();
+
+ result = PyList_New(0);
+ if (result == NULL)
+ return NULL;
+
+ rv = _PyList_Extend((PyListObject *)result, v);
+ if (rv == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_DECREF(rv);
+ return result;
+}
+
+PyObject *
+PySequence_Fast(PyObject *v, const char *m)
+{
+ PyObject *it;
+
+ if (v == NULL)
+ return null_error();
+
+ if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+
+ it = PyObject_GetIter(v);
+ if (it == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_SetString(PyExc_TypeError, m);
+ return NULL;
+ }
+
+ v = PySequence_List(it);
+ Py_DECREF(it);
+
+ return v;
+}
+
+/* Iterate over seq. Result depends on the operation:
+ PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq.
+ PY_ITERSEARCH_INDEX: 0-based index of first occurrence of obj in seq;
+ set ValueError and return -1 if none found; also return -1 on error.
+ Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error.
+*/
+Py_ssize_t
+_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
+{
+ Py_ssize_t n;
+ int wrapped; /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */
+ PyObject *it; /* iter(seq) */
+
+ if (seq == NULL || obj == NULL) {
+ null_error();
+ return -1;
+ }
+
+ it = PyObject_GetIter(seq);
+ if (it == NULL) {
+ type_error("argument of type '%.200s' is not iterable", seq);
+ return -1;
+ }
+
+ n = wrapped = 0;
+ for (;;) {
+ int cmp;
+ PyObject *item = PyIter_Next(it);
+ if (item == NULL) {
+ if (PyErr_Occurred())
+ goto Fail;
+ break;
+ }
+
+ cmp = PyObject_RichCompareBool(obj, item, Py_EQ);
+ Py_DECREF(item);
+ if (cmp < 0)
+ goto Fail;
+ if (cmp > 0) {
+ switch (operation) {
+ case PY_ITERSEARCH_COUNT:
+ if (n == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "count exceeds C integer size");
+ goto Fail;
+ }
+ ++n;
+ break;
+
+ case PY_ITERSEARCH_INDEX:
+ if (wrapped) {
+ PyErr_SetString(PyExc_OverflowError,
+ "index exceeds C integer size");
+ goto Fail;
+ }
+ goto Done;
+
+ case PY_ITERSEARCH_CONTAINS:
+ n = 1;
+ goto Done;
+
+ default:
+ assert(!"unknown operation");
+ }
+ }
+
+ if (operation == PY_ITERSEARCH_INDEX) {
+ if (n == PY_SSIZE_T_MAX)
+ wrapped = 1;
+ ++n;
+ }
+ }
+
+ if (operation != PY_ITERSEARCH_INDEX)
+ goto Done;
+
+ PyErr_SetString(PyExc_ValueError,
+ "sequence.index(x): x not in sequence");
+ /* fall into failure code */
+Fail:
+ n = -1;
+ /* fall through */
+Done:
+ Py_DECREF(it);
+ return n;
+
+}
+
+/* Return # of times o appears in s. */
+Py_ssize_t
+PySequence_Count(PyObject *s, PyObject *o)
+{
+ return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT);
+}
+
+/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
+ * Use sq_contains if possible, else defer to _PySequence_IterSearch().
+ */
+int
+PySequence_Contains(PyObject *seq, PyObject *ob)
+{
+ Py_ssize_t result;
+ if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
+ PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
+ if (sqm != NULL && sqm->sq_contains != NULL)
+ return (*sqm->sq_contains)(seq, ob);
+ }
+ result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
+ return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* Backwards compatibility */
+#undef PySequence_In
+int
+PySequence_In(PyObject *w, PyObject *v)
+{
+ return PySequence_Contains(w, v);
+}
+
+Py_ssize_t
+PySequence_Index(PyObject *s, PyObject *o)
+{
+ return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX);
+}
+
+/* Operations on mappings */
+
+int
+PyMapping_Check(PyObject *o)
+{
+ if (o && PyInstance_Check(o))
+ return PyObject_HasAttrString(o, "__getitem__");
+
+ return o && o->ob_type->tp_as_mapping &&
+ o->ob_type->tp_as_mapping->mp_subscript &&
+ !(o->ob_type->tp_as_sequence &&
+ o->ob_type->tp_as_sequence->sq_slice);
+}
+
+Py_ssize_t
+PyMapping_Size(PyObject *o)
+{
+ PyMappingMethods *m;
+
+ if (o == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_length)
+ return m->mp_length(o);
+
+ type_error("object of type '%.200s' has no len()", o);
+ return -1;
+}
+
+#undef PyMapping_Length
+Py_ssize_t
+PyMapping_Length(PyObject *o)
+{
+ return PyMapping_Size(o);
+}
+#define PyMapping_Length PyMapping_Size
+
+PyObject *
+PyMapping_GetItemString(PyObject *o, char *key)
+{
+ PyObject *okey, *r;
+
+ if (key == NULL)
+ return null_error();
+
+ okey = PyString_FromString(key);
+ if (okey == NULL)
+ return NULL;
+ r = PyObject_GetItem(o, okey);
+ Py_DECREF(okey);
+ return r;
+}
+
+int
+PyMapping_SetItemString(PyObject *o, char *key, PyObject *value)
+{
+ PyObject *okey;
+ int r;
+
+ if (key == NULL) {
+ null_error();
+ return -1;
+ }
+
+ okey = PyString_FromString(key);
+ if (okey == NULL)
+ return -1;
+ r = PyObject_SetItem(o, okey, value);
+ Py_DECREF(okey);
+ return r;
+}
+
+int
+PyMapping_HasKeyString(PyObject *o, char *key)
+{
+ PyObject *v;
+
+ v = PyMapping_GetItemString(o, key);
+ if (v) {
+ Py_DECREF(v);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
+}
+
+int
+PyMapping_HasKey(PyObject *o, PyObject *key)
+{
+ PyObject *v;
+
+ v = PyObject_GetItem(o, key);
+ if (v) {
+ Py_DECREF(v);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
+}
+
+/* Operations on callable objects */
+
+/* XXX PyCallable_Check() is in object.c */
+
+PyObject *
+PyObject_CallObject(PyObject *o, PyObject *a)
+{
+ return PyEval_CallObjectWithKeywords(o, a, NULL);
+}
+
+PyObject *
+PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ ternaryfunc call;
+
+ if ((call = func->ob_type->tp_call) != NULL) {
+ PyObject *result;
+ if (Py_EnterRecursiveCall(" while calling a Python object"))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (result == NULL && !PyErr_Occurred())
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ return result;
+ }
+ PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
+ func->ob_type->tp_name);
+ return NULL;
+}
+
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+ PyObject *retval;
+
+ if (args == NULL)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(a, 0, args);
+ args = a;
+ }
+ retval = PyObject_Call(callable, args, NULL);
+
+ Py_DECREF(args);
+
+ return retval;
+}
+
+PyObject *
+PyObject_CallFunction(PyObject *callable, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+
+ if (callable == NULL)
+ return null_error();
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ return call_function_tail(callable, args);
+}
+
+PyObject *
+_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+
+ if (callable == NULL)
+ return null_error();
+
+ if (format && *format) {
+ va_start(va, format);
+ args = _Py_VaBuildValue_SizeT(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ return call_function_tail(callable, args);
+}
+
+PyObject *
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL)
+ return NULL;
+
+ if (!PyCallable_Check(func)) {
+ type_error("attribute of type '%.200s' is not callable", func);
+ goto exit;
+ }
+
+ if (format && *format) {
+ va_start(va, format);
+ args = Py_VaBuildValue(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ retval = call_function_tail(func, args);
+
+ exit:
+ /* args gets consumed in call_function_tail */
+ Py_XDECREF(func);
+
+ return retval;
+}
+
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL)
+ return NULL;
+
+ if (!PyCallable_Check(func)) {
+ type_error("attribute of type '%.200s' is not callable", func);
+ goto exit;
+ }
+
+ if (format && *format) {
+ va_start(va, format);
+ args = _Py_VaBuildValue_SizeT(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
+
+ retval = call_function_tail(func, args);
+
+ exit:
+ /* args gets consumed in call_function_tail */
+ Py_XDECREF(func);
+
+ return retval;
+}
+
+
+static PyObject *
+objargs_mktuple(va_list va)
+{
+ int i, n = 0;
+ va_list countva;
+ PyObject *result, *tmp;
+
+#ifdef VA_LIST_IS_ARRAY
+ memcpy(countva, va, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(countva, va);
+#else
+ countva = va;
+#endif
+#endif
+
+ while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
+ ++n;
+ result = PyTuple_New(n);
+ if (result != NULL && n > 0) {
+ for (i = 0; i < n; ++i) {
+ tmp = (PyObject *)va_arg(va, PyObject *);
+ PyTuple_SET_ITEM(result, i, tmp);
+ Py_INCREF(tmp);
+ }
+ }
+ return result;
+}
+
+PyObject *
+PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
+{
+ PyObject *args, *tmp;
+ va_list vargs;
+
+ if (callable == NULL || name == NULL)
+ return null_error();
+
+ callable = PyObject_GetAttr(callable, name);
+ if (callable == NULL)
+ return NULL;
+
+ /* count the args */
+ va_start(vargs, name);
+ args = objargs_mktuple(vargs);
+ va_end(vargs);
+ if (args == NULL) {
+ Py_DECREF(callable);
+ return NULL;
+ }
+ tmp = PyObject_Call(callable, args, NULL);
+ Py_DECREF(args);
+ Py_DECREF(callable);
+
+ return tmp;
+}
+
+PyObject *
+PyObject_CallFunctionObjArgs(PyObject *callable, ...)
+{
+ PyObject *args, *tmp;
+ va_list vargs;
+
+ if (callable == NULL)
+ return null_error();
+
+ /* count the args */
+ va_start(vargs, callable);
+ args = objargs_mktuple(vargs);
+ va_end(vargs);
+ if (args == NULL)
+ return NULL;
+ tmp = PyObject_Call(callable, args, NULL);
+ Py_DECREF(args);
+
+ return tmp;
+}
+
+
+/* isinstance(), issubclass() */
+
+/* abstract_get_bases() has logically 4 return states, with a sort of 0th
+ * state that will almost never happen.
+ *
+ * 0. creating the __bases__ static string could get a MemoryError
+ * 1. getattr(cls, '__bases__') could raise an AttributeError
+ * 2. getattr(cls, '__bases__') could raise some other exception
+ * 3. getattr(cls, '__bases__') could return a tuple
+ * 4. getattr(cls, '__bases__') could return something other than a tuple
+ *
+ * Only state #3 is a non-error state and only it returns a non-NULL object
+ * (it returns the retrieved tuple).
+ *
+ * Any raised AttributeErrors are masked by clearing the exception and
+ * returning NULL. If an object other than a tuple comes out of __bases__,
+ * then again, the return value is NULL. So yes, these two situations
+ * produce exactly the same results: NULL is returned and no error is set.
+ *
+ * If some exception other than AttributeError is raised, then NULL is also
+ * returned, but the exception is not cleared. That's because we want the
+ * exception to be propagated along.
+ *
+ * Callers are expected to test for PyErr_Occurred() when the return value
+ * is NULL to decide whether a valid exception should be propagated or not.
+ * When there's no exception to propagate, it's customary for the caller to
+ * set a TypeError.
+ */
+static PyObject *
+abstract_get_bases(PyObject *cls)
+{
+ static PyObject *__bases__ = NULL;
+ PyObject *bases;
+
+ if (__bases__ == NULL) {
+ __bases__ = PyString_InternFromString("__bases__");
+ if (__bases__ == NULL)
+ return NULL;
+ }
+ bases = PyObject_GetAttr(cls, __bases__);
+ if (bases == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ return NULL;
+ }
+ if (!PyTuple_Check(bases)) {
+ Py_DECREF(bases);
+ return NULL;
+ }
+ return bases;
+}
+
+
+static int
+abstract_issubclass(PyObject *derived, PyObject *cls)
+{
+ PyObject *bases = NULL;
+ Py_ssize_t i, n;
+ int r = 0;
+
+ while (1) {
+ if (derived == cls)
+ return 1;
+ bases = abstract_get_bases(derived);
+ if (bases == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+ }
+ n = PyTuple_GET_SIZE(bases);
+ if (n == 0) {
+ Py_DECREF(bases);
+ return 0;
+ }
+ /* Avoid recursivity in the single inheritance case */
+ if (n == 1) {
+ derived = PyTuple_GET_ITEM(bases, 0);
+ Py_DECREF(bases);
+ continue;
+ }
+ for (i = 0; i < n; i++) {
+ r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
+ if (r != 0)
+ break;
+ }
+ Py_DECREF(bases);
+ return r;
+ }
+}
+
+static int
+check_class(PyObject *cls, const char *error)
+{
+ PyObject *bases = abstract_get_bases(cls);
+ if (bases == NULL) {
+ /* Do not mask errors. */
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError, error);
+ return 0;
+ }
+ Py_DECREF(bases);
+ return -1;
+}
+
+static int
+recursive_isinstance(PyObject *inst, PyObject *cls)
+{
+ PyObject *icls;
+ static PyObject *__class__ = NULL;
+ int retval = 0;
+
+ if (__class__ == NULL) {
+ __class__ = PyString_InternFromString("__class__");
+ if (__class__ == NULL)
+ return -1;
+ }
+
+ if (PyClass_Check(cls) && PyInstance_Check(inst)) {
+ PyObject *inclass =
+ (PyObject*)((PyInstanceObject*)inst)->in_class;
+ retval = PyClass_IsSubclass(inclass, cls);
+ }
+ else if (PyType_Check(cls)) {
+ retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
+ if (retval == 0) {
+ PyObject *c = PyObject_GetAttr(inst, __class__);
+ if (c == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ if (c != (PyObject *)(inst->ob_type) &&
+ PyType_Check(c))
+ retval = PyType_IsSubtype(
+ (PyTypeObject *)c,
+ (PyTypeObject *)cls);
+ Py_DECREF(c);
+ }
+ }
+ }
+ else {
+ if (!check_class(cls,
+ "isinstance() arg 2 must be a class, type,"
+ " or tuple of classes and types"))
+ return -1;
+ icls = PyObject_GetAttr(inst, __class__);
+ if (icls == NULL) {
+ PyErr_Clear();
+ retval = 0;
+ }
+ else {
+ retval = abstract_issubclass(icls, cls);
+ Py_DECREF(icls);
+ }
+ }
+
+ return retval;
+}
+
+int
+PyObject_IsInstance(PyObject *inst, PyObject *cls)
+{
+ static PyObject *name = NULL;
+
+ /* Quick test for an exact match */
+ if (Py_TYPE(inst) == (PyTypeObject *)cls)
+ return 1;
+
+ if (PyTuple_Check(cls)) {
+ Py_ssize_t i;
+ Py_ssize_t n;
+ int r = 0;
+
+ if (Py_EnterRecursiveCall(" in __instancecheck__"))
+ return -1;
+ n = PyTuple_GET_SIZE(cls);
+ for (i = 0; i < n; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(cls, i);
+ r = PyObject_IsInstance(inst, item);
+ if (r != 0)
+ /* either found it, or got an error */
+ break;
+ }
+ Py_LeaveRecursiveCall();
+ return r;
+ }
+
+ if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+ PyObject *checker;
+ checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
+ if (checker != NULL) {
+ PyObject *res;
+ int ok = -1;
+ if (Py_EnterRecursiveCall(" in __instancecheck__")) {
+ Py_DECREF(checker);
+ return ok;
+ }
+ res = PyObject_CallFunctionObjArgs(checker, inst, NULL);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(checker);
+ if (res != NULL) {
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ }
+ return ok;
+ }
+ else if (PyErr_Occurred())
+ return -1;
+ }
+ return recursive_isinstance(inst, cls);
+}
+
+static int
+recursive_issubclass(PyObject *derived, PyObject *cls)
+{
+ int retval;
+
+ if (PyType_Check(cls) && PyType_Check(derived)) {
+ /* Fast path (non-recursive) */
+ return PyType_IsSubtype(
+ (PyTypeObject *)derived, (PyTypeObject *)cls);
+ }
+ if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
+ if (!check_class(derived,
+ "issubclass() arg 1 must be a class"))
+ return -1;
+
+ if (!check_class(cls,
+ "issubclass() arg 2 must be a class"
+ " or tuple of classes"))
+ return -1;
+ retval = abstract_issubclass(derived, cls);
+ }
+ else {
+ /* shortcut */
+ if (!(retval = (derived == cls)))
+ retval = PyClass_IsSubclass(derived, cls);
+ }
+
+ return retval;
+}
+
+int
+PyObject_IsSubclass(PyObject *derived, PyObject *cls)
+{
+ static PyObject *name = NULL;
+
+ if (PyTuple_Check(cls)) {
+ Py_ssize_t i;
+ Py_ssize_t n;
+ int r = 0;
+
+ if (Py_EnterRecursiveCall(" in __subclasscheck__"))
+ return -1;
+ n = PyTuple_GET_SIZE(cls);
+ for (i = 0; i < n; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(cls, i);
+ r = PyObject_IsSubclass(derived, item);
+ if (r != 0)
+ /* either found it, or got an error */
+ break;
+ }
+ Py_LeaveRecursiveCall();
+ return r;
+ }
+ if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+ PyObject *checker;
+ checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
+ if (checker != NULL) {
+ PyObject *res;
+ int ok = -1;
+ if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+ Py_DECREF(checker);
+ return ok;
+ }
+ res = PyObject_CallFunctionObjArgs(checker, derived, NULL);
+ Py_LeaveRecursiveCall();
+ Py_DECREF(checker);
+ if (res != NULL) {
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ }
+ return ok;
+ }
+ else if (PyErr_Occurred()) {
+ return -1;
+ }
+ }
+ return recursive_issubclass(derived, cls);
+}
+
+int
+_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
+{
+ return recursive_isinstance(inst, cls);
+}
+
+int
+_PyObject_RealIsSubclass(PyObject *derived, PyObject *cls)
+{
+ return recursive_issubclass(derived, cls);
+}
+
+
+PyObject *
+PyObject_GetIter(PyObject *o)
+{
+ PyTypeObject *t = o->ob_type;
+ getiterfunc f = NULL;
+ if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
+ f = t->tp_iter;
+ if (f == NULL) {
+ if (PySequence_Check(o))
+ return PySeqIter_New(o);
+ return type_error("'%.200s' object is not iterable", o);
+ }
+ else {
+ PyObject *res = (*f)(o);
+ if (res != NULL && !PyIter_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "iter() returned non-iterator "
+ "of type '%.100s'",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ res = NULL;
+ }
+ return res;
+ }
+}
+
+/* Return next item.
+ * If an error occurs, return NULL. PyErr_Occurred() will be true.
+ * If the iteration terminates normally, return NULL and clear the
+ * PyExc_StopIteration exception (if it was set). PyErr_Occurred()
+ * will be false.
+ * Else return the next object. PyErr_Occurred() will be false.
+ */
+PyObject *
+PyIter_Next(PyObject *iter)
+{
+ PyObject *result;
+ result = (*iter->ob_type->tp_iternext)(iter);
+ if (result == NULL &&
+ PyErr_Occurred() &&
+ PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ return result;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/boolobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/boolobject.c
new file mode 100644
index 0000000000..6791ee7cdf
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/boolobject.c
@@ -0,0 +1,202 @@
+/* Boolean type, a subtype of int */
+
+#include "Python.h"
+
+/* We need to define bool_print to override int_print */
+
+static int
+bool_print(PyBoolObject *self, FILE *fp, int flags)
+{
+ Py_BEGIN_ALLOW_THREADS
+ fputs(self->ob_ival == 0 ? "False" : "True", fp);
+ Py_END_ALLOW_THREADS
+ return 0;
+}
+
+/* We define bool_repr to return "False" or "True" */
+
+static PyObject *false_str = NULL;
+static PyObject *true_str = NULL;
+
+static PyObject *
+bool_repr(PyBoolObject *self)
+{
+ PyObject *s;
+
+ if (self->ob_ival)
+ s = true_str ? true_str :
+ (true_str = PyString_InternFromString("True"));
+ else
+ s = false_str ? false_str :
+ (false_str = PyString_InternFromString("False"));
+ Py_XINCREF(s);
+ return s;
+}
+
+/* Function to return a bool from a C long */
+
+PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result;
+
+ if (ok)
+ result = Py_True;
+ else
+ result = Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+/* We define bool_new to always return either Py_True or Py_False */
+
+static PyObject *
+bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"x", 0};
+ PyObject *x = Py_False;
+ long ok;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
+ return NULL;
+ ok = PyObject_IsTrue(x);
+ if (ok < 0)
+ return NULL;
+ return PyBool_FromLong(ok);
+}
+
+/* Arithmetic operations redefined to return bool if both args are bool. */
+
+static PyObject *
+bool_and(PyObject *a, PyObject *b)
+{
+ if (!PyBool_Check(a) || !PyBool_Check(b))
+ return PyInt_Type.tp_as_number->nb_and(a, b);
+ return PyBool_FromLong(
+ ((PyBoolObject *)a)->ob_ival & ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_or(PyObject *a, PyObject *b)
+{
+ if (!PyBool_Check(a) || !PyBool_Check(b))
+ return PyInt_Type.tp_as_number->nb_or(a, b);
+ return PyBool_FromLong(
+ ((PyBoolObject *)a)->ob_ival | ((PyBoolObject *)b)->ob_ival);
+}
+
+static PyObject *
+bool_xor(PyObject *a, PyObject *b)
+{
+ if (!PyBool_Check(a) || !PyBool_Check(b))
+ return PyInt_Type.tp_as_number->nb_xor(a, b);
+ return PyBool_FromLong(
+ ((PyBoolObject *)a)->ob_ival ^ ((PyBoolObject *)b)->ob_ival);
+}
+
+/* Doc string */
+
+PyDoc_STRVAR(bool_doc,
+"bool(x) -> bool\n\
+\n\
+Returns True when the argument x is true, False otherwise.\n\
+The builtins True and False are the only two instances of the class bool.\n\
+The class bool is a subclass of the class int, and cannot be subclassed.");
+
+/* Arithmetic methods -- only so we can override &, |, ^. */
+
+static PyNumberMethods bool_as_number = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_divide */
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ 0, /* nb_nonzero */
+ 0, /* nb_invert */
+ 0, /* nb_lshift */
+ 0, /* nb_rshift */
+ bool_and, /* nb_and */
+ bool_xor, /* nb_xor */
+ bool_or, /* nb_or */
+ 0, /* nb_coerce */
+ 0, /* nb_int */
+ 0, /* nb_long */
+ 0, /* nb_float */
+ 0, /* nb_oct */
+ 0, /* nb_hex */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ 0, /* nb_floor_divide */
+ 0, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+};
+
+/* The type object for bool. Note that this cannot be subclassed! */
+
+PyTypeObject PyBool_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "bool",
+ sizeof(PyIntObject),
+ 0,
+ 0, /* tp_dealloc */
+ (printfunc)bool_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)bool_repr, /* tp_repr */
+ &bool_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)bool_repr, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ bool_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &PyInt_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ bool_new, /* tp_new */
+};
+
+/* The objects representing bool values False and True */
+
+/* Named Zero for link-level compatibility */
+PyIntObject _Py_ZeroStruct = {
+ PyObject_HEAD_INIT(&PyBool_Type)
+ 0
+};
+
+PyIntObject _Py_TrueStruct = {
+ PyObject_HEAD_INIT(&PyBool_Type)
+ 1
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/bufferobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/bufferobject.c
new file mode 100644
index 0000000000..243857489b
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/bufferobject.c
@@ -0,0 +1,878 @@
+
+/* Buffer object implementation */
+
+#include "Python.h"
+
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *b_base;
+ void *b_ptr;
+ Py_ssize_t b_size;
+ Py_ssize_t b_offset;
+ int b_readonly;
+ long b_hash;
+} PyBufferObject;
+
+
+enum buffer_t {
+ READ_BUFFER,
+ WRITE_BUFFER,
+ CHAR_BUFFER,
+ ANY_BUFFER
+};
+
+static int
+get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
+ enum buffer_t buffer_type)
+{
+ if (self->b_base == NULL) {
+ assert (ptr != NULL);
+ *ptr = self->b_ptr;
+ *size = self->b_size;
+ }
+ else {
+ Py_ssize_t count, offset;
+ readbufferproc proc = 0;
+ PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+ if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return 0;
+ }
+ if ((buffer_type == READ_BUFFER) ||
+ ((buffer_type == ANY_BUFFER) && self->b_readonly))
+ proc = bp->bf_getreadbuffer;
+ else if ((buffer_type == WRITE_BUFFER) ||
+ (buffer_type == ANY_BUFFER))
+ proc = (readbufferproc)bp->bf_getwritebuffer;
+ else if (buffer_type == CHAR_BUFFER) {
+ if (!PyType_HasFeature(self->ob_type,
+ Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
+ return 0;
+ }
+ proc = (readbufferproc)bp->bf_getcharbuffer;
+ }
+ if (!proc) {
+ char *buffer_type_name;
+ switch (buffer_type) {
+ case READ_BUFFER:
+ buffer_type_name = "read";
+ break;
+ case WRITE_BUFFER:
+ buffer_type_name = "write";
+ break;
+ case CHAR_BUFFER:
+ buffer_type_name = "char";
+ break;
+ default:
+ buffer_type_name = "no";
+ break;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%s buffer type not available",
+ buffer_type_name);
+ return 0;
+ }
+ if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
+ return 0;
+ /* apply constraints to the start/end */
+ if (self->b_offset > count)
+ offset = count;
+ else
+ offset = self->b_offset;
+ *(char **)ptr = *(char **)ptr + offset;
+ if (self->b_size == Py_END_OF_BUFFER)
+ *size = count;
+ else
+ *size = self->b_size;
+ if (*size > count - offset)
+ *size = count - offset;
+ }
+ return 1;
+}
+
+
+static PyObject *
+buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
+ int readonly)
+{
+ PyBufferObject * b;
+
+ if (size < 0 && size != Py_END_OF_BUFFER) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
+
+ b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
+ if ( b == NULL )
+ return NULL;
+
+ Py_XINCREF(base);
+ b->b_base = base;
+ b->b_ptr = ptr;
+ b->b_size = size;
+ b->b_offset = offset;
+ b->b_readonly = readonly;
+ b->b_hash = -1;
+
+ return (PyObject *) b;
+}
+
+static PyObject *
+buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
+{
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
+ if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
+ /* another buffer, refer to the base object */
+ PyBufferObject *b = (PyBufferObject *)base;
+ if (b->b_size != Py_END_OF_BUFFER) {
+ Py_ssize_t base_size = b->b_size - offset;
+ if (base_size < 0)
+ base_size = 0;
+ if (size == Py_END_OF_BUFFER || size > base_size)
+ size = base_size;
+ }
+ offset += b->b_offset;
+ base = b->b_base;
+ }
+ return buffer_from_memory(base, size, offset, NULL, readonly);
+}
+
+
+PyObject *
+PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
+
+ return buffer_from_object(base, size, offset, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
+{
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+
+ if ( pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
+
+ return buffer_from_object(base, size, offset, 0);
+}
+
+PyObject *
+PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
+{
+ return buffer_from_memory(NULL, size, 0, ptr, 1);
+}
+
+PyObject *
+PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
+{
+ return buffer_from_memory(NULL, size, 0, ptr, 0);
+}
+
+PyObject *
+PyBuffer_New(Py_ssize_t size)
+{
+ PyObject *o;
+ PyBufferObject * b;
+
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
+ /* unlikely */
+ return PyErr_NoMemory();
+ }
+ /* Inline PyObject_New */
+ o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
+ if ( o == NULL )
+ return PyErr_NoMemory();
+ b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
+
+ b->b_base = NULL;
+ b->b_ptr = (void *)(b + 1);
+ b->b_size = size;
+ b->b_offset = 0;
+ b->b_readonly = 0;
+ b->b_hash = -1;
+
+ return o;
+}
+
+/* Methods */
+
+static PyObject *
+buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ PyObject *ob;
+ Py_ssize_t offset = 0;
+ Py_ssize_t size = Py_END_OF_BUFFER;
+
+ if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
+ return NULL;
+
+ if (!_PyArg_NoKeywords("buffer()", kw))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
+ return NULL;
+ return PyBuffer_FromObject(ob, offset, size);
+}
+
+PyDoc_STRVAR(buffer_doc,
+"buffer(object [, offset[, size]])\n\
+\n\
+Create a new buffer object which references the given object.\n\
+The buffer will reference a slice of the target object from the\n\
+start of the object (or at the specified offset). The slice will\n\
+extend to the end of the target object (or with the specified size).");
+
+
+static void
+buffer_dealloc(PyBufferObject *self)
+{
+ Py_XDECREF(self->b_base);
+ PyObject_DEL(self);
+}
+
+static int
+buffer_compare(PyBufferObject *self, PyBufferObject *other)
+{
+ void *p1, *p2;
+ Py_ssize_t len_self, len_other, min_len;
+ int cmp;
+
+ if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
+ return -1;
+ if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
+ return -1;
+ min_len = (len_self < len_other) ? len_self : len_other;
+ if (min_len > 0) {
+ cmp = memcmp(p1, p2, min_len);
+ if (cmp != 0)
+ return cmp < 0 ? -1 : 1;
+ }
+ return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
+}
+
+static PyObject *
+buffer_repr(PyBufferObject *self)
+{
+ const char *status = self->b_readonly ? "read-only" : "read-write";
+
+ if ( self->b_base == NULL )
+ return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+ status,
+ self->b_ptr,
+ self->b_size,
+ self);
+ else
+ return PyString_FromFormat(
+ "<%s buffer for %p, size %zd, offset %zd at %p>",
+ status,
+ self->b_base,
+ self->b_size,
+ self->b_offset,
+ self);
+}
+
+static long
+buffer_hash(PyBufferObject *self)
+{
+ void *ptr;
+ Py_ssize_t size;
+ register Py_ssize_t len;
+ register unsigned char *p;
+ register long x;
+
+ if ( self->b_hash != -1 )
+ return self->b_hash;
+
+ /* XXX potential bugs here, a readonly buffer does not imply that the
+ * underlying memory is immutable. b_readonly is a necessary but not
+ * sufficient condition for a buffer to be hashable. Perhaps it would
+ * be better to only allow hashing if the underlying object is known to
+ * be immutable (e.g. PyString_Check() is true). Another idea would
+ * be to call tp_hash on the underlying object and see if it raises
+ * an error. */
+ if ( !self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "writable buffers are not hashable");
+ return -1;
+ }
+
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ p = (unsigned char *) ptr;
+ len = size;
+ /*
+ We make the hash of the empty buffer be 0, rather than using
+ (prefix ^ suffix), since this slightly obfuscates the hash secret
+ */
+ if (len == 0) {
+ self->b_hash = 0;
+ return 0;
+ }
+ x = _Py_HashSecret.prefix;
+ x ^= *p << 7;
+ while (--len >= 0)
+ x = (1000003*x) ^ *p++;
+ x ^= size;
+ x ^= _Py_HashSecret.suffix;
+ if (x == -1)
+ x = -2;
+ self->b_hash = x;
+ return x;
+}
+
+static PyObject *
+buffer_str(PyBufferObject *self)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ return PyString_FromStringAndSize((const char *)ptr, size);
+}
+
+/* Sequence methods */
+
+static Py_ssize_t
+buffer_length(PyBufferObject *self)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ return size;
+}
+
+static PyObject *
+buffer_concat(PyBufferObject *self, PyObject *other)
+{
+ PyBufferProcs *pb = other->ob_type->tp_as_buffer;
+ void *ptr1, *ptr2;
+ char *p;
+ PyObject *ob;
+ Py_ssize_t size, count;
+
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return NULL;
+ }
+
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return NULL;
+
+ /* optimize special case */
+ if ( size == 0 )
+ {
+ Py_INCREF(other);
+ return other;
+ }
+
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return NULL;
+
+ assert(count <= PY_SIZE_MAX - size);
+
+ ob = PyString_FromStringAndSize(NULL, size + count);
+ if ( ob == NULL )
+ return NULL;
+ p = PyString_AS_STRING(ob);
+ memcpy(p, ptr1, size);
+ memcpy(p + size, ptr2, count);
+
+ /* there is an extra byte in the string object, so this is safe */
+ p[size + count] = '\0';
+
+ return ob;
+}
+
+static PyObject *
+buffer_repeat(PyBufferObject *self, Py_ssize_t count)
+{
+ PyObject *ob;
+ register char *p;
+ void *ptr;
+ Py_ssize_t size;
+
+ if ( count < 0 )
+ count = 0;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if (count > PY_SSIZE_T_MAX / size) {
+ PyErr_SetString(PyExc_MemoryError, "result too large");
+ return NULL;
+ }
+ ob = PyString_FromStringAndSize(NULL, size * count);
+ if ( ob == NULL )
+ return NULL;
+
+ p = PyString_AS_STRING(ob);
+ while ( count-- )
+ {
+ memcpy(p, ptr, size);
+ p += size;
+ }
+
+ /* there is an extra byte in the string object, so this is safe */
+ *p = '\0';
+
+ return ob;
+}
+
+static PyObject *
+buffer_item(PyBufferObject *self, Py_ssize_t idx)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( idx < 0 || idx >= size ) {
+ PyErr_SetString(PyExc_IndexError, "buffer index out of range");
+ return NULL;
+ }
+ return PyString_FromStringAndSize((char *)ptr + idx, 1);
+}
+
+static PyObject *
+buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( left < 0 )
+ left = 0;
+ if ( right < 0 )
+ right = 0;
+ if ( right > size )
+ right = size;
+ if ( right < left )
+ right = left;
+ return PyString_FromStringAndSize((char *)ptr + left,
+ right - left);
+}
+
+static PyObject *
+buffer_subscript(PyBufferObject *self, PyObject *item)
+{
+ void *p;
+ Py_ssize_t size;
+
+ if (!get_buf(self, &p, &size, ANY_BUFFER))
+ return NULL;
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += size;
+ return buffer_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0)
+ return PyString_FromStringAndSize("", 0);
+ else if (step == 1)
+ return PyString_FromStringAndSize((char *)p + start,
+ stop - start);
+ else {
+ PyObject *result;
+ char *source_buf = (char *)p;
+ char *result_buf = (char *)PyMem_Malloc(slicelength);
+
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+
+ result = PyString_FromStringAndSize(result_buf,
+ slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "sequence index must be integer");
+ return NULL;
+ }
+}
+
+static int
+buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
+{
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t count;
+
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
+
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
+
+ if (idx < 0 || idx >= size) {
+ PyErr_SetString(PyExc_IndexError,
+ "buffer assignment index out of range");
+ return -1;
+ }
+
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
+ if ( count != 1 ) {
+ PyErr_SetString(PyExc_TypeError,
+ "right operand must be a single byte");
+ return -1;
+ }
+
+ ((char *)ptr1)[idx] = *(char *)ptr2;
+ return 0;
+}
+
+static int
+buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
+{
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t slice_len;
+ Py_ssize_t count;
+
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
+
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
+
+ if ( left < 0 )
+ left = 0;
+ else if ( left > size )
+ left = size;
+ if ( right < left )
+ right = left;
+ else if ( right > size )
+ right = size;
+ slice_len = right - left;
+
+ if ( count != slice_len ) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
+
+ if ( slice_len )
+ memcpy((char *)ptr1 + left, ptr2, slice_len);
+
+ return 0;
+}
+
+static int
+buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
+{
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t selfsize;
+ Py_ssize_t othersize;
+
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
+
+ pb = value ? value->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
+ return -1;
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += selfsize;
+ return buffer_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
+ &start, &stop, &step, &slicelength) < 0)
+ return -1;
+
+ if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
+ return -1;
+
+ if (othersize != slicelength) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
+
+ if (slicelength == 0)
+ return 0;
+ else if (step == 1) {
+ memcpy((char *)ptr1 + start, ptr2, slicelength);
+ return 0;
+ }
+ else {
+ Py_ssize_t cur, i;
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ ((char *)ptr1)[cur] = ((char *)ptr2)[i];
+ }
+
+ return 0;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer indices must be integers");
+ return -1;
+ }
+}
+
+/* Buffer methods */
+
+static Py_ssize_t
+buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, READ_BUFFER))
+ return -1;
+ return size;
+}
+
+static Py_ssize_t
+buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
+{
+ Py_ssize_t size;
+
+ if ( self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer is read-only");
+ return -1;
+ }
+
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, WRITE_BUFFER))
+ return -1;
+ return size;
+}
+
+static Py_ssize_t
+buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ if (lenp)
+ *lenp = size;
+ return 1;
+}
+
+static Py_ssize_t
+buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
+ return -1;
+ *pp = (const char *)ptr;
+ return size;
+}
+
+static int buffer_getbuffer(PyBufferObject *self, Py_buffer *buf, int flags)
+{
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ return PyBuffer_FillInfo(buf, (PyObject*)self, ptr, size,
+ self->b_readonly, flags);
+}
+
+static PySequenceMethods buffer_as_sequence = {
+ (lenfunc)buffer_length, /*sq_length*/
+ (binaryfunc)buffer_concat, /*sq_concat*/
+ (ssizeargfunc)buffer_repeat, /*sq_repeat*/
+ (ssizeargfunc)buffer_item, /*sq_item*/
+ (ssizessizeargfunc)buffer_slice, /*sq_slice*/
+ (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
+ (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+};
+
+static PyMappingMethods buffer_as_mapping = {
+ (lenfunc)buffer_length,
+ (binaryfunc)buffer_subscript,
+ (objobjargproc)buffer_ass_subscript,
+};
+
+static PyBufferProcs buffer_as_buffer = {
+ (readbufferproc)buffer_getreadbuf,
+ (writebufferproc)buffer_getwritebuf,
+ (segcountproc)buffer_getsegcount,
+ (charbufferproc)buffer_getcharbuf,
+ (getbufferproc)buffer_getbuffer,
+};
+
+PyTypeObject PyBuffer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "buffer",
+ sizeof(PyBufferObject),
+ 0,
+ (destructor)buffer_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)buffer_compare, /* tp_compare */
+ (reprfunc)buffer_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &buffer_as_sequence, /* tp_as_sequence */
+ &buffer_as_mapping, /* tp_as_mapping */
+ (hashfunc)buffer_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)buffer_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &buffer_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+ buffer_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* 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 */
+ buffer_new, /* tp_new */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/bytearrayobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/bytearrayobject.c
new file mode 100644
index 0000000000..b24ca7894c
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/bytearrayobject.c
@@ -0,0 +1,3052 @@
+/* PyBytes (bytearray) implementation */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#include "bytes_methods.h"
+
+char _PyByteArray_empty_string[] = "";
+
+void
+PyByteArray_Fini(void)
+{
+}
+
+int
+PyByteArray_Init(void)
+{
+ return 1;
+}
+
+/* end nullbytes support */
+
+/* Helpers */
+
+static int
+_getbytevalue(PyObject* arg, int *value)
+{
+ long face_value;
+
+ if (PyBytes_CheckExact(arg)) {
+ if (Py_SIZE(arg) != 1) {
+ PyErr_SetString(PyExc_ValueError, "string must be of size 1");
+ return 0;
+ }
+ *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
+ return 1;
+ }
+ else if (PyInt_Check(arg) || PyLong_Check(arg)) {
+ face_value = PyLong_AsLong(arg);
+ }
+ else {
+ PyObject *index = PyNumber_Index(arg);
+ if (index == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "an integer or string of size 1 is required");
+ return 0;
+ }
+ face_value = PyLong_AsLong(index);
+ Py_DECREF(index);
+ }
+
+ if (face_value < 0 || face_value >= 256) {
+ /* this includes the OverflowError in case the long is too large */
+ PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ return 0;
+ }
+
+ *value = face_value;
+ return 1;
+}
+
+static Py_ssize_t
+bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent bytes segment");
+ return -1;
+ }
+ *ptr = (void *)PyByteArray_AS_STRING(self);
+ return Py_SIZE(self);
+}
+
+static Py_ssize_t
+bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent bytes segment");
+ return -1;
+ }
+ *ptr = (void *)PyByteArray_AS_STRING(self);
+ return Py_SIZE(self);
+}
+
+static Py_ssize_t
+bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
+{
+ if ( lenp )
+ *lenp = Py_SIZE(self);
+ return 1;
+}
+
+static Py_ssize_t
+bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent bytes segment");
+ return -1;
+ }
+ *ptr = PyByteArray_AS_STRING(self);
+ return Py_SIZE(self);
+}
+
+static int
+bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
+{
+ int ret;
+ void *ptr;
+ if (view == NULL) {
+ obj->ob_exports++;
+ return 0;
+ }
+ ptr = (void *) PyByteArray_AS_STRING(obj);
+ ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
+ if (ret >= 0) {
+ obj->ob_exports++;
+ }
+ return ret;
+}
+
+static void
+bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
+{
+ obj->ob_exports--;
+}
+
+static Py_ssize_t
+_getbuffer(PyObject *obj, Py_buffer *view)
+{
+ PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
+
+ if (buffer == NULL || buffer->bf_getbuffer == NULL)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "Type %.100s doesn't support the buffer API",
+ Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+
+ if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
+ return -1;
+ return view->len;
+}
+
+static int
+_canresize(PyByteArrayObject *self)
+{
+ if (self->ob_exports > 0) {
+ PyErr_SetString(PyExc_BufferError,
+ "Existing exports of data: object cannot be re-sized");
+ return 0;
+ }
+ return 1;
+}
+
+/* Direct API functions */
+
+PyObject *
+PyByteArray_FromObject(PyObject *input)
+{
+ return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
+ input, NULL);
+}
+
+PyObject *
+PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
+{
+ PyByteArrayObject *new;
+ Py_ssize_t alloc;
+
+ if (size < 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "Negative size passed to PyByteArray_FromStringAndSize");
+ return NULL;
+ }
+
+ new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
+ if (new == NULL)
+ return NULL;
+
+ if (size == 0) {
+ new->ob_bytes = NULL;
+ alloc = 0;
+ }
+ else {
+ alloc = size + 1;
+ new->ob_bytes = PyMem_Malloc(alloc);
+ if (new->ob_bytes == NULL) {
+ Py_DECREF(new);
+ return PyErr_NoMemory();
+ }
+ if (bytes != NULL && size > 0)
+ memcpy(new->ob_bytes, bytes, size);
+ new->ob_bytes[size] = '\0'; /* Trailing null byte */
+ }
+ Py_SIZE(new) = size;
+ new->ob_alloc = alloc;
+ new->ob_exports = 0;
+
+ return (PyObject *)new;
+}
+
+Py_ssize_t
+PyByteArray_Size(PyObject *self)
+{
+ assert(self != NULL);
+ assert(PyByteArray_Check(self));
+
+ return PyByteArray_GET_SIZE(self);
+}
+
+char *
+PyByteArray_AsString(PyObject *self)
+{
+ assert(self != NULL);
+ assert(PyByteArray_Check(self));
+
+ return PyByteArray_AS_STRING(self);
+}
+
+int
+PyByteArray_Resize(PyObject *self, Py_ssize_t size)
+{
+ void *sval;
+ Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
+
+ assert(self != NULL);
+ assert(PyByteArray_Check(self));
+ assert(size >= 0);
+
+ if (size == Py_SIZE(self)) {
+ return 0;
+ }
+ if (!_canresize((PyByteArrayObject *)self)) {
+ return -1;
+ }
+
+ if (size < alloc / 2) {
+ /* Major downsize; resize down to exact size */
+ alloc = size + 1;
+ }
+ else if (size < alloc) {
+ /* Within allocated size; quick exit */
+ Py_SIZE(self) = size;
+ ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
+ return 0;
+ }
+ else if (size <= alloc * 1.125) {
+ /* Moderate upsize; overallocate similar to list_resize() */
+ alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
+ }
+ else {
+ /* Major upsize; resize up to exact size */
+ alloc = size + 1;
+ }
+
+ sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
+ if (sval == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ ((PyByteArrayObject *)self)->ob_bytes = sval;
+ Py_SIZE(self) = size;
+ ((PyByteArrayObject *)self)->ob_alloc = alloc;
+ ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
+
+ return 0;
+}
+
+PyObject *
+PyByteArray_Concat(PyObject *a, PyObject *b)
+{
+ Py_ssize_t size;
+ Py_buffer va, vb;
+ PyByteArrayObject *result = NULL;
+
+ va.len = -1;
+ vb.len = -1;
+ if (_getbuffer(a, &va) < 0 ||
+ _getbuffer(b, &vb) < 0) {
+ PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
+ Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
+ goto done;
+ }
+
+ size = va.len + vb.len;
+ if (size < 0) {
+ PyErr_NoMemory();
+ goto done;
+ }
+
+ result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
+ if (result != NULL) {
+ memcpy(result->ob_bytes, va.buf, va.len);
+ memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
+ }
+
+ done:
+ if (va.len != -1)
+ PyBuffer_Release(&va);
+ if (vb.len != -1)
+ PyBuffer_Release(&vb);
+ return (PyObject *)result;
+}
+
+/* Functions stuffed into the type object */
+
+static Py_ssize_t
+bytearray_length(PyByteArrayObject *self)
+{
+ return Py_SIZE(self);
+}
+
+static PyObject *
+bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
+{
+ Py_ssize_t mysize;
+ Py_ssize_t size;
+ Py_buffer vo;
+
+ if (_getbuffer(other, &vo) < 0) {
+ PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
+ Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
+ return NULL;
+ }
+
+ mysize = Py_SIZE(self);
+ size = mysize + vo.len;
+ if (size < 0) {
+ PyBuffer_Release(&vo);
+ return PyErr_NoMemory();
+ }
+ if (size < self->ob_alloc) {
+ Py_SIZE(self) = size;
+ self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
+ }
+ else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
+ PyBuffer_Release(&vo);
+ return NULL;
+ }
+ memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
+ PyBuffer_Release(&vo);
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static PyObject *
+bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
+{
+ PyByteArrayObject *result;
+ Py_ssize_t mysize;
+ Py_ssize_t size;
+
+ if (count < 0)
+ count = 0;
+ mysize = Py_SIZE(self);
+ size = mysize * count;
+ if (count != 0 && size / count != mysize)
+ return PyErr_NoMemory();
+ result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
+ if (result != NULL && size != 0) {
+ if (mysize == 1)
+ memset(result->ob_bytes, self->ob_bytes[0], size);
+ else {
+ Py_ssize_t i;
+ for (i = 0; i < count; i++)
+ memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
+ }
+ }
+ return (PyObject *)result;
+}
+
+static PyObject *
+bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
+{
+ Py_ssize_t mysize;
+ Py_ssize_t size;
+
+ if (count < 0)
+ count = 0;
+ mysize = Py_SIZE(self);
+ size = mysize * count;
+ if (count != 0 && size / count != mysize)
+ return PyErr_NoMemory();
+ if (size < self->ob_alloc) {
+ Py_SIZE(self) = size;
+ self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
+ }
+ else if (PyByteArray_Resize((PyObject *)self, size) < 0)
+ return NULL;
+
+ if (mysize == 1)
+ memset(self->ob_bytes, self->ob_bytes[0], size);
+ else {
+ Py_ssize_t i;
+ for (i = 1; i < count; i++)
+ memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
+ }
+
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static PyObject *
+bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
+{
+ if (i < 0)
+ i += Py_SIZE(self);
+ if (i < 0 || i >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+ return NULL;
+ }
+ return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
+}
+
+static PyObject *
+bytearray_subscript(PyByteArrayObject *self, PyObject *index)
+{
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
+
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+
+ if (i < 0)
+ i += PyByteArray_GET_SIZE(self);
+
+ if (i < 0 || i >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+ return NULL;
+ }
+ return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
+ }
+ else if (PySlice_Check(index)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
+ PyByteArray_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0)
+ return PyByteArray_FromStringAndSize("", 0);
+ else if (step == 1) {
+ return PyByteArray_FromStringAndSize(self->ob_bytes + start,
+ slicelength);
+ }
+ else {
+ char *source_buf = PyByteArray_AS_STRING(self);
+ char *result_buf = (char *)PyMem_Malloc(slicelength);
+ PyObject *result;
+
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+ result = PyByteArray_FromStringAndSize(result_buf, slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
+ return NULL;
+ }
+}
+
+static int
+bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
+ PyObject *values)
+{
+ Py_ssize_t avail, needed;
+ void *bytes;
+ Py_buffer vbytes;
+ int res = 0;
+
+ vbytes.len = -1;
+ if (values == (PyObject *)self) {
+ /* Make a copy and call this function recursively */
+ int err;
+ values = PyByteArray_FromObject(values);
+ if (values == NULL)
+ return -1;
+ err = bytearray_setslice(self, lo, hi, values);
+ Py_DECREF(values);
+ return err;
+ }
+ if (values == NULL) {
+ /* del b[lo:hi] */
+ bytes = NULL;
+ needed = 0;
+ }
+ else {
+ if (_getbuffer(values, &vbytes) < 0) {
+ PyErr_Format(PyExc_TypeError,
+ "can't set bytearray slice from %.100s",
+ Py_TYPE(values)->tp_name);
+ return -1;
+ }
+ needed = vbytes.len;
+ bytes = vbytes.buf;
+ }
+
+ if (lo < 0)
+ lo = 0;
+ if (hi < lo)
+ hi = lo;
+ if (hi > Py_SIZE(self))
+ hi = Py_SIZE(self);
+
+ avail = hi - lo;
+ if (avail < 0)
+ lo = hi = avail = 0;
+
+ if (avail != needed) {
+ if (avail > needed) {
+ if (!_canresize(self)) {
+ res = -1;
+ goto finish;
+ }
+ /*
+ 0 lo hi old_size
+ | |<----avail----->|<-----tomove------>|
+ | |<-needed->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
+ Py_SIZE(self) - hi);
+ }
+ /* XXX(nnorwitz): need to verify this can't overflow! */
+ if (PyByteArray_Resize((PyObject *)self,
+ Py_SIZE(self) + needed - avail) < 0) {
+ res = -1;
+ goto finish;
+ }
+ if (avail < needed) {
+ /*
+ 0 lo hi old_size
+ | |<-avail->|<-----tomove------>|
+ | |<----needed---->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
+ Py_SIZE(self) - lo - needed);
+ }
+ }
+
+ if (needed > 0)
+ memcpy(self->ob_bytes + lo, bytes, needed);
+
+
+ finish:
+ if (vbytes.len != -1)
+ PyBuffer_Release(&vbytes);
+ return res;
+}
+
+static int
+bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
+{
+ int ival;
+
+ if (i < 0)
+ i += Py_SIZE(self);
+
+ if (i < 0 || i >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+ return -1;
+ }
+
+ if (value == NULL)
+ return bytearray_setslice(self, i, i+1, NULL);
+
+ if (!_getbytevalue(value, &ival))
+ return -1;
+
+ self->ob_bytes[i] = ival;
+ return 0;
+}
+
+static int
+bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
+{
+ Py_ssize_t start, stop, step, slicelen, needed;
+ char *bytes;
+
+ if (PyIndex_Check(index)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
+
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+
+ if (i < 0)
+ i += PyByteArray_GET_SIZE(self);
+
+ if (i < 0 || i >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
+ return -1;
+ }
+
+ if (values == NULL) {
+ /* Fall through to slice assignment */
+ start = i;
+ stop = i + 1;
+ step = 1;
+ slicelen = 1;
+ }
+ else {
+ int ival;
+ if (!_getbytevalue(values, &ival))
+ return -1;
+ self->ob_bytes[i] = (char)ival;
+ return 0;
+ }
+ }
+ else if (PySlice_Check(index)) {
+ if (PySlice_GetIndicesEx((PySliceObject *)index,
+ PyByteArray_GET_SIZE(self),
+ &start, &stop, &step, &slicelen) < 0) {
+ return -1;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
+ return -1;
+ }
+
+ if (values == NULL) {
+ bytes = NULL;
+ needed = 0;
+ }
+ else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
+ int err;
+ if (PyNumber_Check(values) || PyUnicode_Check(values)) {
+ PyErr_SetString(PyExc_TypeError,
+ "can assign only bytes, buffers, or iterables "
+ "of ints in range(0, 256)");
+ return -1;
+ }
+ /* Make a copy and call this function recursively */
+ values = PyByteArray_FromObject(values);
+ if (values == NULL)
+ return -1;
+ err = bytearray_ass_subscript(self, index, values);
+ Py_DECREF(values);
+ return err;
+ }
+ else {
+ assert(PyByteArray_Check(values));
+ bytes = ((PyByteArrayObject *)values)->ob_bytes;
+ needed = Py_SIZE(values);
+ }
+ /* Make sure b[5:2] = ... inserts before 5, not before 2. */
+ if ((step < 0 && start < stop) ||
+ (step > 0 && start > stop))
+ stop = start;
+ if (step == 1) {
+ if (slicelen != needed) {
+ if (!_canresize(self))
+ return -1;
+ if (slicelen > needed) {
+ /*
+ 0 start stop old_size
+ | |<---slicelen--->|<-----tomove------>|
+ | |<-needed->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
+ Py_SIZE(self) - stop);
+ }
+ if (PyByteArray_Resize((PyObject *)self,
+ Py_SIZE(self) + needed - slicelen) < 0)
+ return -1;
+ if (slicelen < needed) {
+ /*
+ 0 lo hi old_size
+ | |<-avail->|<-----tomove------>|
+ | |<----needed---->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
+ Py_SIZE(self) - start - needed);
+ }
+ }
+
+ if (needed > 0)
+ memcpy(self->ob_bytes + start, bytes, needed);
+
+ return 0;
+ }
+ else {
+ if (needed == 0) {
+ /* Delete slice */
+ size_t cur;
+ Py_ssize_t i;
+
+ if (!_canresize(self))
+ return -1;
+ if (step < 0) {
+ stop = start + 1;
+ start = stop + step * (slicelen - 1) - 1;
+ step = -step;
+ }
+ for (cur = start, i = 0;
+ i < slicelen; cur += step, i++) {
+ Py_ssize_t lim = step - 1;
+
+ if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
+ lim = PyByteArray_GET_SIZE(self) - cur - 1;
+
+ memmove(self->ob_bytes + cur - i,
+ self->ob_bytes + cur + 1, lim);
+ }
+ /* Move the tail of the bytes, in one chunk */
+ cur = start + slicelen*step;
+ if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
+ memmove(self->ob_bytes + cur - slicelen,
+ self->ob_bytes + cur,
+ PyByteArray_GET_SIZE(self) - cur);
+ }
+ if (PyByteArray_Resize((PyObject *)self,
+ PyByteArray_GET_SIZE(self) - slicelen) < 0)
+ return -1;
+
+ return 0;
+ }
+ else {
+ /* Assign slice */
+ Py_ssize_t cur, i;
+
+ if (needed != slicelen) {
+ PyErr_Format(PyExc_ValueError,
+ "attempt to assign bytes of size %zd "
+ "to extended slice of size %zd",
+ needed, slicelen);
+ return -1;
+ }
+ for (cur = start, i = 0; i < slicelen; cur += step, i++)
+ self->ob_bytes[cur] = bytes[i];
+ return 0;
+ }
+ }
+}
+
+static int
+bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"source", "encoding", "errors", 0};
+ PyObject *arg = NULL;
+ const char *encoding = NULL;
+ const char *errors = NULL;
+ Py_ssize_t count;
+ PyObject *it;
+ PyObject *(*iternext)(PyObject *);
+
+ if (Py_SIZE(self) != 0) {
+ /* Empty previous contents (yes, do this first of all!) */
+ if (PyByteArray_Resize((PyObject *)self, 0) < 0)
+ return -1;
+ }
+
+ /* Parse arguments */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
+ &arg, &encoding, &errors))
+ return -1;
+
+ /* Make a quick exit if no first argument */
+ if (arg == NULL) {
+ if (encoding != NULL || errors != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding or errors without sequence argument");
+ return -1;
+ }
+ return 0;
+ }
+
+ if (PyBytes_Check(arg)) {
+ PyObject *new, *encoded;
+ if (encoding != NULL) {
+ encoded = PyCodec_Encode(arg, encoding, errors);
+ if (encoded == NULL)
+ return -1;
+ assert(PyBytes_Check(encoded));
+ }
+ else {
+ encoded = arg;
+ Py_INCREF(arg);
+ }
+ new = bytearray_iconcat(self, arg);
+ Py_DECREF(encoded);
+ if (new == NULL)
+ return -1;
+ Py_DECREF(new);
+ return 0;
+ }
+
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(arg)) {
+ /* Encode via the codec registry */
+ PyObject *encoded, *new;
+ if (encoding == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "unicode argument without an encoding");
+ return -1;
+ }
+ encoded = PyCodec_Encode(arg, encoding, errors);
+ if (encoded == NULL)
+ return -1;
+ assert(PyBytes_Check(encoded));
+ new = bytearray_iconcat(self, encoded);
+ Py_DECREF(encoded);
+ if (new == NULL)
+ return -1;
+ Py_DECREF(new);
+ return 0;
+ }
+#endif
+
+ /* If it's not unicode, there can't be encoding or errors */
+ if (encoding != NULL || errors != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding or errors without a string argument");
+ return -1;
+ }
+
+ /* Is it an int? */
+ count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
+ if (count == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ return -1;
+ PyErr_Clear();
+ }
+ else if (count < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative count");
+ return -1;
+ }
+ else {
+ if (count > 0) {
+ if (PyByteArray_Resize((PyObject *)self, count))
+ return -1;
+ memset(self->ob_bytes, 0, count);
+ }
+ return 0;
+ }
+
+ /* Use the buffer API */
+ if (PyObject_CheckBuffer(arg)) {
+ Py_ssize_t size;
+ Py_buffer view;
+ if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
+ return -1;
+ size = view.len;
+ if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
+ if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
+ goto fail;
+ PyBuffer_Release(&view);
+ return 0;
+ fail:
+ PyBuffer_Release(&view);
+ return -1;
+ }
+
+ /* XXX Optimize this if the arguments is a list, tuple */
+
+ /* Get the iterator */
+ it = PyObject_GetIter(arg);
+ if (it == NULL)
+ return -1;
+ iternext = *Py_TYPE(it)->tp_iternext;
+
+ /* Run the iterator to exhaustion */
+ for (;;) {
+ PyObject *item;
+ int rc, value;
+
+ /* Get the next item */
+ item = iternext(it);
+ if (item == NULL) {
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+ goto error;
+ PyErr_Clear();
+ }
+ break;
+ }
+
+ /* Interpret it as an int (__index__) */
+ rc = _getbytevalue(item, &value);
+ Py_DECREF(item);
+ if (!rc)
+ goto error;
+
+ /* Append the byte */
+ if (Py_SIZE(self) < self->ob_alloc)
+ Py_SIZE(self)++;
+ else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
+ goto error;
+ self->ob_bytes[Py_SIZE(self)-1] = value;
+ }
+
+ /* Clean up and return success */
+ Py_DECREF(it);
+ return 0;
+
+ error:
+ /* Error handling when it != NULL */
+ Py_DECREF(it);
+ return -1;
+}
+
+/* Mostly copied from string_repr, but without the
+ "smart quote" functionality. */
+static PyObject *
+bytearray_repr(PyByteArrayObject *self)
+{
+ static const char *hexdigits = "0123456789abcdef";
+ const char *quote_prefix = "bytearray(b";
+ const char *quote_postfix = ")";
+ Py_ssize_t length = Py_SIZE(self);
+ /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
+ size_t newsize;
+ PyObject *v;
+ if (length > (PY_SSIZE_T_MAX - 14) / 4) {
+ PyErr_SetString(PyExc_OverflowError,
+ "bytearray object is too large to make repr");
+ return NULL;
+ }
+ newsize = 14 + 4 * length;
+ v = PyString_FromStringAndSize(NULL, newsize);
+ if (v == NULL) {
+ return NULL;
+ }
+ else {
+ register Py_ssize_t i;
+ register char c;
+ register char *p;
+ int quote;
+
+ /* Figure out which quote to use; single is preferred */
+ quote = '\'';
+ {
+ char *test, *start;
+ start = PyByteArray_AS_STRING(self);
+ for (test = start; test < start+length; ++test) {
+ if (*test == '"') {
+ quote = '\''; /* back to single */
+ goto decided;
+ }
+ else if (*test == '\'')
+ quote = '"';
+ }
+ decided:
+ ;
+ }
+
+ p = PyString_AS_STRING(v);
+ while (*quote_prefix)
+ *p++ = *quote_prefix++;
+ *p++ = quote;
+
+ for (i = 0; i < length; i++) {
+ /* There's at least enough room for a hex escape
+ and a closing quote. */
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+ c = self->ob_bytes[i];
+ if (c == '\'' || c == '\\')
+ *p++ = '\\', *p++ = c;
+ else if (c == '\t')
+ *p++ = '\\', *p++ = 't';
+ else if (c == '\n')
+ *p++ = '\\', *p++ = 'n';
+ else if (c == '\r')
+ *p++ = '\\', *p++ = 'r';
+ else if (c == 0)
+ *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
+ else if (c < ' ' || c >= 0x7f) {
+ *p++ = '\\';
+ *p++ = 'x';
+ *p++ = hexdigits[(c & 0xf0) >> 4];
+ *p++ = hexdigits[c & 0xf];
+ }
+ else
+ *p++ = c;
+ }
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+ *p++ = quote;
+ while (*quote_postfix) {
+ *p++ = *quote_postfix++;
+ }
+ *p = '\0';
+ /* v is cleared on error */
+ (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
+ return v;
+ }
+}
+
+static PyObject *
+bytearray_str(PyObject *op)
+{
+#if 0
+ if (Py_BytesWarningFlag) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "str() on a bytearray instance", 1))
+ return NULL;
+ }
+ return bytearray_repr((PyByteArrayObject*)op);
+#endif
+ return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
+}
+
+static PyObject *
+bytearray_richcompare(PyObject *self, PyObject *other, int op)
+{
+ Py_ssize_t self_size, other_size;
+ Py_buffer self_bytes, other_bytes;
+ PyObject *res;
+ Py_ssize_t minsize;
+ int cmp;
+
+ /* Bytes can be compared to anything that supports the (binary)
+ buffer API. Except that a comparison with Unicode is always an
+ error, even if the comparison is for equality. */
+#ifdef Py_USING_UNICODE
+ if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
+ PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
+ if (Py_BytesWarningFlag && op == Py_EQ) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "Comparison between bytearray and string", 1))
+ return NULL;
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+#endif
+
+ self_size = _getbuffer(self, &self_bytes);
+ if (self_size < 0) {
+ PyErr_Clear();
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ other_size = _getbuffer(other, &other_bytes);
+ if (other_size < 0) {
+ PyErr_Clear();
+ PyBuffer_Release(&self_bytes);
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
+ /* Shortcut: if the lengths differ, the objects differ */
+ cmp = (op == Py_NE);
+ }
+ else {
+ minsize = self_size;
+ if (other_size < minsize)
+ minsize = other_size;
+
+ cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
+ /* In ISO C, memcmp() guarantees to use unsigned bytes! */
+
+ if (cmp == 0) {
+ if (self_size < other_size)
+ cmp = -1;
+ else if (self_size > other_size)
+ cmp = 1;
+ }
+
+ switch (op) {
+ case Py_LT: cmp = cmp < 0; break;
+ case Py_LE: cmp = cmp <= 0; break;
+ case Py_EQ: cmp = cmp == 0; break;
+ case Py_NE: cmp = cmp != 0; break;
+ case Py_GT: cmp = cmp > 0; break;
+ case Py_GE: cmp = cmp >= 0; break;
+ }
+ }
+
+ res = cmp ? Py_True : Py_False;
+ PyBuffer_Release(&self_bytes);
+ PyBuffer_Release(&other_bytes);
+ Py_INCREF(res);
+ return res;
+}
+
+static void
+bytearray_dealloc(PyByteArrayObject *self)
+{
+ if (self->ob_exports > 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "deallocated bytearray object has exported buffers");
+ PyErr_Print();
+ }
+ if (self->ob_bytes != 0) {
+ PyMem_Free(self->ob_bytes);
+ }
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Methods */
+
+#define STRINGLIB_CHAR char
+#define STRINGLIB_LEN PyByteArray_GET_SIZE
+#define STRINGLIB_STR PyByteArray_AS_STRING
+#define STRINGLIB_NEW PyByteArray_FromStringAndSize
+#define STRINGLIB_ISSPACE Py_ISSPACE
+#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
+#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
+#define STRINGLIB_MUTABLE 1
+
+#include "stringlib/fastsearch.h"
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+#include "stringlib/ctype.h"
+#include "stringlib/transmogrify.h"
+
+
+/* The following Py_LOCAL_INLINE and Py_LOCAL functions
+were copied from the old char* style string object. */
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
+{
+ PyObject *subobj;
+ Py_buffer subbuf;
+ Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+ Py_ssize_t res;
+
+ if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+ args, &subobj, &start, &end))
+ return -2;
+ if (_getbuffer(subobj, &subbuf) < 0)
+ return -2;
+ if (dir > 0)
+ res = stringlib_find_slice(
+ PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+ subbuf.buf, subbuf.len, start, end);
+ else
+ res = stringlib_rfind_slice(
+ PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+ subbuf.buf, subbuf.len, start, end);
+ PyBuffer_Release(&subbuf);
+ return res;
+}
+
+PyDoc_STRVAR(find__doc__,
+"B.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in B where subsection sub is found,\n\
+such that sub is contained within B[start,end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+bytearray_find(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t result = bytearray_find_internal(self, args, +1);
+ if (result == -2)
+ return NULL;
+ return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(count__doc__,
+"B.count(sub [,start [,end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of subsection sub in\n\
+bytes B[start:end]. Optional arguments start and end are interpreted\n\
+as in slice notation.");
+
+static PyObject *
+bytearray_count(PyByteArrayObject *self, PyObject *args)
+{
+ PyObject *sub_obj;
+ const char *str = PyByteArray_AS_STRING(self);
+ Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+ Py_buffer vsub;
+ PyObject *count_obj;
+
+ if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
+ return NULL;
+
+ if (_getbuffer(sub_obj, &vsub) < 0)
+ return NULL;
+
+ ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
+
+ count_obj = PyInt_FromSsize_t(
+ stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
+ );
+ PyBuffer_Release(&vsub);
+ return count_obj;
+}
+
+
+PyDoc_STRVAR(index__doc__,
+"B.index(sub [,start [,end]]) -> int\n\
+\n\
+Like B.find() but raise ValueError when the subsection is not found.");
+
+static PyObject *
+bytearray_index(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t result = bytearray_find_internal(self, args, +1);
+ if (result == -2)
+ return NULL;
+ if (result == -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "subsection not found");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"B.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in B where subsection sub is found,\n\
+such that sub is contained within B[start,end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+bytearray_rfind(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t result = bytearray_find_internal(self, args, -1);
+ if (result == -2)
+ return NULL;
+ return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rindex__doc__,
+"B.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like B.rfind() but raise ValueError when the subsection is not found.");
+
+static PyObject *
+bytearray_rindex(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t result = bytearray_find_internal(self, args, -1);
+ if (result == -2)
+ return NULL;
+ if (result == -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "subsection not found");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(result);
+}
+
+
+static int
+bytearray_contains(PyObject *self, PyObject *arg)
+{
+ Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
+ if (ival == -1 && PyErr_Occurred()) {
+ Py_buffer varg;
+ int pos;
+ PyErr_Clear();
+ if (_getbuffer(arg, &varg) < 0)
+ return -1;
+ pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
+ varg.buf, varg.len, 0);
+ PyBuffer_Release(&varg);
+ return pos >= 0;
+ }
+ if (ival < 0 || ival >= 256) {
+ PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ return -1;
+ }
+
+ return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
+}
+
+
+/* Matches the end (direction >= 0) or start (direction < 0) of self
+ * against substr, using the start and end arguments. Returns
+ * -1 on error, 0 if not found and 1 if found.
+ */
+Py_LOCAL(int)
+_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
+ Py_ssize_t end, int direction)
+{
+ Py_ssize_t len = PyByteArray_GET_SIZE(self);
+ const char* str;
+ Py_buffer vsubstr;
+ int rv = 0;
+
+ str = PyByteArray_AS_STRING(self);
+
+ if (_getbuffer(substr, &vsubstr) < 0)
+ return -1;
+
+ ADJUST_INDICES(start, end, len);
+
+ if (direction < 0) {
+ /* startswith */
+ if (start+vsubstr.len > len) {
+ goto done;
+ }
+ } else {
+ /* endswith */
+ if (end-start < vsubstr.len || start > len) {
+ goto done;
+ }
+
+ if (end-vsubstr.len > start)
+ start = end - vsubstr.len;
+ }
+ if (end-start >= vsubstr.len)
+ rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
+
+done:
+ PyBuffer_Release(&vsubstr);
+ return rv;
+}
+
+
+PyDoc_STRVAR(startswith__doc__,
+"B.startswith(prefix [,start [,end]]) -> bool\n\
+\n\
+Return True if B starts with the specified prefix, False otherwise.\n\
+With optional start, test B beginning at that position.\n\
+With optional end, stop comparing B at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+bytearray_startswith(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ PyObject *subobj;
+ int result;
+
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ result = _bytearray_tailmatch(self,
+ PyTuple_GET_ITEM(subobj, i),
+ start, end, -1);
+ if (result == -1)
+ return NULL;
+ else if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ result = _bytearray_tailmatch(self, subobj, start, end, -1);
+ if (result == -1)
+ return NULL;
+ else
+ return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(endswith__doc__,
+"B.endswith(suffix [,start [,end]]) -> bool\n\
+\n\
+Return True if B ends with the specified suffix, False otherwise.\n\
+With optional start, test B beginning at that position.\n\
+With optional end, stop comparing B at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+bytearray_endswith(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ PyObject *subobj;
+ int result;
+
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ result = _bytearray_tailmatch(self,
+ PyTuple_GET_ITEM(subobj, i),
+ start, end, +1);
+ if (result == -1)
+ return NULL;
+ else if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ result = _bytearray_tailmatch(self, subobj, start, end, +1);
+ if (result == -1)
+ return NULL;
+ else
+ return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"B.translate(table[, deletechars]) -> bytearray\n\
+\n\
+Return a copy of B, where all characters occurring in the\n\
+optional argument deletechars are removed, and the remaining\n\
+characters have been mapped through the given translation\n\
+table, which must be a bytes object of length 256.");
+
+static PyObject *
+bytearray_translate(PyByteArrayObject *self, PyObject *args)
+{
+ register char *input, *output;
+ register const char *table;
+ register Py_ssize_t i, c;
+ PyObject *input_obj = (PyObject*)self;
+ const char *output_start;
+ Py_ssize_t inlen;
+ PyObject *result = NULL;
+ int trans_table[256];
+ PyObject *tableobj = NULL, *delobj = NULL;
+ Py_buffer vtable, vdel;
+
+ if (!PyArg_UnpackTuple(args, "translate", 1, 2,
+ &tableobj, &delobj))
+ return NULL;
+
+ if (tableobj == Py_None) {
+ table = NULL;
+ tableobj = NULL;
+ } else if (_getbuffer(tableobj, &vtable) < 0) {
+ return NULL;
+ } else {
+ if (vtable.len != 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "translation table must be 256 characters long");
+ PyBuffer_Release(&vtable);
+ return NULL;
+ }
+ table = (const char*)vtable.buf;
+ }
+
+ if (delobj != NULL) {
+ if (_getbuffer(delobj, &vdel) < 0) {
+ if (tableobj != NULL)
+ PyBuffer_Release(&vtable);
+ return NULL;
+ }
+ }
+ else {
+ vdel.buf = NULL;
+ vdel.len = 0;
+ }
+
+ inlen = PyByteArray_GET_SIZE(input_obj);
+ result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
+ if (result == NULL)
+ goto done;
+ output_start = output = PyByteArray_AsString(result);
+ input = PyByteArray_AS_STRING(input_obj);
+
+ if (vdel.len == 0 && table != NULL) {
+ /* If no deletions are required, use faster code */
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ *output++ = table[c];
+ }
+ goto done;
+ }
+
+ if (table == NULL) {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(i);
+ } else {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(table[i]);
+ }
+
+ for (i = 0; i < vdel.len; i++)
+ trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
+
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (trans_table[c] != -1)
+ if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+ continue;
+ }
+ /* Fix the size of the resulting string */
+ if (inlen > 0)
+ PyByteArray_Resize(result, output - output_start);
+
+done:
+ if (tableobj != NULL)
+ PyBuffer_Release(&vtable);
+ if (delobj != NULL)
+ PyBuffer_Release(&vdel);
+ return result;
+}
+
+
+/* find and count characters and substrings */
+
+#define findchar(target, target_len, c) \
+ ((char *)memchr((const void *)(target), c, target_len))
+
+
+/* Bytes ops must return a string, create a copy */
+Py_LOCAL(PyByteArrayObject *)
+return_self(PyByteArrayObject *self)
+{
+ return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
+ PyByteArray_AS_STRING(self),
+ PyByteArray_GET_SIZE(self));
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
+{
+ Py_ssize_t count=0;
+ const char *start=target;
+ const char *end=target+target_len;
+
+ while ( (start=findchar(start, end-start, c)) != NULL ) {
+ count++;
+ if (count >= maxcount)
+ break;
+ start += 1;
+ }
+ return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_interleave(PyByteArrayObject *self,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, i, product;
+ PyByteArrayObject *result;
+
+ self_len = PyByteArray_GET_SIZE(self);
+
+ /* 1 at the end plus 1 after every character */
+ count = self_len+1;
+ if (maxcount < count)
+ count = maxcount;
+
+ /* Check for overflow */
+ /* result_len = count * to_len + self_len; */
+ product = count * to_len;
+ if (product / to_len != count) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+ result_len = product + self_len;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+
+ if (! (result = (PyByteArrayObject *)
+ PyByteArray_FromStringAndSize(NULL, result_len)) )
+ return NULL;
+
+ self_s = PyByteArray_AS_STRING(self);
+ result_s = PyByteArray_AS_STRING(result);
+
+ /* TODO: special case single character, which doesn't need memcpy */
+
+ /* Lay the first one down (guaranteed this will occur) */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ count -= 1;
+
+ for (i=0; i<count; i++) {
+ *result_s++ = *self_s++;
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ }
+
+ /* Copy the rest of the original string */
+ Py_MEMCPY(result_s, self_s, self_len-i);
+
+ return result;
+}
+
+/* Special case for deleting a single character */
+/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_delete_single_character(PyByteArrayObject *self,
+ char from_c, Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count;
+ PyByteArrayObject *result;
+
+ self_len = PyByteArray_GET_SIZE(self);
+ self_s = PyByteArray_AS_STRING(self);
+
+ count = countchar(self_s, self_len, from_c, maxcount);
+ if (count == 0) {
+ return return_self(self);
+ }
+
+ result_len = self_len - count; /* from_len == 1 */
+ assert(result_len>=0);
+
+ if ( (result = (PyByteArrayObject *)
+ PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyByteArray_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ start = next+1;
+ }
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
+
+Py_LOCAL(PyByteArrayObject *)
+replace_delete_substring(PyByteArrayObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, offset;
+ PyByteArrayObject *result;
+
+ self_len = PyByteArray_GET_SIZE(self);
+ self_s = PyByteArray_AS_STRING(self);
+
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
+
+ if (count == 0) {
+ /* no matches */
+ return return_self(self);
+ }
+
+ result_len = self_len - (count * from_len);
+ assert (result_len>=0);
+
+ if ( (result = (PyByteArrayObject *)
+ PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
+ return NULL;
+
+ result_s = PyByteArray_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset == -1)
+ break;
+ next = start + offset;
+
+ Py_MEMCPY(result_s, start, next-start);
+
+ result_s += (next-start);
+ start = next+from_len;
+ }
+ Py_MEMCPY(result_s, start, end-start);
+ return result;
+}
+
+/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_single_character_in_place(PyByteArrayObject *self,
+ char from_c, char to_c,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s, *start, *end, *next;
+ Py_ssize_t self_len;
+ PyByteArrayObject *result;
+
+ /* The result string will be the same size */
+ self_s = PyByteArray_AS_STRING(self);
+ self_len = PyByteArray_GET_SIZE(self);
+
+ next = findchar(self_s, self_len, from_c);
+
+ if (next == NULL) {
+ /* No matches; return the original bytes */
+ return return_self(self);
+ }
+
+ /* Need to make a new bytes */
+ result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
+ if (result == NULL)
+ return NULL;
+ result_s = PyByteArray_AS_STRING(result);
+ Py_MEMCPY(result_s, self_s, self_len);
+
+ /* change everything in-place, starting with this one */
+ start = result_s + (next-self_s);
+ *start = to_c;
+ start++;
+ end = result_s + self_len;
+
+ while (--maxcount > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+ *next = to_c;
+ start = next+1;
+ }
+
+ return result;
+}
+
+/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_substring_in_place(PyByteArrayObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *result_s, *start, *end;
+ char *self_s;
+ Py_ssize_t self_len, offset;
+ PyByteArrayObject *result;
+
+ /* The result bytes will be the same size */
+
+ self_s = PyByteArray_AS_STRING(self);
+ self_len = PyByteArray_GET_SIZE(self);
+
+ offset = stringlib_find(self_s, self_len,
+ from_s, from_len,
+ 0);
+ if (offset == -1) {
+ /* No matches; return the original bytes */
+ return return_self(self);
+ }
+
+ /* Need to make a new bytes */
+ result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
+ if (result == NULL)
+ return NULL;
+ result_s = PyByteArray_AS_STRING(result);
+ Py_MEMCPY(result_s, self_s, self_len);
+
+ /* change everything in-place, starting with this one */
+ start = result_s + offset;
+ Py_MEMCPY(start, to_s, from_len);
+ start += from_len;
+ end = result_s + self_len;
+
+ while ( --maxcount > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset==-1)
+ break;
+ Py_MEMCPY(start+offset, to_s, from_len);
+ start += offset+from_len;
+ }
+
+ return result;
+}
+
+/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_single_character(PyByteArrayObject *self,
+ char from_c,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, product;
+ PyByteArrayObject *result;
+
+ self_s = PyByteArray_AS_STRING(self);
+ self_len = PyByteArray_GET_SIZE(self);
+
+ count = countchar(self_s, self_len, from_c, maxcount);
+ if (count == 0) {
+ /* no matches, return unchanged */
+ return return_self(self);
+ }
+
+ /* use the difference between current and new, hence the "-1" */
+ /* result_len = self_len + count * (to_len-1) */
+ product = count * (to_len-1);
+ if (product / (to_len-1) != count) {
+ PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+ return NULL;
+ }
+ result_len = self_len + product;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+ return NULL;
+ }
+
+ if ( (result = (PyByteArrayObject *)
+ PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyByteArray_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+
+ if (next == start) {
+ /* replace with the 'to' */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start += 1;
+ } else {
+ /* copy the unchanged old then the 'to' */
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start = next+1;
+ }
+ }
+ /* Copy the remainder of the remaining bytes */
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyByteArrayObject *)
+replace_substring(PyByteArrayObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, offset, product;
+ PyByteArrayObject *result;
+
+ self_s = PyByteArray_AS_STRING(self);
+ self_len = PyByteArray_GET_SIZE(self);
+
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
+
+ if (count == 0) {
+ /* no matches, return unchanged */
+ return return_self(self);
+ }
+
+ /* Check for overflow */
+ /* result_len = self_len + count * (to_len-from_len) */
+ product = count * (to_len-from_len);
+ if (product / (to_len-from_len) != count) {
+ PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+ return NULL;
+ }
+ result_len = self_len + product;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
+ return NULL;
+ }
+
+ if ( (result = (PyByteArrayObject *)
+ PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyByteArray_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset == -1)
+ break;
+ next = start+offset;
+ if (next == start) {
+ /* replace with the 'to' */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start += from_len;
+ } else {
+ /* copy the unchanged old then the 'to' */
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start = next+from_len;
+ }
+ }
+ /* Copy the remainder of the remaining bytes */
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+
+Py_LOCAL(PyByteArrayObject *)
+replace(PyByteArrayObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ if (maxcount < 0) {
+ maxcount = PY_SSIZE_T_MAX;
+ } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
+ /* nothing to do; return the original bytes */
+ return return_self(self);
+ }
+
+ if (maxcount == 0 ||
+ (from_len == 0 && to_len == 0)) {
+ /* nothing to do; return the original bytes */
+ return return_self(self);
+ }
+
+ /* Handle zero-length special cases */
+
+ if (from_len == 0) {
+ /* insert the 'to' bytes everywhere. */
+ /* >>> "Python".replace("", ".") */
+ /* '.P.y.t.h.o.n.' */
+ return replace_interleave(self, to_s, to_len, maxcount);
+ }
+
+ /* Except for "".replace("", "A") == "A" there is no way beyond this */
+ /* point for an empty self bytes to generate a non-empty bytes */
+ /* Special case so the remaining code always gets a non-empty bytes */
+ if (PyByteArray_GET_SIZE(self) == 0) {
+ return return_self(self);
+ }
+
+ if (to_len == 0) {
+ /* delete all occurances of 'from' bytes */
+ if (from_len == 1) {
+ return replace_delete_single_character(
+ self, from_s[0], maxcount);
+ } else {
+ return replace_delete_substring(self, from_s, from_len, maxcount);
+ }
+ }
+
+ /* Handle special case where both bytes have the same length */
+
+ if (from_len == to_len) {
+ if (from_len == 1) {
+ return replace_single_character_in_place(
+ self,
+ from_s[0],
+ to_s[0],
+ maxcount);
+ } else {
+ return replace_substring_in_place(
+ self, from_s, from_len, to_s, to_len, maxcount);
+ }
+ }
+
+ /* Otherwise use the more generic algorithms */
+ if (from_len == 1) {
+ return replace_single_character(self, from_s[0],
+ to_s, to_len, maxcount);
+ } else {
+ /* len('from')>=2, len('to')>=1 */
+ return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
+ }
+}
+
+
+PyDoc_STRVAR(replace__doc__,
+"B.replace(old, new[, count]) -> bytes\n\
+\n\
+Return a copy of B with all occurrences of subsection\n\
+old replaced by new. If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject *
+bytearray_replace(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t count = -1;
+ PyObject *from, *to, *res;
+ Py_buffer vfrom, vto;
+
+ if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+ return NULL;
+
+ if (_getbuffer(from, &vfrom) < 0)
+ return NULL;
+ if (_getbuffer(to, &vto) < 0) {
+ PyBuffer_Release(&vfrom);
+ return NULL;
+ }
+
+ res = (PyObject *)replace((PyByteArrayObject *) self,
+ vfrom.buf, vfrom.len,
+ vto.buf, vto.len, count);
+
+ PyBuffer_Release(&vfrom);
+ PyBuffer_Release(&vto);
+ return res;
+}
+
+PyDoc_STRVAR(split__doc__,
+"B.split([sep[, maxsplit]]) -> list of bytearray\n\
+\n\
+Return a list of the sections in B, using sep as the delimiter.\n\
+If sep is not given, B is split on ASCII whitespace characters\n\
+(space, tab, return, newline, formfeed, vertical tab).\n\
+If maxsplit is given, at most maxsplit splits are done.");
+
+static PyObject *
+bytearray_split(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyByteArray_AS_STRING(self), *sub;
+ PyObject *list, *subobj = Py_None;
+ Py_buffer vsub;
+
+ if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+ return NULL;
+ if (maxsplit < 0)
+ maxsplit = PY_SSIZE_T_MAX;
+
+ if (subobj == Py_None)
+ return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
+
+ if (_getbuffer(subobj, &vsub) < 0)
+ return NULL;
+ sub = vsub.buf;
+ n = vsub.len;
+
+ list = stringlib_split(
+ (PyObject*) self, s, len, sub, n, maxsplit
+ );
+ PyBuffer_Release(&vsub);
+ return list;
+}
+
+PyDoc_STRVAR(partition__doc__,
+"B.partition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in B, and returns the part before it,\n\
+the separator itself, and the part after it. If the separator is not\n\
+found, returns B and two empty bytearray objects.");
+
+static PyObject *
+bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
+{
+ PyObject *bytesep, *result;
+
+ bytesep = PyByteArray_FromObject(sep_obj);
+ if (! bytesep)
+ return NULL;
+
+ result = stringlib_partition(
+ (PyObject*) self,
+ PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+ bytesep,
+ PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
+ );
+
+ Py_DECREF(bytesep);
+ return result;
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"B.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Searches for the separator sep in B, starting at the end of B,\n\
+and returns the part before it, the separator itself, and the\n\
+part after it. If the separator is not found, returns two empty\n\
+bytearray objects and B.");
+
+static PyObject *
+bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
+{
+ PyObject *bytesep, *result;
+
+ bytesep = PyByteArray_FromObject(sep_obj);
+ if (! bytesep)
+ return NULL;
+
+ result = stringlib_rpartition(
+ (PyObject*) self,
+ PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
+ bytesep,
+ PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
+ );
+
+ Py_DECREF(bytesep);
+ return result;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
+\n\
+Return a list of the sections in B, using sep as the delimiter,\n\
+starting at the end of B and working to the front.\n\
+If sep is not given, B is split on ASCII whitespace characters\n\
+(space, tab, return, newline, formfeed, vertical tab).\n\
+If maxsplit is given, at most maxsplit splits are done.");
+
+static PyObject *
+bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyByteArray_AS_STRING(self), *sub;
+ PyObject *list, *subobj = Py_None;
+ Py_buffer vsub;
+
+ if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+ return NULL;
+ if (maxsplit < 0)
+ maxsplit = PY_SSIZE_T_MAX;
+
+ if (subobj == Py_None)
+ return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
+
+ if (_getbuffer(subobj, &vsub) < 0)
+ return NULL;
+ sub = vsub.buf;
+ n = vsub.len;
+
+ list = stringlib_rsplit(
+ (PyObject*) self, s, len, sub, n, maxsplit
+ );
+ PyBuffer_Release(&vsub);
+ return list;
+}
+
+PyDoc_STRVAR(reverse__doc__,
+"B.reverse() -> None\n\
+\n\
+Reverse the order of the values in B in place.");
+static PyObject *
+bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
+{
+ char swap, *head, *tail;
+ Py_ssize_t i, j, n = Py_SIZE(self);
+
+ j = n / 2;
+ head = self->ob_bytes;
+ tail = head + n - 1;
+ for (i = 0; i < j; i++) {
+ swap = *head;
+ *head++ = *tail;
+ *tail-- = swap;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(insert__doc__,
+"B.insert(index, int) -> None\n\
+\n\
+Insert a single item into the bytearray before the given index.");
+static PyObject *
+bytearray_insert(PyByteArrayObject *self, PyObject *args)
+{
+ PyObject *value;
+ int ival;
+ Py_ssize_t where, n = Py_SIZE(self);
+
+ if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
+ return NULL;
+
+ if (n == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot add more objects to bytearray");
+ return NULL;
+ }
+ if (!_getbytevalue(value, &ival))
+ return NULL;
+ if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+ return NULL;
+
+ if (where < 0) {
+ where += n;
+ if (where < 0)
+ where = 0;
+ }
+ if (where > n)
+ where = n;
+ memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
+ self->ob_bytes[where] = ival;
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(append__doc__,
+"B.append(int) -> None\n\
+\n\
+Append a single item to the end of B.");
+static PyObject *
+bytearray_append(PyByteArrayObject *self, PyObject *arg)
+{
+ int value;
+ Py_ssize_t n = Py_SIZE(self);
+
+ if (! _getbytevalue(arg, &value))
+ return NULL;
+ if (n == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot add more objects to bytearray");
+ return NULL;
+ }
+ if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+ return NULL;
+
+ self->ob_bytes[n] = value;
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(extend__doc__,
+"B.extend(iterable int) -> None\n\
+\n\
+Append all the elements from the iterator or sequence to the\n\
+end of B.");
+static PyObject *
+bytearray_extend(PyByteArrayObject *self, PyObject *arg)
+{
+ PyObject *it, *item, *bytearray_obj;
+ Py_ssize_t buf_size = 0, len = 0;
+ int value;
+ char *buf;
+
+ /* bytearray_setslice code only accepts something supporting PEP 3118. */
+ if (PyObject_CheckBuffer(arg)) {
+ if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
+ return NULL;
+
+ Py_RETURN_NONE;
+ }
+
+ it = PyObject_GetIter(arg);
+ if (it == NULL)
+ return NULL;
+
+ /* Try to determine the length of the argument. 32 is arbitrary. */
+ buf_size = _PyObject_LengthHint(arg, 32);
+ if (buf_size == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+
+ bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
+ if (bytearray_obj == NULL) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ buf = PyByteArray_AS_STRING(bytearray_obj);
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ if (! _getbytevalue(item, &value)) {
+ Py_DECREF(item);
+ Py_DECREF(it);
+ Py_DECREF(bytearray_obj);
+ return NULL;
+ }
+ buf[len++] = value;
+ Py_DECREF(item);
+
+ if (len >= buf_size) {
+ buf_size = len + (len >> 1) + 1;
+ if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
+ Py_DECREF(it);
+ Py_DECREF(bytearray_obj);
+ return NULL;
+ }
+ /* Recompute the `buf' pointer, since the resizing operation may
+ have invalidated it. */
+ buf = PyByteArray_AS_STRING(bytearray_obj);
+ }
+ }
+ Py_DECREF(it);
+
+ /* Resize down to exact size. */
+ if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
+ Py_DECREF(bytearray_obj);
+ return NULL;
+ }
+
+ if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
+ Py_DECREF(bytearray_obj);
+ return NULL;
+ }
+ Py_DECREF(bytearray_obj);
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(pop__doc__,
+"B.pop([index]) -> int\n\
+\n\
+Remove and return a single item from B. If no index\n\
+argument is given, will pop the last value.");
+static PyObject *
+bytearray_pop(PyByteArrayObject *self, PyObject *args)
+{
+ int value;
+ Py_ssize_t where = -1, n = Py_SIZE(self);
+
+ if (!PyArg_ParseTuple(args, "|n:pop", &where))
+ return NULL;
+
+ if (n == 0) {
+ PyErr_SetString(PyExc_IndexError,
+ "pop from empty bytearray");
+ return NULL;
+ }
+ if (where < 0)
+ where += Py_SIZE(self);
+ if (where < 0 || where >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "pop index out of range");
+ return NULL;
+ }
+ if (!_canresize(self))
+ return NULL;
+
+ value = self->ob_bytes[where];
+ memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+ if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+ return NULL;
+
+ return PyInt_FromLong((unsigned char)value);
+}
+
+PyDoc_STRVAR(remove__doc__,
+"B.remove(int) -> None\n\
+\n\
+Remove the first occurance of a value in B.");
+static PyObject *
+bytearray_remove(PyByteArrayObject *self, PyObject *arg)
+{
+ int value;
+ Py_ssize_t where, n = Py_SIZE(self);
+
+ if (! _getbytevalue(arg, &value))
+ return NULL;
+
+ for (where = 0; where < n; where++) {
+ if (self->ob_bytes[where] == value)
+ break;
+ }
+ if (where == n) {
+ PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
+ return NULL;
+ }
+ if (!_canresize(self))
+ return NULL;
+
+ memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+ if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+/* XXX These two helpers could be optimized if argsize == 1 */
+
+static Py_ssize_t
+lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+ void *argptr, Py_ssize_t argsize)
+{
+ Py_ssize_t i = 0;
+ while (i < mysize && memchr(argptr, myptr[i], argsize))
+ i++;
+ return i;
+}
+
+static Py_ssize_t
+rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+ void *argptr, Py_ssize_t argsize)
+{
+ Py_ssize_t i = mysize - 1;
+ while (i >= 0 && memchr(argptr, myptr[i], argsize))
+ i--;
+ return i + 1;
+}
+
+PyDoc_STRVAR(strip__doc__,
+"B.strip([bytes]) -> bytearray\n\
+\n\
+Strip leading and trailing bytes contained in the argument.\n\
+If the argument is omitted, strip ASCII whitespace.");
+static PyObject *
+bytearray_strip(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t left, right, mysize, argsize;
+ void *myptr, *argptr;
+ PyObject *arg = Py_None;
+ Py_buffer varg;
+ if (!PyArg_ParseTuple(args, "|O:strip", &arg))
+ return NULL;
+ if (arg == Py_None) {
+ argptr = "\t\n\r\f\v ";
+ argsize = 6;
+ }
+ else {
+ if (_getbuffer(arg, &varg) < 0)
+ return NULL;
+ argptr = varg.buf;
+ argsize = varg.len;
+ }
+ myptr = self->ob_bytes;
+ mysize = Py_SIZE(self);
+ left = lstrip_helper(myptr, mysize, argptr, argsize);
+ if (left == mysize)
+ right = left;
+ else
+ right = rstrip_helper(myptr, mysize, argptr, argsize);
+ if (arg != Py_None)
+ PyBuffer_Release(&varg);
+ return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(lstrip__doc__,
+"B.lstrip([bytes]) -> bytearray\n\
+\n\
+Strip leading bytes contained in the argument.\n\
+If the argument is omitted, strip leading ASCII whitespace.");
+static PyObject *
+bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t left, right, mysize, argsize;
+ void *myptr, *argptr;
+ PyObject *arg = Py_None;
+ Py_buffer varg;
+ if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
+ return NULL;
+ if (arg == Py_None) {
+ argptr = "\t\n\r\f\v ";
+ argsize = 6;
+ }
+ else {
+ if (_getbuffer(arg, &varg) < 0)
+ return NULL;
+ argptr = varg.buf;
+ argsize = varg.len;
+ }
+ myptr = self->ob_bytes;
+ mysize = Py_SIZE(self);
+ left = lstrip_helper(myptr, mysize, argptr, argsize);
+ right = mysize;
+ if (arg != Py_None)
+ PyBuffer_Release(&varg);
+ return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(rstrip__doc__,
+"B.rstrip([bytes]) -> bytearray\n\
+\n\
+Strip trailing bytes contained in the argument.\n\
+If the argument is omitted, strip trailing ASCII whitespace.");
+static PyObject *
+bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
+{
+ Py_ssize_t left, right, mysize, argsize;
+ void *myptr, *argptr;
+ PyObject *arg = Py_None;
+ Py_buffer varg;
+ if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
+ return NULL;
+ if (arg == Py_None) {
+ argptr = "\t\n\r\f\v ";
+ argsize = 6;
+ }
+ else {
+ if (_getbuffer(arg, &varg) < 0)
+ return NULL;
+ argptr = varg.buf;
+ argsize = varg.len;
+ }
+ myptr = self->ob_bytes;
+ mysize = Py_SIZE(self);
+ left = 0;
+ right = rstrip_helper(myptr, mysize, argptr, argsize);
+ if (arg != Py_None)
+ PyBuffer_Release(&varg);
+ return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+}
+
+PyDoc_STRVAR(decode_doc,
+"B.decode([encoding[, errors]]) -> unicode object.\n\
+\n\
+Decodes B using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ const char *encoding = NULL;
+ const char *errors = NULL;
+ static char *kwlist[] = {"encoding", "errors", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
+ return NULL;
+ if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+ encoding = PyUnicode_GetDefaultEncoding();
+#else
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ return NULL;
+#endif
+ }
+ return PyCodec_Decode(self, encoding, errors);
+}
+
+PyDoc_STRVAR(alloc_doc,
+"B.__alloc__() -> int\n\
+\n\
+Returns the number of bytes actually allocated.");
+
+static PyObject *
+bytearray_alloc(PyByteArrayObject *self)
+{
+ return PyInt_FromSsize_t(self->ob_alloc);
+}
+
+PyDoc_STRVAR(join_doc,
+"B.join(iterable_of_bytes) -> bytes\n\
+\n\
+Concatenates any number of bytearray objects, with B in between each pair.");
+
+static PyObject *
+bytearray_join(PyByteArrayObject *self, PyObject *it)
+{
+ PyObject *seq;
+ Py_ssize_t mysize = Py_SIZE(self);
+ Py_ssize_t i;
+ Py_ssize_t n;
+ PyObject **items;
+ Py_ssize_t totalsize = 0;
+ PyObject *result;
+ char *dest;
+
+ seq = PySequence_Fast(it, "can only join an iterable");
+ if (seq == NULL)
+ return NULL;
+ n = PySequence_Fast_GET_SIZE(seq);
+ items = PySequence_Fast_ITEMS(seq);
+
+ /* Compute the total size, and check that they are all bytes */
+ /* XXX Shouldn't we use _getbuffer() on these items instead? */
+ for (i = 0; i < n; i++) {
+ PyObject *obj = items[i];
+ if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only join an iterable of bytes "
+ "(item %ld has type '%.100s')",
+ /* XXX %ld isn't right on Win64 */
+ (long)i, Py_TYPE(obj)->tp_name);
+ goto error;
+ }
+ if (i > 0)
+ totalsize += mysize;
+ totalsize += Py_SIZE(obj);
+ if (totalsize < 0) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ }
+
+ /* Allocate the result, and copy the bytes */
+ result = PyByteArray_FromStringAndSize(NULL, totalsize);
+ if (result == NULL)
+ goto error;
+ dest = PyByteArray_AS_STRING(result);
+ for (i = 0; i < n; i++) {
+ PyObject *obj = items[i];
+ Py_ssize_t size = Py_SIZE(obj);
+ char *buf;
+ if (PyByteArray_Check(obj))
+ buf = PyByteArray_AS_STRING(obj);
+ else
+ buf = PyBytes_AS_STRING(obj);
+ if (i) {
+ memcpy(dest, self->ob_bytes, mysize);
+ dest += mysize;
+ }
+ memcpy(dest, buf, size);
+ dest += size;
+ }
+
+ /* Done */
+ Py_DECREF(seq);
+ return result;
+
+ /* Error handling */
+ error:
+ Py_DECREF(seq);
+ return NULL;
+}
+
+PyDoc_STRVAR(splitlines__doc__,
+"B.splitlines(keepends=False) -> list of lines\n\
+\n\
+Return a list of the lines in B, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+bytearray_splitlines(PyObject *self, PyObject *args)
+{
+ int keepends = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+ return NULL;
+
+ return stringlib_splitlines(
+ (PyObject*) self, PyByteArray_AS_STRING(self),
+ PyByteArray_GET_SIZE(self), keepends
+ );
+}
+
+PyDoc_STRVAR(fromhex_doc,
+"bytearray.fromhex(string) -> bytearray\n\
+\n\
+Create a bytearray object from a string of hexadecimal numbers.\n\
+Spaces between two numbers are accepted.\n\
+Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
+
+static int
+hex_digit_to_int(char c)
+{
+ if (Py_ISDIGIT(c))
+ return c - '0';
+ else {
+ if (Py_ISUPPER(c))
+ c = Py_TOLOWER(c);
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ }
+ return -1;
+}
+
+static PyObject *
+bytearray_fromhex(PyObject *cls, PyObject *args)
+{
+ PyObject *newbytes;
+ char *buf;
+ char *hex;
+ Py_ssize_t hexlen, byteslen, i, j;
+ int top, bot;
+
+ if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
+ return NULL;
+ byteslen = hexlen/2; /* This overestimates if there are spaces */
+ newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
+ if (!newbytes)
+ return NULL;
+ buf = PyByteArray_AS_STRING(newbytes);
+ for (i = j = 0; i < hexlen; i += 2) {
+ /* skip over spaces in the input */
+ while (hex[i] == ' ')
+ i++;
+ if (i >= hexlen)
+ break;
+ top = hex_digit_to_int(hex[i]);
+ bot = hex_digit_to_int(hex[i+1]);
+ if (top == -1 || bot == -1) {
+ PyErr_Format(PyExc_ValueError,
+ "non-hexadecimal number found in "
+ "fromhex() arg at position %zd", i);
+ goto error;
+ }
+ buf[j++] = (top << 4) + bot;
+ }
+ if (PyByteArray_Resize(newbytes, j) < 0)
+ goto error;
+ return newbytes;
+
+ error:
+ Py_DECREF(newbytes);
+ return NULL;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+bytearray_reduce(PyByteArrayObject *self)
+{
+ PyObject *latin1, *dict;
+ if (self->ob_bytes)
+#ifdef Py_USING_UNICODE
+ latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
+ Py_SIZE(self), NULL);
+#else
+ latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
+#endif
+ else
+#ifdef Py_USING_UNICODE
+ latin1 = PyUnicode_FromString("");
+#else
+ latin1 = PyString_FromString("");
+#endif
+
+ dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
+ if (dict == NULL) {
+ PyErr_Clear();
+ dict = Py_None;
+ Py_INCREF(dict);
+ }
+
+ return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
+}
+
+PyDoc_STRVAR(sizeof_doc,
+"B.__sizeof__() -> int\n\
+ \n\
+Returns the size of B in memory, in bytes");
+static PyObject *
+bytearray_sizeof(PyByteArrayObject *self)
+{
+ Py_ssize_t res;
+
+ res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
+ return PyInt_FromSsize_t(res);
+}
+
+static PySequenceMethods bytearray_as_sequence = {
+ (lenfunc)bytearray_length, /* sq_length */
+ (binaryfunc)PyByteArray_Concat, /* sq_concat */
+ (ssizeargfunc)bytearray_repeat, /* sq_repeat */
+ (ssizeargfunc)bytearray_getitem, /* sq_item */
+ 0, /* sq_slice */
+ (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)bytearray_contains, /* sq_contains */
+ (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
+ (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
+};
+
+static PyMappingMethods bytearray_as_mapping = {
+ (lenfunc)bytearray_length,
+ (binaryfunc)bytearray_subscript,
+ (objobjargproc)bytearray_ass_subscript,
+};
+
+static PyBufferProcs bytearray_as_buffer = {
+ (readbufferproc)bytearray_buffer_getreadbuf,
+ (writebufferproc)bytearray_buffer_getwritebuf,
+ (segcountproc)bytearray_buffer_getsegcount,
+ (charbufferproc)bytearray_buffer_getcharbuf,
+ (getbufferproc)bytearray_getbuffer,
+ (releasebufferproc)bytearray_releasebuffer,
+};
+
+static PyMethodDef
+bytearray_methods[] = {
+ {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
+ {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
+ {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
+ {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
+ {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
+ _Py_capitalize__doc__},
+ {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
+ {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
+ {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
+ {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
+ {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
+ expandtabs__doc__},
+ {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
+ {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
+ {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
+ fromhex_doc},
+ {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
+ {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
+ {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
+ _Py_isalnum__doc__},
+ {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
+ _Py_isalpha__doc__},
+ {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
+ _Py_isdigit__doc__},
+ {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
+ _Py_islower__doc__},
+ {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
+ _Py_isspace__doc__},
+ {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
+ _Py_istitle__doc__},
+ {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
+ _Py_isupper__doc__},
+ {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
+ {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
+ {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
+ {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
+ {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
+ {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
+ {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
+ {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
+ {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
+ {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
+ {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
+ {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
+ {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
+ {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
+ {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
+ {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
+ {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
+ splitlines__doc__},
+ {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
+ startswith__doc__},
+ {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
+ {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
+ _Py_swapcase__doc__},
+ {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
+ {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
+ translate__doc__},
+ {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
+ {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
+ {NULL}
+};
+
+PyDoc_STRVAR(bytearray_doc,
+"bytearray(iterable_of_ints) -> bytearray.\n\
+bytearray(string, encoding[, errors]) -> bytearray.\n\
+bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
+bytearray(memory_view) -> bytearray.\n\
+\n\
+Construct an mutable bytearray object from:\n\
+ - an iterable yielding integers in range(256)\n\
+ - a text string encoded using the specified encoding\n\
+ - a bytes or a bytearray object\n\
+ - any object implementing the buffer API.\n\
+\n\
+bytearray(int) -> bytearray.\n\
+\n\
+Construct a zero-initialized bytearray of the given length.");
+
+
+static PyObject *bytearray_iter(PyObject *seq);
+
+PyTypeObject PyByteArray_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "bytearray",
+ sizeof(PyByteArrayObject),
+ 0,
+ (destructor)bytearray_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)bytearray_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &bytearray_as_sequence, /* tp_as_sequence */
+ &bytearray_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ bytearray_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &bytearray_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+ bytearray_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ bytearray_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ bytearray_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)bytearray_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+/*********************** Bytes Iterator ****************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t it_index;
+ PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
+} bytesiterobject;
+
+static void
+bytearrayiter_dealloc(bytesiterobject *it)
+{
+ _PyObject_GC_UNTRACK(it);
+ Py_XDECREF(it->it_seq);
+ PyObject_GC_Del(it);
+}
+
+static int
+bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_seq);
+ return 0;
+}
+
+static PyObject *
+bytearrayiter_next(bytesiterobject *it)
+{
+ PyByteArrayObject *seq;
+ PyObject *item;
+
+ assert(it != NULL);
+ seq = it->it_seq;
+ if (seq == NULL)
+ return NULL;
+ assert(PyByteArray_Check(seq));
+
+ if (it->it_index < PyByteArray_GET_SIZE(seq)) {
+ item = PyInt_FromLong(
+ (unsigned char)seq->ob_bytes[it->it_index]);
+ if (item != NULL)
+ ++it->it_index;
+ return item;
+ }
+
+ Py_DECREF(seq);
+ it->it_seq = NULL;
+ return NULL;
+}
+
+static PyObject *
+bytesarrayiter_length_hint(bytesiterobject *it)
+{
+ Py_ssize_t len = 0;
+ if (it->it_seq)
+ len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
+ return PyInt_FromSsize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc,
+ "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef bytearrayiter_methods[] = {
+ {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
+ length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyByteArrayIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "bytearray_iterator", /* tp_name */
+ sizeof(bytesiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)bytearrayiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)bytearrayiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)bytearrayiter_next, /* tp_iternext */
+ bytearrayiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+bytearray_iter(PyObject *seq)
+{
+ bytesiterobject *it;
+
+ if (!PyByteArray_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
+ if (it == NULL)
+ return NULL;
+ it->it_index = 0;
+ Py_INCREF(seq);
+ it->it_seq = (PyByteArrayObject *)seq;
+ _PyObject_GC_TRACK(it);
+ return (PyObject *)it;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/bytes_methods.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/bytes_methods.c
new file mode 100644
index 0000000000..28f78cb76e
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/bytes_methods.c
@@ -0,0 +1,398 @@
+#include "Python.h"
+#include "bytes_methods.h"
+
+PyDoc_STRVAR_shared(_Py_isspace__doc__,
+"B.isspace() -> bool\n\
+\n\
+Return True if all characters in B are whitespace\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isspace(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (len == 1 && Py_ISSPACE(*p))
+ Py_RETURN_TRUE;
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ for (; p < e; p++) {
+ if (!Py_ISSPACE(*p))
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isalpha__doc__,
+"B.isalpha() -> bool\n\
+\n\
+Return True if all characters in B are alphabetic\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (len == 1 && Py_ISALPHA(*p))
+ Py_RETURN_TRUE;
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ for (; p < e; p++) {
+ if (!Py_ISALPHA(*p))
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isalnum__doc__,
+"B.isalnum() -> bool\n\
+\n\
+Return True if all characters in B are alphanumeric\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (len == 1 && Py_ISALNUM(*p))
+ Py_RETURN_TRUE;
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ for (; p < e; p++) {
+ if (!Py_ISALNUM(*p))
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_isdigit__doc__,
+"B.isdigit() -> bool\n\
+\n\
+Return True if all characters in B are digits\n\
+and there is at least one character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (len == 1 && Py_ISDIGIT(*p))
+ Py_RETURN_TRUE;
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ for (; p < e; p++) {
+ if (!Py_ISDIGIT(*p))
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+}
+
+
+PyDoc_STRVAR_shared(_Py_islower__doc__,
+"B.islower() -> bool\n\
+\n\
+Return True if all cased characters in B are lowercase and there is\n\
+at least one cased character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_islower(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (len == 1)
+ return PyBool_FromLong(Py_ISLOWER(*p));
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ cased = 0;
+ for (; p < e; p++) {
+ if (Py_ISUPPER(*p))
+ Py_RETURN_FALSE;
+ else if (!cased && Py_ISLOWER(*p))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_isupper__doc__,
+"B.isupper() -> bool\n\
+\n\
+Return True if all cased characters in B are uppercase and there is\n\
+at least one cased character in B, False otherwise.");
+
+PyObject*
+_Py_bytes_isupper(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (len == 1)
+ return PyBool_FromLong(Py_ISUPPER(*p));
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ cased = 0;
+ for (; p < e; p++) {
+ if (Py_ISLOWER(*p))
+ Py_RETURN_FALSE;
+ else if (!cased && Py_ISUPPER(*p))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_istitle__doc__,
+"B.istitle() -> bool\n\
+\n\
+Return True if B is a titlecased string and there is at least one\n\
+character in B, i.e. uppercase characters may only follow uncased\n\
+characters and lowercase characters only cased ones. Return False\n\
+otherwise.");
+
+PyObject*
+_Py_bytes_istitle(const char *cptr, Py_ssize_t len)
+{
+ register const unsigned char *p
+ = (unsigned char *) cptr;
+ register const unsigned char *e;
+ int cased, previous_is_cased;
+
+ /* Shortcut for single character strings */
+ if (len == 1)
+ return PyBool_FromLong(Py_ISUPPER(*p));
+
+ /* Special case for empty strings */
+ if (len == 0)
+ Py_RETURN_FALSE;
+
+ e = p + len;
+ cased = 0;
+ previous_is_cased = 0;
+ for (; p < e; p++) {
+ register const unsigned char ch = *p;
+
+ if (Py_ISUPPER(ch)) {
+ if (previous_is_cased)
+ Py_RETURN_FALSE;
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else if (Py_ISLOWER(ch)) {
+ if (!previous_is_cased)
+ Py_RETURN_FALSE;
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else
+ previous_is_cased = 0;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR_shared(_Py_lower__doc__,
+"B.lower() -> copy of B\n\
+\n\
+Return a copy of B with all ASCII characters converted to lowercase.");
+
+void
+_Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
+{
+ Py_ssize_t i;
+
+ /*
+ newobj = PyString_FromStringAndSize(NULL, len);
+ if (!newobj)
+ return NULL;
+
+ s = PyString_AS_STRING(newobj);
+ */
+
+ Py_MEMCPY(result, cptr, len);
+
+ for (i = 0; i < len; i++) {
+ int c = Py_CHARMASK(result[i]);
+ if (Py_ISUPPER(c))
+ result[i] = Py_TOLOWER(c);
+ }
+}
+
+
+PyDoc_STRVAR_shared(_Py_upper__doc__,
+"B.upper() -> copy of B\n\
+\n\
+Return a copy of B with all ASCII characters converted to uppercase.");
+
+void
+_Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
+{
+ Py_ssize_t i;
+
+ /*
+ newobj = PyString_FromStringAndSize(NULL, len);
+ if (!newobj)
+ return NULL;
+
+ s = PyString_AS_STRING(newobj);
+ */
+
+ Py_MEMCPY(result, cptr, len);
+
+ for (i = 0; i < len; i++) {
+ int c = Py_CHARMASK(result[i]);
+ if (Py_ISLOWER(c))
+ result[i] = Py_TOUPPER(c);
+ }
+}
+
+
+PyDoc_STRVAR_shared(_Py_title__doc__,
+"B.title() -> copy of B\n\
+\n\
+Return a titlecased version of B, i.e. ASCII words start with uppercase\n\
+characters, all remaining cased characters have lowercase.");
+
+void
+_Py_bytes_title(char *result, char *s, Py_ssize_t len)
+{
+ Py_ssize_t i;
+ int previous_is_cased = 0;
+
+ /*
+ newobj = PyString_FromStringAndSize(NULL, len);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ */
+ for (i = 0; i < len; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (Py_ISLOWER(c)) {
+ if (!previous_is_cased)
+ c = Py_TOUPPER(c);
+ previous_is_cased = 1;
+ } else if (Py_ISUPPER(c)) {
+ if (previous_is_cased)
+ c = Py_TOLOWER(c);
+ previous_is_cased = 1;
+ } else
+ previous_is_cased = 0;
+ *result++ = c;
+ }
+}
+
+
+PyDoc_STRVAR_shared(_Py_capitalize__doc__,
+"B.capitalize() -> copy of B\n\
+\n\
+Return a copy of B with only its first character capitalized (ASCII)\n\
+and the rest lower-cased.");
+
+void
+_Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
+{
+ Py_ssize_t i;
+
+ /*
+ newobj = PyString_FromStringAndSize(NULL, len);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ */
+ if (0 < len) {
+ int c = Py_CHARMASK(*s++);
+ if (Py_ISLOWER(c))
+ *result = Py_TOUPPER(c);
+ else
+ *result = c;
+ result++;
+ }
+ for (i = 1; i < len; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (Py_ISUPPER(c))
+ *result = Py_TOLOWER(c);
+ else
+ *result = c;
+ result++;
+ }
+}
+
+
+PyDoc_STRVAR_shared(_Py_swapcase__doc__,
+"B.swapcase() -> copy of B\n\
+\n\
+Return a copy of B with uppercase ASCII characters converted\n\
+to lowercase ASCII and vice versa.");
+
+void
+_Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
+{
+ Py_ssize_t i;
+
+ /*
+ newobj = PyString_FromStringAndSize(NULL, len);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ */
+ for (i = 0; i < len; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (Py_ISLOWER(c)) {
+ *result = Py_TOUPPER(c);
+ }
+ else if (Py_ISUPPER(c)) {
+ *result = Py_TOLOWER(c);
+ }
+ else
+ *result = c;
+ result++;
+ }
+}
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/capsule.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/capsule.c
new file mode 100644
index 0000000000..f7f2e047a7
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/capsule.c
@@ -0,0 +1,324 @@
+/* Wrap void * pointers to be passed between C modules */
+
+#include "Python.h"
+
+/* Internal structure of PyCapsule */
+typedef struct {
+ PyObject_HEAD
+ void *pointer;
+ const char *name;
+ void *context;
+ PyCapsule_Destructor destructor;
+} PyCapsule;
+
+
+
+static int
+_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
+{
+ if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
+ PyErr_SetString(PyExc_ValueError, invalid_capsule);
+ return 0;
+ }
+ return 1;
+}
+
+#define is_legal_capsule(capsule, name) \
+ (_is_legal_capsule(capsule, \
+ name " called with invalid PyCapsule object"))
+
+
+static int
+name_matches(const char *name1, const char *name2) {
+ /* if either is NULL, */
+ if (!name1 || !name2) {
+ /* they're only the same if they're both NULL. */
+ return name1 == name2;
+ }
+ return !strcmp(name1, name2);
+}
+
+
+
+PyObject *
+PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
+{
+ PyCapsule *capsule;
+
+ if (!pointer) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
+ return NULL;
+ }
+
+ capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
+ if (capsule == NULL) {
+ return NULL;
+ }
+
+ capsule->pointer = pointer;
+ capsule->name = name;
+ capsule->context = NULL;
+ capsule->destructor = destructor;
+
+ return (PyObject *)capsule;
+}
+
+
+int
+PyCapsule_IsValid(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ return (capsule != NULL &&
+ PyCapsule_CheckExact(capsule) &&
+ capsule->pointer != NULL &&
+ name_matches(capsule->name, name));
+}
+
+
+void *
+PyCapsule_GetPointer(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
+ return NULL;
+ }
+
+ if (!name_matches(name, capsule->name)) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
+ return NULL;
+ }
+
+ return capsule->pointer;
+}
+
+
+const char *
+PyCapsule_GetName(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
+ return NULL;
+ }
+ return capsule->name;
+}
+
+
+PyCapsule_Destructor
+PyCapsule_GetDestructor(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
+ return NULL;
+ }
+ return capsule->destructor;
+}
+
+
+void *
+PyCapsule_GetContext(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
+ return NULL;
+ }
+ return capsule->context;
+}
+
+
+int
+PyCapsule_SetPointer(PyObject *o, void *pointer)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!pointer) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
+ return -1;
+ }
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
+ return -1;
+ }
+
+ capsule->pointer = pointer;
+ return 0;
+}
+
+
+int
+PyCapsule_SetName(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
+ return -1;
+ }
+
+ capsule->name = name;
+ return 0;
+}
+
+
+int
+PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
+ return -1;
+ }
+
+ capsule->destructor = destructor;
+ return 0;
+}
+
+
+int
+PyCapsule_SetContext(PyObject *o, void *context)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
+ return -1;
+ }
+
+ capsule->context = context;
+ return 0;
+}
+
+
+void *
+PyCapsule_Import(const char *name, int no_block)
+{
+ PyObject *object = NULL;
+ void *return_value = NULL;
+ char *trace;
+ size_t name_length = (strlen(name) + 1) * sizeof(char);
+ char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+ if (!name_dup) {
+ return NULL;
+ }
+
+ memcpy(name_dup, name, name_length);
+
+ trace = name_dup;
+ while (trace) {
+ char *dot = strchr(trace, '.');
+ if (dot) {
+ *dot++ = '\0';
+ }
+
+ if (object == NULL) {
+ if (no_block) {
+ object = PyImport_ImportModuleNoBlock(trace);
+ } else {
+ object = PyImport_ImportModule(trace);
+ if (!object) {
+ PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
+ }
+ }
+ } else {
+ PyObject *object2 = PyObject_GetAttrString(object, trace);
+ Py_DECREF(object);
+ object = object2;
+ }
+ if (!object) {
+ goto EXIT;
+ }
+
+ trace = dot;
+ }
+
+ /* compare attribute name to module.name by hand */
+ if (PyCapsule_IsValid(object, name)) {
+ PyCapsule *capsule = (PyCapsule *)object;
+ return_value = capsule->pointer;
+ } else {
+ PyErr_Format(PyExc_AttributeError,
+ "PyCapsule_Import \"%s\" is not valid",
+ name);
+ }
+
+EXIT:
+ Py_XDECREF(object);
+ if (name_dup) {
+ PyMem_FREE(name_dup);
+ }
+ return return_value;
+}
+
+
+static void
+capsule_dealloc(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+ if (capsule->destructor) {
+ capsule->destructor(o);
+ }
+ PyObject_DEL(o);
+}
+
+
+static PyObject *
+capsule_repr(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+ const char *name;
+ const char *quote;
+
+ if (capsule->name) {
+ quote = "\"";
+ name = capsule->name;
+ } else {
+ quote = "";
+ name = "NULL";
+ }
+
+ return PyString_FromFormat("<capsule object %s%s%s at %p>",
+ quote, name, quote, capsule);
+}
+
+
+
+PyDoc_STRVAR(PyCapsule_Type__doc__,
+"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
+object. They're a way of passing data through the Python interpreter\n\
+without creating your own custom type.\n\
+\n\
+Capsules are used for communication between extension modules.\n\
+They provide a way for an extension module to export a C interface\n\
+to other extension modules, so that extension modules can use the\n\
+Python import mechanism to link to one another.\n\
+");
+
+PyTypeObject PyCapsule_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "PyCapsule", /*tp_name*/
+ sizeof(PyCapsule), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ capsule_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ capsule_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ 0, /*tp_flags*/
+ PyCapsule_Type__doc__ /*tp_doc*/
+};
+
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/cellobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/cellobject.c
new file mode 100644
index 0000000000..463f7b1984
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/cellobject.c
@@ -0,0 +1,145 @@
+/* Cell object implementation */
+
+#include "Python.h"
+
+PyObject *
+PyCell_New(PyObject *obj)
+{
+ PyCellObject *op;
+
+ op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type);
+ if (op == NULL)
+ return NULL;
+ op->ob_ref = obj;
+ Py_XINCREF(obj);
+
+ _PyObject_GC_TRACK(op);
+ return (PyObject *)op;
+}
+
+PyObject *
+PyCell_Get(PyObject *op)
+{
+ if (!PyCell_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ Py_XINCREF(((PyCellObject*)op)->ob_ref);
+ return PyCell_GET(op);
+}
+
+int
+PyCell_Set(PyObject *op, PyObject *obj)
+{
+ PyObject* oldobj;
+ if (!PyCell_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ oldobj = PyCell_GET(op);
+ Py_XINCREF(obj);
+ PyCell_SET(op, obj);
+ Py_XDECREF(oldobj);
+ return 0;
+}
+
+static void
+cell_dealloc(PyCellObject *op)
+{
+ _PyObject_GC_UNTRACK(op);
+ Py_XDECREF(op->ob_ref);
+ PyObject_GC_Del(op);
+}
+
+static int
+cell_compare(PyCellObject *a, PyCellObject *b)
+{
+ /* Py3K warning for comparisons */
+ if (PyErr_WarnPy3k("cell comparisons not supported in 3.x",
+ 1) < 0) {
+ return -2;
+ }
+
+ if (a->ob_ref == NULL) {
+ if (b->ob_ref == NULL)
+ return 0;
+ return -1;
+ } else if (b->ob_ref == NULL)
+ return 1;
+ return PyObject_Compare(a->ob_ref, b->ob_ref);
+}
+
+static PyObject *
+cell_repr(PyCellObject *op)
+{
+ if (op->ob_ref == NULL)
+ return PyString_FromFormat("<cell at %p: empty>", op);
+
+ return PyString_FromFormat("<cell at %p: %.80s object at %p>",
+ op, op->ob_ref->ob_type->tp_name,
+ op->ob_ref);
+}
+
+static int
+cell_traverse(PyCellObject *op, visitproc visit, void *arg)
+{
+ Py_VISIT(op->ob_ref);
+ return 0;
+}
+
+static int
+cell_clear(PyCellObject *op)
+{
+ Py_CLEAR(op->ob_ref);
+ return 0;
+}
+
+static PyObject *
+cell_get_contents(PyCellObject *op, void *closure)
+{
+ if (op->ob_ref == NULL)
+ {
+ PyErr_SetString(PyExc_ValueError, "Cell is empty");
+ return NULL;
+ }
+ Py_INCREF(op->ob_ref);
+ return op->ob_ref;
+}
+
+static PyGetSetDef cell_getsetlist[] = {
+ {"cell_contents", (getter)cell_get_contents, NULL},
+ {NULL} /* sentinel */
+};
+
+PyTypeObject PyCell_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "cell",
+ sizeof(PyCellObject),
+ 0,
+ (destructor)cell_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)cell_compare, /* tp_compare */
+ (reprfunc)cell_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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)cell_traverse, /* tp_traverse */
+ (inquiry)cell_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ cell_getsetlist, /* tp_getset */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/classobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/classobject.c
new file mode 100644
index 0000000000..aa68db4c7c
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/classobject.c
@@ -0,0 +1,2696 @@
+
+/* Class object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Free list for method objects to save malloc/free overhead
+ * The im_self element is used to chain the elements.
+ */
+static PyMethodObject *free_list;
+static int numfree = 0;
+#ifndef PyMethod_MAXFREELIST
+#define PyMethod_MAXFREELIST 256
+#endif
+
+#define TP_DESCR_GET(t) \
+ (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
+
+/* Forward */
+static PyObject *class_lookup(PyClassObject *, PyObject *,
+ PyClassObject **);
+static PyObject *instance_getattr1(PyInstanceObject *, PyObject *);
+static PyObject *instance_getattr2(PyInstanceObject *, PyObject *);
+
+static PyObject *getattrstr, *setattrstr, *delattrstr;
+
+
+PyObject *
+PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
+ /* bases is NULL or tuple of classobjects! */
+{
+ PyClassObject *op, *dummy;
+ static PyObject *docstr, *modstr, *namestr;
+ if (docstr == NULL) {
+ docstr= PyString_InternFromString("__doc__");
+ if (docstr == NULL)
+ return NULL;
+ }
+ if (modstr == NULL) {
+ modstr= PyString_InternFromString("__module__");
+ if (modstr == NULL)
+ return NULL;
+ }
+ if (namestr == NULL) {
+ namestr= PyString_InternFromString("__name__");
+ if (namestr == NULL)
+ return NULL;
+ }
+ if (name == NULL || !PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyClass_New: name must be a string");
+ return NULL;
+ }
+ if (dict == NULL || !PyDict_Check(dict)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyClass_New: dict must be a dictionary");
+ return NULL;
+ }
+ if (PyDict_GetItem(dict, docstr) == NULL) {
+ if (PyDict_SetItem(dict, docstr, Py_None) < 0)
+ return NULL;
+ }
+ if (PyDict_GetItem(dict, modstr) == NULL) {
+ PyObject *globals = PyEval_GetGlobals();
+ if (globals != NULL) {
+ PyObject *modname = PyDict_GetItem(globals, namestr);
+ if (modname != NULL) {
+ if (PyDict_SetItem(dict, modstr, modname) < 0)
+ return NULL;
+ }
+ }
+ }
+ if (bases == NULL) {
+ bases = PyTuple_New(0);
+ if (bases == NULL)
+ return NULL;
+ }
+ else {
+ Py_ssize_t i, n;
+ PyObject *base;
+ if (!PyTuple_Check(bases)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyClass_New: bases must be a tuple");
+ return NULL;
+ }
+ n = PyTuple_Size(bases);
+ for (i = 0; i < n; i++) {
+ base = PyTuple_GET_ITEM(bases, i);
+ if (!PyClass_Check(base)) {
+ if (PyCallable_Check(
+ (PyObject *) base->ob_type))
+ return PyObject_CallFunctionObjArgs(
+ (PyObject *) base->ob_type,
+ name, bases, dict, NULL);
+ PyErr_SetString(PyExc_TypeError,
+ "PyClass_New: base must be a class");
+ return NULL;
+ }
+ }
+ Py_INCREF(bases);
+ }
+
+ if (getattrstr == NULL) {
+ getattrstr = PyString_InternFromString("__getattr__");
+ if (getattrstr == NULL)
+ goto alloc_error;
+ setattrstr = PyString_InternFromString("__setattr__");
+ if (setattrstr == NULL)
+ goto alloc_error;
+ delattrstr = PyString_InternFromString("__delattr__");
+ if (delattrstr == NULL)
+ goto alloc_error;
+ }
+
+ op = PyObject_GC_New(PyClassObject, &PyClass_Type);
+ if (op == NULL) {
+alloc_error:
+ Py_DECREF(bases);
+ return NULL;
+ }
+ op->cl_bases = bases;
+ Py_INCREF(dict);
+ op->cl_dict = dict;
+ Py_XINCREF(name);
+ op->cl_name = name;
+ op->cl_weakreflist = NULL;
+
+ op->cl_getattr = class_lookup(op, getattrstr, &dummy);
+ op->cl_setattr = class_lookup(op, setattrstr, &dummy);
+ op->cl_delattr = class_lookup(op, delattrstr, &dummy);
+ Py_XINCREF(op->cl_getattr);
+ Py_XINCREF(op->cl_setattr);
+ Py_XINCREF(op->cl_delattr);
+ _PyObject_GC_TRACK(op);
+ return (PyObject *) op;
+}
+
+PyObject *
+PyMethod_Function(PyObject *im)
+{
+ if (!PyMethod_Check(im)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyMethodObject *)im)->im_func;
+}
+
+PyObject *
+PyMethod_Self(PyObject *im)
+{
+ if (!PyMethod_Check(im)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyMethodObject *)im)->im_self;
+}
+
+PyObject *
+PyMethod_Class(PyObject *im)
+{
+ if (!PyMethod_Check(im)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyMethodObject *)im)->im_class;
+}
+
+PyDoc_STRVAR(class_doc,
+"classobj(name, bases, dict)\n\
+\n\
+Create a class object. The name must be a string; the second argument\n\
+a tuple of classes, and the third a dictionary.");
+
+static PyObject *
+class_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *name, *bases, *dict;
+ static char *kwlist[] = {"name", "bases", "dict", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SOO", kwlist,
+ &name, &bases, &dict))
+ return NULL;
+ return PyClass_New(bases, dict, name);
+}
+
+/* Class methods */
+
+static void
+class_dealloc(PyClassObject *op)
+{
+ _PyObject_GC_UNTRACK(op);
+ if (op->cl_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) op);
+ Py_DECREF(op->cl_bases);
+ Py_DECREF(op->cl_dict);
+ Py_XDECREF(op->cl_name);
+ Py_XDECREF(op->cl_getattr);
+ Py_XDECREF(op->cl_setattr);
+ Py_XDECREF(op->cl_delattr);
+ PyObject_GC_Del(op);
+}
+
+static PyObject *
+class_lookup(PyClassObject *cp, PyObject *name, PyClassObject **pclass)
+{
+ Py_ssize_t i, n;
+ PyObject *value = PyDict_GetItem(cp->cl_dict, name);
+ if (value != NULL) {
+ *pclass = cp;
+ return value;
+ }
+ n = PyTuple_Size(cp->cl_bases);
+ for (i = 0; i < n; i++) {
+ /* XXX What if one of the bases is not a class? */
+ PyObject *v = class_lookup(
+ (PyClassObject *)
+ PyTuple_GetItem(cp->cl_bases, i), name, pclass);
+ if (v != NULL)
+ return v;
+ }
+ return NULL;
+}
+
+static PyObject *
+class_getattr(register PyClassObject *op, PyObject *name)
+{
+ register PyObject *v;
+ register char *sname;
+ PyClassObject *klass;
+ descrgetfunc f;
+
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+ return NULL;
+ }
+
+ sname = PyString_AsString(name);
+ if (sname[0] == '_' && sname[1] == '_') {
+ if (strcmp(sname, "__dict__") == 0) {
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "class.__dict__ not accessible in restricted mode");
+ return NULL;
+ }
+ Py_INCREF(op->cl_dict);
+ return op->cl_dict;
+ }
+ if (strcmp(sname, "__bases__") == 0) {
+ Py_INCREF(op->cl_bases);
+ return op->cl_bases;
+ }
+ if (strcmp(sname, "__name__") == 0) {
+ if (op->cl_name == NULL)
+ v = Py_None;
+ else
+ v = op->cl_name;
+ Py_INCREF(v);
+ return v;
+ }
+ }
+ v = class_lookup(op, name, &klass);
+ if (v == NULL) {
+ PyErr_Format(PyExc_AttributeError,
+ "class %.50s has no attribute '%.400s'",
+ PyString_AS_STRING(op->cl_name), sname);
+ return NULL;
+ }
+ f = TP_DESCR_GET(v->ob_type);
+ if (f == NULL)
+ Py_INCREF(v);
+ else
+ v = f(v, (PyObject *)NULL, (PyObject *)op);
+ return v;
+}
+
+static void
+set_slot(PyObject **slot, PyObject *v)
+{
+ PyObject *temp = *slot;
+ Py_XINCREF(v);
+ *slot = v;
+ Py_XDECREF(temp);
+}
+
+static void
+set_attr_slots(PyClassObject *c)
+{
+ PyClassObject *dummy;
+
+ set_slot(&c->cl_getattr, class_lookup(c, getattrstr, &dummy));
+ set_slot(&c->cl_setattr, class_lookup(c, setattrstr, &dummy));
+ set_slot(&c->cl_delattr, class_lookup(c, delattrstr, &dummy));
+}
+
+static char *
+set_dict(PyClassObject *c, PyObject *v)
+{
+ if (v == NULL || !PyDict_Check(v))
+ return "__dict__ must be a dictionary object";
+ set_slot(&c->cl_dict, v);
+ set_attr_slots(c);
+ return "";
+}
+
+static char *
+set_bases(PyClassObject *c, PyObject *v)
+{
+ Py_ssize_t i, n;
+
+ if (v == NULL || !PyTuple_Check(v))
+ return "__bases__ must be a tuple object";
+ n = PyTuple_Size(v);
+ for (i = 0; i < n; i++) {
+ PyObject *x = PyTuple_GET_ITEM(v, i);
+ if (!PyClass_Check(x))
+ return "__bases__ items must be classes";
+ if (PyClass_IsSubclass(x, (PyObject *)c))
+ return "a __bases__ item causes an inheritance cycle";
+ }
+ set_slot(&c->cl_bases, v);
+ set_attr_slots(c);
+ return "";
+}
+
+static char *
+set_name(PyClassObject *c, PyObject *v)
+{
+ if (v == NULL || !PyString_Check(v))
+ return "__name__ must be a string object";
+ if (strlen(PyString_AS_STRING(v)) != (size_t)PyString_GET_SIZE(v))
+ return "__name__ must not contain null bytes";
+ set_slot(&c->cl_name, v);
+ return "";
+}
+
+static int
+class_setattr(PyClassObject *op, PyObject *name, PyObject *v)
+{
+ char *sname;
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "classes are read-only in restricted mode");
+ return -1;
+ }
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+ return -1;
+ }
+ sname = PyString_AsString(name);
+ if (sname[0] == '_' && sname[1] == '_') {
+ Py_ssize_t n = PyString_Size(name);
+ if (sname[n-1] == '_' && sname[n-2] == '_') {
+ char *err = NULL;
+ if (strcmp(sname, "__dict__") == 0)
+ err = set_dict(op, v);
+ else if (strcmp(sname, "__bases__") == 0)
+ err = set_bases(op, v);
+ else if (strcmp(sname, "__name__") == 0)
+ err = set_name(op, v);
+ else if (strcmp(sname, "__getattr__") == 0)
+ set_slot(&op->cl_getattr, v);
+ else if (strcmp(sname, "__setattr__") == 0)
+ set_slot(&op->cl_setattr, v);
+ else if (strcmp(sname, "__delattr__") == 0)
+ set_slot(&op->cl_delattr, v);
+ /* For the last three, we fall through to update the
+ dictionary as well. */
+ if (err != NULL) {
+ if (*err == '\0')
+ return 0;
+ PyErr_SetString(PyExc_TypeError, err);
+ return -1;
+ }
+ }
+ }
+ if (v == NULL) {
+ int rv = PyDict_DelItem(op->cl_dict, name);
+ if (rv < 0)
+ PyErr_Format(PyExc_AttributeError,
+ "class %.50s has no attribute '%.400s'",
+ PyString_AS_STRING(op->cl_name), sname);
+ return rv;
+ }
+ else
+ return PyDict_SetItem(op->cl_dict, name, v);
+}
+
+static PyObject *
+class_repr(PyClassObject *op)
+{
+ PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+ char *name;
+ if (op->cl_name == NULL || !PyString_Check(op->cl_name))
+ name = "?";
+ else
+ name = PyString_AsString(op->cl_name);
+ if (mod == NULL || !PyString_Check(mod))
+ return PyString_FromFormat("<class ?.%s at %p>", name, op);
+ else
+ return PyString_FromFormat("<class %s.%s at %p>",
+ PyString_AsString(mod),
+ name, op);
+}
+
+static PyObject *
+class_str(PyClassObject *op)
+{
+ PyObject *mod = PyDict_GetItemString(op->cl_dict, "__module__");
+ PyObject *name = op->cl_name;
+ PyObject *res;
+ Py_ssize_t m, n;
+
+ if (name == NULL || !PyString_Check(name))
+ return class_repr(op);
+ if (mod == NULL || !PyString_Check(mod)) {
+ Py_INCREF(name);
+ return name;
+ }
+ m = PyString_GET_SIZE(mod);
+ n = PyString_GET_SIZE(name);
+ res = PyString_FromStringAndSize((char *)NULL, m+1+n);
+ if (res != NULL) {
+ char *s = PyString_AS_STRING(res);
+ memcpy(s, PyString_AS_STRING(mod), m);
+ s += m;
+ *s++ = '.';
+ memcpy(s, PyString_AS_STRING(name), n);
+ }
+ return res;
+}
+
+static int
+class_traverse(PyClassObject *o, visitproc visit, void *arg)
+{
+ Py_VISIT(o->cl_bases);
+ Py_VISIT(o->cl_dict);
+ Py_VISIT(o->cl_name);
+ Py_VISIT(o->cl_getattr);
+ Py_VISIT(o->cl_setattr);
+ Py_VISIT(o->cl_delattr);
+ return 0;
+}
+
+PyTypeObject PyClass_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "classobj",
+ sizeof(PyClassObject),
+ 0,
+ (destructor)class_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)class_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ PyInstance_New, /* tp_call */
+ (reprfunc)class_str, /* tp_str */
+ (getattrofunc)class_getattr, /* tp_getattro */
+ (setattrofunc)class_setattr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ class_doc, /* tp_doc */
+ (traverseproc)class_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* 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 */
+ class_new, /* tp_new */
+};
+
+int
+PyClass_IsSubclass(PyObject *klass, PyObject *base)
+{
+ Py_ssize_t i, n;
+ PyClassObject *cp;
+ if (klass == base)
+ return 1;
+ if (PyTuple_Check(base)) {
+ n = PyTuple_GET_SIZE(base);
+ for (i = 0; i < n; i++) {
+ if (PyClass_IsSubclass(klass, PyTuple_GET_ITEM(base, i)))
+ return 1;
+ }
+ return 0;
+ }
+ if (klass == NULL || !PyClass_Check(klass))
+ return 0;
+ cp = (PyClassObject *)klass;
+ n = PyTuple_Size(cp->cl_bases);
+ for (i = 0; i < n; i++) {
+ if (PyClass_IsSubclass(PyTuple_GetItem(cp->cl_bases, i), base))
+ return 1;
+ }
+ return 0;
+}
+
+
+/* Instance objects */
+
+PyObject *
+PyInstance_NewRaw(PyObject *klass, PyObject *dict)
+{
+ PyInstanceObject *inst;
+
+ if (!PyClass_Check(klass)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (dict == NULL) {
+ dict = PyDict_New();
+ if (dict == NULL)
+ return NULL;
+ }
+ else {
+ if (!PyDict_Check(dict)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ Py_INCREF(dict);
+ }
+ inst = PyObject_GC_New(PyInstanceObject, &PyInstance_Type);
+ if (inst == NULL) {
+ Py_DECREF(dict);
+ return NULL;
+ }
+ inst->in_weakreflist = NULL;
+ Py_INCREF(klass);
+ inst->in_class = (PyClassObject *)klass;
+ inst->in_dict = dict;
+ _PyObject_GC_TRACK(inst);
+ return (PyObject *)inst;
+}
+
+PyObject *
+PyInstance_New(PyObject *klass, PyObject *arg, PyObject *kw)
+{
+ register PyInstanceObject *inst;
+ PyObject *init;
+ static PyObject *initstr;
+
+ if (initstr == NULL) {
+ initstr = PyString_InternFromString("__init__");
+ if (initstr == NULL)
+ return NULL;
+ }
+ inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL);
+ if (inst == NULL)
+ return NULL;
+ init = instance_getattr2(inst, initstr);
+ if (init == NULL) {
+ if (PyErr_Occurred()) {
+ Py_DECREF(inst);
+ return NULL;
+ }
+ if ((arg != NULL && (!PyTuple_Check(arg) ||
+ PyTuple_Size(arg) != 0))
+ || (kw != NULL && (!PyDict_Check(kw) ||
+ PyDict_Size(kw) != 0))) {
+ PyErr_SetString(PyExc_TypeError,
+ "this constructor takes no arguments");
+ Py_DECREF(inst);
+ inst = NULL;
+ }
+ }
+ else {
+ PyObject *res = PyEval_CallObjectWithKeywords(init, arg, kw);
+ Py_DECREF(init);
+ if (res == NULL) {
+ Py_DECREF(inst);
+ inst = NULL;
+ }
+ else {
+ if (res != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "__init__() should return None");
+ Py_DECREF(inst);
+ inst = NULL;
+ }
+ Py_DECREF(res);
+ }
+ }
+ return (PyObject *)inst;
+}
+
+/* Instance methods */
+
+PyDoc_STRVAR(instance_doc,
+"instance(class[, dict])\n\
+\n\
+Create an instance without calling its __init__() method.\n\
+The class must be a classic class.\n\
+If present, dict must be a dictionary or None.");
+
+static PyObject *
+instance_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+ PyObject *klass;
+ PyObject *dict = Py_None;
+
+ if (!PyArg_ParseTuple(args, "O!|O:instance",
+ &PyClass_Type, &klass, &dict))
+ return NULL;
+
+ if (dict == Py_None)
+ dict = NULL;
+ else if (!PyDict_Check(dict)) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance() second arg must be dictionary or None");
+ return NULL;
+ }
+ return PyInstance_NewRaw(klass, dict);
+}
+
+
+static void
+instance_dealloc(register PyInstanceObject *inst)
+{
+ PyObject *error_type, *error_value, *error_traceback;
+ PyObject *del;
+ static PyObject *delstr;
+
+ _PyObject_GC_UNTRACK(inst);
+ if (inst->in_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) inst);
+
+ /* Temporarily resurrect the object. */
+ assert(inst->ob_type == &PyInstance_Type);
+ assert(inst->ob_refcnt == 0);
+ inst->ob_refcnt = 1;
+
+ /* Save the current exception, if any. */
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ /* Execute __del__ method, if any. */
+ if (delstr == NULL) {
+ delstr = PyString_InternFromString("__del__");
+ if (delstr == NULL)
+ PyErr_WriteUnraisable((PyObject*)inst);
+ }
+ if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) {
+ PyObject *res = PyEval_CallObject(del, (PyObject *)NULL);
+ if (res == NULL)
+ PyErr_WriteUnraisable(del);
+ else
+ Py_DECREF(res);
+ Py_DECREF(del);
+ }
+ /* Restore the saved exception. */
+ PyErr_Restore(error_type, error_value, error_traceback);
+
+ /* Undo the temporary resurrection; can't use DECREF here, it would
+ * cause a recursive call.
+ */
+ assert(inst->ob_refcnt > 0);
+ if (--inst->ob_refcnt == 0) {
+
+ /* New weakrefs could be created during the finalizer call.
+ If this occurs, clear them out without calling their
+ finalizers since they might rely on part of the object
+ being finalized that has already been destroyed. */
+ while (inst->in_weakreflist != NULL) {
+ _PyWeakref_ClearRef((PyWeakReference *)
+ (inst->in_weakreflist));
+ }
+
+ Py_DECREF(inst->in_class);
+ Py_XDECREF(inst->in_dict);
+ PyObject_GC_Del(inst);
+ }
+ else {
+ Py_ssize_t refcnt = inst->ob_refcnt;
+ /* __del__ resurrected it! Make it look like the original
+ * Py_DECREF never happened.
+ */
+ _Py_NewReference((PyObject *)inst);
+ inst->ob_refcnt = refcnt;
+ _PyObject_GC_TRACK(inst);
+ /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+ * we need to undo that. */
+ _Py_DEC_REFTOTAL;
+ /* If Py_TRACE_REFS, _Py_NewReference re-added self to the
+ * object chain, so no more to do there.
+ * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+ * _Py_NewReference bumped tp_allocs: both of those need to be
+ * undone.
+ */
+#ifdef COUNT_ALLOCS
+ --inst->ob_type->tp_frees;
+ --inst->ob_type->tp_allocs;
+#endif
+ }
+}
+
+static PyObject *
+instance_getattr1(register PyInstanceObject *inst, PyObject *name)
+{
+ register PyObject *v;
+ register char *sname;
+
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+ return NULL;
+ }
+
+ sname = PyString_AsString(name);
+ if (sname[0] == '_' && sname[1] == '_') {
+ if (strcmp(sname, "__dict__") == 0) {
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "instance.__dict__ not accessible in restricted mode");
+ return NULL;
+ }
+ Py_INCREF(inst->in_dict);
+ return inst->in_dict;
+ }
+ if (strcmp(sname, "__class__") == 0) {
+ Py_INCREF(inst->in_class);
+ return (PyObject *)inst->in_class;
+ }
+ }
+ v = instance_getattr2(inst, name);
+ if (v == NULL && !PyErr_Occurred()) {
+ PyErr_Format(PyExc_AttributeError,
+ "%.50s instance has no attribute '%.400s'",
+ PyString_AS_STRING(inst->in_class->cl_name), sname);
+ }
+ return v;
+}
+
+static PyObject *
+instance_getattr2(register PyInstanceObject *inst, PyObject *name)
+{
+ register PyObject *v;
+ PyClassObject *klass;
+ descrgetfunc f;
+
+ v = PyDict_GetItem(inst->in_dict, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ return v;
+ }
+ v = class_lookup(inst->in_class, name, &klass);
+ if (v != NULL) {
+ Py_INCREF(v);
+ f = TP_DESCR_GET(v->ob_type);
+ if (f != NULL) {
+ PyObject *w = f(v, (PyObject *)inst,
+ (PyObject *)(inst->in_class));
+ Py_DECREF(v);
+ v = w;
+ }
+ }
+ return v;
+}
+
+static PyObject *
+instance_getattr(register PyInstanceObject *inst, PyObject *name)
+{
+ register PyObject *func, *res;
+ res = instance_getattr1(inst, name);
+ if (res == NULL && (func = inst->in_class->cl_getattr) != NULL) {
+ PyObject *args;
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ args = PyTuple_Pack(2, inst, name);
+ if (args == NULL)
+ return NULL;
+ res = PyEval_CallObject(func, args);
+ Py_DECREF(args);
+ }
+ return res;
+}
+
+/* See classobject.h comments: this only does dict lookups, and is always
+ * safe to call.
+ */
+PyObject *
+_PyInstance_Lookup(PyObject *pinst, PyObject *name)
+{
+ PyObject *v;
+ PyClassObject *klass;
+ PyInstanceObject *inst; /* pinst cast to the right type */
+
+ assert(PyInstance_Check(pinst));
+ inst = (PyInstanceObject *)pinst;
+
+ assert(PyString_Check(name));
+
+ v = PyDict_GetItem(inst->in_dict, name);
+ if (v == NULL)
+ v = class_lookup(inst->in_class, name, &klass);
+ return v;
+}
+
+static int
+instance_setattr1(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+ if (v == NULL) {
+ int rv = PyDict_DelItem(inst->in_dict, name);
+ if (rv < 0)
+ PyErr_Format(PyExc_AttributeError,
+ "%.50s instance has no attribute '%.400s'",
+ PyString_AS_STRING(inst->in_class->cl_name),
+ PyString_AS_STRING(name));
+ return rv;
+ }
+ else
+ return PyDict_SetItem(inst->in_dict, name, v);
+}
+
+static int
+instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v)
+{
+ PyObject *func, *args, *res, *tmp;
+ char *sname;
+
+ if (!PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError, "attribute name must be a string");
+ return -1;
+ }
+
+ sname = PyString_AsString(name);
+ if (sname[0] == '_' && sname[1] == '_') {
+ Py_ssize_t n = PyString_Size(name);
+ if (sname[n-1] == '_' && sname[n-2] == '_') {
+ if (strcmp(sname, "__dict__") == 0) {
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "__dict__ not accessible in restricted mode");
+ return -1;
+ }
+ if (v == NULL || !PyDict_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__dict__ must be set to a dictionary");
+ return -1;
+ }
+ tmp = inst->in_dict;
+ Py_INCREF(v);
+ inst->in_dict = v;
+ Py_DECREF(tmp);
+ return 0;
+ }
+ if (strcmp(sname, "__class__") == 0) {
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "__class__ not accessible in restricted mode");
+ return -1;
+ }
+ if (v == NULL || !PyClass_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__class__ must be set to a class");
+ return -1;
+ }
+ tmp = (PyObject *)(inst->in_class);
+ Py_INCREF(v);
+ inst->in_class = (PyClassObject *)v;
+ Py_DECREF(tmp);
+ return 0;
+ }
+ }
+ }
+ if (v == NULL)
+ func = inst->in_class->cl_delattr;
+ else
+ func = inst->in_class->cl_setattr;
+ if (func == NULL)
+ return instance_setattr1(inst, name, v);
+ if (v == NULL)
+ args = PyTuple_Pack(2, inst, name);
+ else
+ args = PyTuple_Pack(3, inst, name, v);
+ if (args == NULL)
+ return -1;
+ res = PyEval_CallObject(func, args);
+ Py_DECREF(args);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static PyObject *
+instance_repr(PyInstanceObject *inst)
+{
+ PyObject *func;
+ PyObject *res;
+ static PyObject *reprstr;
+
+ if (reprstr == NULL) {
+ reprstr = PyString_InternFromString("__repr__");
+ if (reprstr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, reprstr);
+ if (func == NULL) {
+ PyObject *classname, *mod;
+ char *cname;
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ classname = inst->in_class->cl_name;
+ mod = PyDict_GetItemString(inst->in_class->cl_dict,
+ "__module__");
+ if (classname != NULL && PyString_Check(classname))
+ cname = PyString_AsString(classname);
+ else
+ cname = "?";
+ if (mod == NULL || !PyString_Check(mod))
+ return PyString_FromFormat("<?.%s instance at %p>",
+ cname, inst);
+ else
+ return PyString_FromFormat("<%s.%s instance at %p>",
+ PyString_AsString(mod),
+ cname, inst);
+ }
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ return res;
+}
+
+static PyObject *
+instance_str(PyInstanceObject *inst)
+{
+ PyObject *func;
+ PyObject *res;
+ static PyObject *strstr;
+
+ if (strstr == NULL) {
+ strstr = PyString_InternFromString("__str__");
+ if (strstr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, strstr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ return instance_repr(inst);
+ }
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ return res;
+}
+
+static long
+instance_hash(PyInstanceObject *inst)
+{
+ PyObject *func;
+ PyObject *res;
+ long outcome;
+ static PyObject *hashstr, *eqstr, *cmpstr;
+
+ if (hashstr == NULL) {
+ hashstr = PyString_InternFromString("__hash__");
+ if (hashstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, hashstr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ /* If there is no __eq__ and no __cmp__ method, we hash on the
+ address. If an __eq__ or __cmp__ method exists, there must
+ be a __hash__. */
+ if (eqstr == NULL) {
+ eqstr = PyString_InternFromString("__eq__");
+ if (eqstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, eqstr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ if (cmpstr == NULL) {
+ cmpstr = PyString_InternFromString("__cmp__");
+ if (cmpstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, cmpstr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(
+ PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ return _Py_HashPointer(inst);
+ }
+ }
+ Py_XDECREF(func);
+ PyErr_SetString(PyExc_TypeError, "unhashable instance");
+ return -1;
+ }
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ if (res == NULL)
+ return -1;
+ if (PyInt_Check(res) || PyLong_Check(res))
+ /* This already converts a -1 result to -2. */
+ outcome = res->ob_type->tp_hash(res);
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "__hash__() should return an int");
+ outcome = -1;
+ }
+ Py_DECREF(res);
+ return outcome;
+}
+
+static int
+instance_traverse(PyInstanceObject *o, visitproc visit, void *arg)
+{
+ Py_VISIT(o->in_class);
+ Py_VISIT(o->in_dict);
+ return 0;
+}
+
+static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
+static PyObject *iterstr, *nextstr;
+
+static Py_ssize_t
+instance_length(PyInstanceObject *inst)
+{
+ PyObject *func;
+ PyObject *res;
+ Py_ssize_t outcome;
+
+ if (lenstr == NULL) {
+ lenstr = PyString_InternFromString("__len__");
+ if (lenstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, lenstr);
+ if (func == NULL)
+ return -1;
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ if (res == NULL)
+ return -1;
+ if (PyInt_Check(res)) {
+ outcome = PyInt_AsSsize_t(res);
+ if (outcome == -1 && PyErr_Occurred()) {
+ Py_DECREF(res);
+ return -1;
+ }
+#if SIZEOF_SIZE_T < SIZEOF_INT
+ /* Overflow check -- range of PyInt is more than C int */
+ if (outcome != (int)outcome) {
+ PyErr_SetString(PyExc_OverflowError,
+ "__len__() should return 0 <= outcome < 2**31");
+ outcome = -1;
+ }
+ else
+#endif
+ if (outcome < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "__len__() should return >= 0");
+ outcome = -1;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "__len__() should return an int");
+ outcome = -1;
+ }
+ Py_DECREF(res);
+ return outcome;
+}
+
+static PyObject *
+instance_subscript(PyInstanceObject *inst, PyObject *key)
+{
+ PyObject *func;
+ PyObject *arg;
+ PyObject *res;
+
+ if (getitemstr == NULL) {
+ getitemstr = PyString_InternFromString("__getitem__");
+ if (getitemstr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, getitemstr);
+ if (func == NULL)
+ return NULL;
+ arg = PyTuple_Pack(1, key);
+ if (arg == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ return res;
+}
+
+static int
+instance_ass_subscript(PyInstanceObject *inst, PyObject *key, PyObject *value)
+{
+ PyObject *func;
+ PyObject *arg;
+ PyObject *res;
+
+ if (value == NULL) {
+ if (delitemstr == NULL) {
+ delitemstr = PyString_InternFromString("__delitem__");
+ if (delitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, delitemstr);
+ }
+ else {
+ if (setitemstr == NULL) {
+ setitemstr = PyString_InternFromString("__setitem__");
+ if (setitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, setitemstr);
+ }
+ if (func == NULL)
+ return -1;
+ if (value == NULL)
+ arg = PyTuple_Pack(1, key);
+ else
+ arg = PyTuple_Pack(2, key, value);
+ if (arg == NULL) {
+ Py_DECREF(func);
+ return -1;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static PyMappingMethods instance_as_mapping = {
+ (lenfunc)instance_length, /* mp_length */
+ (binaryfunc)instance_subscript, /* mp_subscript */
+ (objobjargproc)instance_ass_subscript, /* mp_ass_subscript */
+};
+
+static PyObject *
+instance_item(PyInstanceObject *inst, Py_ssize_t i)
+{
+ PyObject *func, *res;
+
+ if (getitemstr == NULL) {
+ getitemstr = PyString_InternFromString("__getitem__");
+ if (getitemstr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, getitemstr);
+ if (func == NULL)
+ return NULL;
+ res = PyObject_CallFunction(func, "n", i);
+ Py_DECREF(func);
+ return res;
+}
+
+static PyObject *
+instance_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j)
+{
+ PyObject *func, *arg, *res;
+ static PyObject *getslicestr;
+
+ if (getslicestr == NULL) {
+ getslicestr = PyString_InternFromString("__getslice__");
+ if (getslicestr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, getslicestr);
+
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+
+ if (getitemstr == NULL) {
+ getitemstr = PyString_InternFromString("__getitem__");
+ if (getitemstr == NULL)
+ return NULL;
+ }
+ func = instance_getattr(inst, getitemstr);
+ if (func == NULL)
+ return NULL;
+ arg = Py_BuildValue("(N)", _PySlice_FromIndices(i, j));
+ }
+ else {
+ if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
+ "use __getitem__", 1) < 0) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ arg = Py_BuildValue("(nn)", i, j);
+ }
+
+ if (arg == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ return res;
+}
+
+static int
+instance_ass_item(PyInstanceObject *inst, Py_ssize_t i, PyObject *item)
+{
+ PyObject *func, *arg, *res;
+
+ if (item == NULL) {
+ if (delitemstr == NULL) {
+ delitemstr = PyString_InternFromString("__delitem__");
+ if (delitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, delitemstr);
+ }
+ else {
+ if (setitemstr == NULL) {
+ setitemstr = PyString_InternFromString("__setitem__");
+ if (setitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, setitemstr);
+ }
+ if (func == NULL)
+ return -1;
+ if (item == NULL)
+ arg = Py_BuildValue("(n)", i);
+ else
+ arg = Py_BuildValue("(nO)", i, item);
+ if (arg == NULL) {
+ Py_DECREF(func);
+ return -1;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static int
+instance_ass_slice(PyInstanceObject *inst, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+ PyObject *func, *arg, *res;
+ static PyObject *setslicestr, *delslicestr;
+
+ if (value == NULL) {
+ if (delslicestr == NULL) {
+ delslicestr =
+ PyString_InternFromString("__delslice__");
+ if (delslicestr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, delslicestr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ if (delitemstr == NULL) {
+ delitemstr =
+ PyString_InternFromString("__delitem__");
+ if (delitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, delitemstr);
+ if (func == NULL)
+ return -1;
+
+ arg = Py_BuildValue("(N)",
+ _PySlice_FromIndices(i, j));
+ }
+ else {
+ if (PyErr_WarnPy3k("in 3.x, __delslice__ has been "
+ "removed; use __delitem__", 1) < 0) {
+ Py_DECREF(func);
+ return -1;
+ }
+ arg = Py_BuildValue("(nn)", i, j);
+ }
+ }
+ else {
+ if (setslicestr == NULL) {
+ setslicestr =
+ PyString_InternFromString("__setslice__");
+ if (setslicestr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, setslicestr);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ if (setitemstr == NULL) {
+ setitemstr =
+ PyString_InternFromString("__setitem__");
+ if (setitemstr == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, setitemstr);
+ if (func == NULL)
+ return -1;
+
+ arg = Py_BuildValue("(NO)",
+ _PySlice_FromIndices(i, j), value);
+ }
+ else {
+ if (PyErr_WarnPy3k("in 3.x, __setslice__ has been "
+ "removed; use __setitem__", 1) < 0) {
+ Py_DECREF(func);
+ return -1;
+ }
+ arg = Py_BuildValue("(nnO)", i, j, value);
+ }
+ }
+ if (arg == NULL) {
+ Py_DECREF(func);
+ return -1;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static int
+instance_contains(PyInstanceObject *inst, PyObject *member)
+{
+ static PyObject *__contains__;
+ PyObject *func;
+
+ /* Try __contains__ first.
+ * If that can't be done, try iterator-based searching.
+ */
+
+ if(__contains__ == NULL) {
+ __contains__ = PyString_InternFromString("__contains__");
+ if(__contains__ == NULL)
+ return -1;
+ }
+ func = instance_getattr(inst, __contains__);
+ if (func) {
+ PyObject *res;
+ int ret;
+ PyObject *arg = PyTuple_Pack(1, member);
+ if(arg == NULL) {
+ Py_DECREF(func);
+ return -1;
+ }
+ res = PyEval_CallObject(func, arg);
+ Py_DECREF(func);
+ Py_DECREF(arg);
+ if(res == NULL)
+ return -1;
+ ret = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ return ret;
+ }
+
+ /* Couldn't find __contains__. */
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ Py_ssize_t rc;
+ /* Assume the failure was simply due to that there is no
+ * __contains__ attribute, and try iterating instead.
+ */
+ PyErr_Clear();
+ rc = _PySequence_IterSearch((PyObject *)inst, member,
+ PY_ITERSEARCH_CONTAINS);
+ if (rc >= 0)
+ return rc > 0;
+ }
+ return -1;
+}
+
+static PySequenceMethods
+instance_as_sequence = {
+ (lenfunc)instance_length, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)instance_item, /* sq_item */
+ (ssizessizeargfunc)instance_slice, /* sq_slice */
+ (ssizeobjargproc)instance_ass_item, /* sq_ass_item */
+ (ssizessizeobjargproc)instance_ass_slice,/* sq_ass_slice */
+ (objobjproc)instance_contains, /* sq_contains */
+};
+
+static PyObject *
+generic_unary_op(PyInstanceObject *self, PyObject *methodname)
+{
+ PyObject *func, *res;
+
+ if ((func = instance_getattr(self, methodname)) == NULL)
+ return NULL;
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ return res;
+}
+
+static PyObject *
+generic_binary_op(PyObject *v, PyObject *w, char *opname)
+{
+ PyObject *result;
+ PyObject *args;
+ PyObject *func = PyObject_GetAttrString(v, opname);
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ args = PyTuple_Pack(1, w);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObject(func, args);
+ Py_DECREF(args);
+ Py_DECREF(func);
+ return result;
+}
+
+
+static PyObject *coerce_obj;
+
+/* Try one half of a binary operator involving a class instance. */
+static PyObject *
+half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc,
+ int swapped)
+{
+ PyObject *args;
+ PyObject *coercefunc;
+ PyObject *coerced = NULL;
+ PyObject *v1;
+ PyObject *result;
+
+ if (!PyInstance_Check(v)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ if (coerce_obj == NULL) {
+ coerce_obj = PyString_InternFromString("__coerce__");
+ if (coerce_obj == NULL)
+ return NULL;
+ }
+ coercefunc = PyObject_GetAttr(v, coerce_obj);
+ if (coercefunc == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ return generic_binary_op(v, w, opname);
+ }
+
+ args = PyTuple_Pack(1, w);
+ if (args == NULL) {
+ Py_DECREF(coercefunc);
+ return NULL;
+ }
+ coerced = PyEval_CallObject(coercefunc, args);
+ Py_DECREF(args);
+ Py_DECREF(coercefunc);
+ if (coerced == NULL) {
+ return NULL;
+ }
+ if (coerced == Py_None || coerced == Py_NotImplemented) {
+ Py_DECREF(coerced);
+ return generic_binary_op(v, w, opname);
+ }
+ if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+ Py_DECREF(coerced);
+ PyErr_SetString(PyExc_TypeError,
+ "coercion should return None or 2-tuple");
+ return NULL;
+ }
+ v1 = PyTuple_GetItem(coerced, 0);
+ w = PyTuple_GetItem(coerced, 1);
+ if (v1->ob_type == v->ob_type && PyInstance_Check(v)) {
+ /* prevent recursion if __coerce__ returns self as the first
+ * argument */
+ result = generic_binary_op(v1, w, opname);
+ } else {
+ if (Py_EnterRecursiveCall(" after coercion"))
+ return NULL;
+ if (swapped)
+ result = (thisfunc)(w, v1);
+ else
+ result = (thisfunc)(v1, w);
+ Py_LeaveRecursiveCall();
+ }
+ Py_DECREF(coerced);
+ return result;
+}
+
+/* Implement a binary operator involving at least one class instance. */
+static PyObject *
+do_binop(PyObject *v, PyObject *w, char *opname, char *ropname,
+ binaryfunc thisfunc)
+{
+ PyObject *result = half_binop(v, w, opname, thisfunc, 0);
+ if (result == Py_NotImplemented) {
+ Py_DECREF(result);
+ result = half_binop(w, v, ropname, thisfunc, 1);
+ }
+ return result;
+}
+
+static PyObject *
+do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname,
+ char *ropname, binaryfunc thisfunc)
+{
+ PyObject *result = half_binop(v, w, iopname, thisfunc, 0);
+ if (result == Py_NotImplemented) {
+ Py_DECREF(result);
+ result = do_binop(v, w, opname, ropname, thisfunc);
+ }
+ return result;
+}
+
+static int
+instance_coerce(PyObject **pv, PyObject **pw)
+{
+ PyObject *v = *pv;
+ PyObject *w = *pw;
+ PyObject *coercefunc;
+ PyObject *args;
+ PyObject *coerced;
+
+ if (coerce_obj == NULL) {
+ coerce_obj = PyString_InternFromString("__coerce__");
+ if (coerce_obj == NULL)
+ return -1;
+ }
+ coercefunc = PyObject_GetAttr(v, coerce_obj);
+ if (coercefunc == NULL) {
+ /* No __coerce__ method */
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ return 1;
+ }
+ /* Has __coerce__ method: call it */
+ args = PyTuple_Pack(1, w);
+ if (args == NULL) {
+ return -1;
+ }
+ coerced = PyEval_CallObject(coercefunc, args);
+ Py_DECREF(args);
+ Py_DECREF(coercefunc);
+ if (coerced == NULL) {
+ /* __coerce__ call raised an exception */
+ return -1;
+ }
+ if (coerced == Py_None || coerced == Py_NotImplemented) {
+ /* __coerce__ says "I can't do it" */
+ Py_DECREF(coerced);
+ return 1;
+ }
+ if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) {
+ /* __coerce__ return value is malformed */
+ Py_DECREF(coerced);
+ PyErr_SetString(PyExc_TypeError,
+ "coercion should return None or 2-tuple");
+ return -1;
+ }
+ /* __coerce__ returned two new values */
+ *pv = PyTuple_GetItem(coerced, 0);
+ *pw = PyTuple_GetItem(coerced, 1);
+ Py_INCREF(*pv);
+ Py_INCREF(*pw);
+ Py_DECREF(coerced);
+ return 0;
+}
+
+#define UNARY(funcname, methodname) \
+static PyObject *funcname(PyInstanceObject *self) { \
+ static PyObject *o; \
+ if (o == NULL) { o = PyString_InternFromString(methodname); \
+ if (o == NULL) return NULL; } \
+ return generic_unary_op(self, o); \
+}
+
+/* unary function with a fallback */
+#define UNARY_FB(funcname, methodname, funcname_fb) \
+static PyObject *funcname(PyInstanceObject *self) { \
+ static PyObject *o; \
+ if (o == NULL) { o = PyString_InternFromString(methodname); \
+ if (o == NULL) return NULL; } \
+ if (PyObject_HasAttr((PyObject*)self, o)) \
+ return generic_unary_op(self, o); \
+ else \
+ return funcname_fb(self); \
+}
+
+#define BINARY(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+ return do_binop(v, w, "__" m "__", "__r" m "__", n); \
+}
+
+#define BINARY_INPLACE(f, m, n) \
+static PyObject *f(PyObject *v, PyObject *w) { \
+ return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \
+ "__r" m "__", n); \
+}
+
+UNARY(instance_neg, "__neg__")
+UNARY(instance_pos, "__pos__")
+UNARY(instance_abs, "__abs__")
+
+BINARY(instance_or, "or", PyNumber_Or)
+BINARY(instance_and, "and", PyNumber_And)
+BINARY(instance_xor, "xor", PyNumber_Xor)
+BINARY(instance_lshift, "lshift", PyNumber_Lshift)
+BINARY(instance_rshift, "rshift", PyNumber_Rshift)
+BINARY(instance_add, "add", PyNumber_Add)
+BINARY(instance_sub, "sub", PyNumber_Subtract)
+BINARY(instance_mul, "mul", PyNumber_Multiply)
+BINARY(instance_div, "div", PyNumber_Divide)
+BINARY(instance_mod, "mod", PyNumber_Remainder)
+BINARY(instance_divmod, "divmod", PyNumber_Divmod)
+BINARY(instance_floordiv, "floordiv", PyNumber_FloorDivide)
+BINARY(instance_truediv, "truediv", PyNumber_TrueDivide)
+
+BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr)
+BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor)
+BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd)
+BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift)
+BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift)
+BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd)
+BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract)
+BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply)
+BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide)
+BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder)
+BINARY_INPLACE(instance_ifloordiv, "floordiv", PyNumber_InPlaceFloorDivide)
+BINARY_INPLACE(instance_itruediv, "truediv", PyNumber_InPlaceTrueDivide)
+
+/* Try a 3-way comparison, returning an int; v is an instance. Return:
+ -2 for an exception;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w;
+ 2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+half_cmp(PyObject *v, PyObject *w)
+{
+ static PyObject *cmp_obj;
+ PyObject *args;
+ PyObject *cmp_func;
+ PyObject *result;
+ long l;
+
+ assert(PyInstance_Check(v));
+
+ if (cmp_obj == NULL) {
+ cmp_obj = PyString_InternFromString("__cmp__");
+ if (cmp_obj == NULL)
+ return -2;
+ }
+
+ cmp_func = PyObject_GetAttr(v, cmp_obj);
+ if (cmp_func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -2;
+ PyErr_Clear();
+ return 2;
+ }
+
+ args = PyTuple_Pack(1, w);
+ if (args == NULL) {
+ Py_DECREF(cmp_func);
+ return -2;
+ }
+
+ result = PyEval_CallObject(cmp_func, args);
+ Py_DECREF(args);
+ Py_DECREF(cmp_func);
+
+ if (result == NULL)
+ return -2;
+
+ if (result == Py_NotImplemented) {
+ Py_DECREF(result);
+ return 2;
+ }
+
+ l = PyInt_AsLong(result);
+ Py_DECREF(result);
+ if (l == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "comparison did not return an int");
+ return -2;
+ }
+
+ return l < 0 ? -1 : l > 0 ? 1 : 0;
+}
+
+/* Try a 3-way comparison, returning an int; either v or w is an instance.
+ We first try a coercion. Return:
+ -2 for an exception;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w;
+ 2 if this particular 3-way comparison is not implemented or undefined.
+ THIS IS ONLY CALLED FROM object.c!
+*/
+static int
+instance_compare(PyObject *v, PyObject *w)
+{
+ int c;
+
+ c = PyNumber_CoerceEx(&v, &w);
+ if (c < 0)
+ return -2;
+ if (c == 0) {
+ /* If neither is now an instance, use regular comparison */
+ if (!PyInstance_Check(v) && !PyInstance_Check(w)) {
+ c = PyObject_Compare(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (PyErr_Occurred())
+ return -2;
+ return c < 0 ? -1 : c > 0 ? 1 : 0;
+ }
+ }
+ else {
+ /* The coercion didn't do anything.
+ Treat this the same as returning v and w unchanged. */
+ Py_INCREF(v);
+ Py_INCREF(w);
+ }
+
+ if (PyInstance_Check(v)) {
+ c = half_cmp(v, w);
+ if (c <= 1) {
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return c;
+ }
+ }
+ if (PyInstance_Check(w)) {
+ c = half_cmp(w, v);
+ if (c <= 1) {
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (c >= -1)
+ c = -c;
+ return c;
+ }
+ }
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return 2;
+}
+
+static int
+instance_nonzero(PyInstanceObject *self)
+{
+ PyObject *func, *res;
+ long outcome;
+ static PyObject *nonzerostr;
+
+ if (nonzerostr == NULL) {
+ nonzerostr = PyString_InternFromString("__nonzero__");
+ if (nonzerostr == NULL)
+ return -1;
+ }
+ if ((func = instance_getattr(self, nonzerostr)) == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ if (lenstr == NULL) {
+ lenstr = PyString_InternFromString("__len__");
+ if (lenstr == NULL)
+ return -1;
+ }
+ if ((func = instance_getattr(self, lenstr)) == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_Clear();
+ /* Fall back to the default behavior:
+ all instances are nonzero */
+ return 1;
+ }
+ }
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ if (res == NULL)
+ return -1;
+ if (!PyInt_Check(res)) {
+ Py_DECREF(res);
+ PyErr_SetString(PyExc_TypeError,
+ "__nonzero__ should return an int");
+ return -1;
+ }
+ outcome = PyInt_AsLong(res);
+ Py_DECREF(res);
+ if (outcome < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "__nonzero__ should return >= 0");
+ return -1;
+ }
+ return outcome > 0;
+}
+
+static PyObject *
+instance_index(PyInstanceObject *self)
+{
+ PyObject *func, *res;
+ static PyObject *indexstr = NULL;
+
+ if (indexstr == NULL) {
+ indexstr = PyString_InternFromString("__index__");
+ if (indexstr == NULL)
+ return NULL;
+ }
+ if ((func = instance_getattr(self, indexstr)) == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "object cannot be interpreted as an index");
+ return NULL;
+ }
+ res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ return res;
+}
+
+
+UNARY(instance_invert, "__invert__")
+UNARY(_instance_trunc, "__trunc__")
+
+static PyObject *
+instance_int(PyInstanceObject *self)
+{
+ PyObject *truncated;
+ static PyObject *int_name;
+ if (int_name == NULL) {
+ int_name = PyString_InternFromString("__int__");
+ if (int_name == NULL)
+ return NULL;
+ }
+ if (PyObject_HasAttr((PyObject*)self, int_name))
+ return generic_unary_op(self, int_name);
+
+ truncated = _instance_trunc(self);
+ /* __trunc__ is specified to return an Integral type, but
+ int() needs to return an int. */
+ return _PyNumber_ConvertIntegralToInt(
+ truncated,
+ "__trunc__ returned non-Integral (type %.200s)");
+}
+
+UNARY_FB(instance_long, "__long__", instance_int)
+UNARY(instance_float, "__float__")
+UNARY(instance_oct, "__oct__")
+UNARY(instance_hex, "__hex__")
+
+static PyObject *
+bin_power(PyObject *v, PyObject *w)
+{
+ return PyNumber_Power(v, w, Py_None);
+}
+
+/* This version is for ternary calls only (z != None) */
+static PyObject *
+instance_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+ if (z == Py_None) {
+ return do_binop(v, w, "__pow__", "__rpow__", bin_power);
+ }
+ else {
+ PyObject *func;
+ PyObject *args;
+ PyObject *result;
+
+ /* XXX Doesn't do coercions... */
+ func = PyObject_GetAttrString(v, "__pow__");
+ if (func == NULL)
+ return NULL;
+ args = PyTuple_Pack(2, w, z);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObject(func, args);
+ Py_DECREF(func);
+ Py_DECREF(args);
+ return result;
+ }
+}
+
+static PyObject *
+bin_inplace_power(PyObject *v, PyObject *w)
+{
+ return PyNumber_InPlacePower(v, w, Py_None);
+}
+
+
+static PyObject *
+instance_ipow(PyObject *v, PyObject *w, PyObject *z)
+{
+ if (z == Py_None) {
+ return do_binop_inplace(v, w, "__ipow__", "__pow__",
+ "__rpow__", bin_inplace_power);
+ }
+ else {
+ /* XXX Doesn't do coercions... */
+ PyObject *func;
+ PyObject *args;
+ PyObject *result;
+
+ func = PyObject_GetAttrString(v, "__ipow__");
+ if (func == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ return instance_pow(v, w, z);
+ }
+ args = PyTuple_Pack(2, w, z);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObject(func, args);
+ Py_DECREF(func);
+ Py_DECREF(args);
+ return result;
+ }
+}
+
+
+/* Map rich comparison operators to their __xx__ namesakes */
+#define NAME_OPS 6
+static PyObject **name_op = NULL;
+
+static int
+init_name_op(void)
+{
+ int i;
+ char *_name_op[] = {
+ "__lt__",
+ "__le__",
+ "__eq__",
+ "__ne__",
+ "__gt__",
+ "__ge__",
+ };
+
+ name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS);
+ if (name_op == NULL)
+ return -1;
+ for (i = 0; i < NAME_OPS; ++i) {
+ name_op[i] = PyString_InternFromString(_name_op[i]);
+ if (name_op[i] == NULL)
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+half_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *method;
+ PyObject *args;
+ PyObject *res;
+
+ assert(PyInstance_Check(v));
+
+ if (name_op == NULL) {
+ if (init_name_op() < 0)
+ return NULL;
+ }
+ /* If the instance doesn't define an __getattr__ method, use
+ instance_getattr2 directly because it will not set an
+ exception on failure. */
+ if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL)
+ method = instance_getattr2((PyInstanceObject *)v,
+ name_op[op]);
+ else
+ method = PyObject_GetAttr(v, name_op[op]);
+ if (method == NULL) {
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ }
+ res = Py_NotImplemented;
+ Py_INCREF(res);
+ return res;
+ }
+
+ args = PyTuple_Pack(1, w);
+ if (args == NULL) {
+ Py_DECREF(method);
+ return NULL;
+ }
+
+ res = PyEval_CallObject(method, args);
+ Py_DECREF(args);
+ Py_DECREF(method);
+
+ return res;
+}
+
+static PyObject *
+instance_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+
+ if (PyInstance_Check(v)) {
+ res = half_richcompare(v, w, op);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+
+ if (PyInstance_Check(w)) {
+ res = half_richcompare(w, v, _Py_SwappedOp[op]);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+
+/* Get the iterator */
+static PyObject *
+instance_getiter(PyInstanceObject *self)
+{
+ PyObject *func;
+
+ if (iterstr == NULL) {
+ iterstr = PyString_InternFromString("__iter__");
+ if (iterstr == NULL)
+ return NULL;
+ }
+ if (getitemstr == NULL) {
+ getitemstr = PyString_InternFromString("__getitem__");
+ if (getitemstr == NULL)
+ return NULL;
+ }
+
+ if ((func = instance_getattr(self, iterstr)) != NULL) {
+ PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ if (res != NULL && !PyIter_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "__iter__ returned non-iterator "
+ "of type '%.100s'",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ res = NULL;
+ }
+ return res;
+ }
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ if ((func = instance_getattr(self, getitemstr)) == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "iteration over non-sequence");
+ return NULL;
+ }
+ Py_DECREF(func);
+ return PySeqIter_New((PyObject *)self);
+}
+
+
+/* Call the iterator's next */
+static PyObject *
+instance_iternext(PyInstanceObject *self)
+{
+ PyObject *func;
+
+ if (nextstr == NULL) {
+ nextstr = PyString_InternFromString("next");
+ if (nextstr == NULL)
+ return NULL;
+ }
+
+ if ((func = instance_getattr(self, nextstr)) != NULL) {
+ PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ if (res != NULL) {
+ return res;
+ }
+ if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+ PyErr_Clear();
+ return NULL;
+ }
+ return NULL;
+ }
+ PyErr_SetString(PyExc_TypeError, "instance has no next() method");
+ return NULL;
+}
+
+static PyObject *
+instance_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ PyObject *res, *call = PyObject_GetAttrString(func, "__call__");
+ if (call == NULL) {
+ PyInstanceObject *inst = (PyInstanceObject*) func;
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ PyErr_Format(PyExc_AttributeError,
+ "%.200s instance has no __call__ method",
+ PyString_AsString(inst->in_class->cl_name));
+ return NULL;
+ }
+ /* We must check and increment the recursion depth here. Scenario:
+ class A:
+ pass
+ A.__call__ = A() # that's right
+ a = A() # ok
+ a() # infinite recursion
+ This bounces between instance_call() and PyObject_Call() without
+ ever hitting eval_frame() (which has the main recursion check). */
+ if (Py_EnterRecursiveCall(" in __call__")) {
+ res = NULL;
+ }
+ else {
+ res = PyObject_Call(call, arg, kw);
+ Py_LeaveRecursiveCall();
+ }
+ Py_DECREF(call);
+ return res;
+}
+
+
+static PyNumberMethods instance_as_number = {
+ instance_add, /* nb_add */
+ instance_sub, /* nb_subtract */
+ instance_mul, /* nb_multiply */
+ instance_div, /* nb_divide */
+ instance_mod, /* nb_remainder */
+ instance_divmod, /* nb_divmod */
+ instance_pow, /* nb_power */
+ (unaryfunc)instance_neg, /* nb_negative */
+ (unaryfunc)instance_pos, /* nb_positive */
+ (unaryfunc)instance_abs, /* nb_absolute */
+ (inquiry)instance_nonzero, /* nb_nonzero */
+ (unaryfunc)instance_invert, /* nb_invert */
+ instance_lshift, /* nb_lshift */
+ instance_rshift, /* nb_rshift */
+ instance_and, /* nb_and */
+ instance_xor, /* nb_xor */
+ instance_or, /* nb_or */
+ instance_coerce, /* nb_coerce */
+ (unaryfunc)instance_int, /* nb_int */
+ (unaryfunc)instance_long, /* nb_long */
+ (unaryfunc)instance_float, /* nb_float */
+ (unaryfunc)instance_oct, /* nb_oct */
+ (unaryfunc)instance_hex, /* nb_hex */
+ instance_iadd, /* nb_inplace_add */
+ instance_isub, /* nb_inplace_subtract */
+ instance_imul, /* nb_inplace_multiply */
+ instance_idiv, /* nb_inplace_divide */
+ instance_imod, /* nb_inplace_remainder */
+ instance_ipow, /* nb_inplace_power */
+ instance_ilshift, /* nb_inplace_lshift */
+ instance_irshift, /* nb_inplace_rshift */
+ instance_iand, /* nb_inplace_and */
+ instance_ixor, /* nb_inplace_xor */
+ instance_ior, /* nb_inplace_or */
+ instance_floordiv, /* nb_floor_divide */
+ instance_truediv, /* nb_true_divide */
+ instance_ifloordiv, /* nb_inplace_floor_divide */
+ instance_itruediv, /* nb_inplace_true_divide */
+ (unaryfunc)instance_index, /* nb_index */
+};
+
+PyTypeObject PyInstance_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "instance",
+ sizeof(PyInstanceObject),
+ 0,
+ (destructor)instance_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ instance_compare, /* tp_compare */
+ (reprfunc)instance_repr, /* tp_repr */
+ &instance_as_number, /* tp_as_number */
+ &instance_as_sequence, /* tp_as_sequence */
+ &instance_as_mapping, /* tp_as_mapping */
+ (hashfunc)instance_hash, /* tp_hash */
+ instance_call, /* tp_call */
+ (reprfunc)instance_str, /* tp_str */
+ (getattrofunc)instance_getattr, /* tp_getattro */
+ (setattrofunc)instance_setattr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/
+ instance_doc, /* tp_doc */
+ (traverseproc)instance_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ instance_richcompare, /* tp_richcompare */
+ offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)instance_getiter, /* tp_iter */
+ (iternextfunc)instance_iternext, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* 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 */
+ instance_new, /* tp_new */
+};
+
+
+/* Instance method objects are used for two purposes:
+ (a) as bound instance methods (returned by instancename.methodname)
+ (b) as unbound methods (returned by ClassName.methodname)
+ In case (b), im_self is NULL
+*/
+
+PyObject *
+PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
+{
+ register PyMethodObject *im;
+ im = free_list;
+ if (im != NULL) {
+ free_list = (PyMethodObject *)(im->im_self);
+ PyObject_INIT(im, &PyMethod_Type);
+ numfree--;
+ }
+ else {
+ im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
+ if (im == NULL)
+ return NULL;
+ }
+ im->im_weakreflist = NULL;
+ Py_INCREF(func);
+ im->im_func = func;
+ Py_XINCREF(self);
+ im->im_self = self;
+ Py_XINCREF(klass);
+ im->im_class = klass;
+ _PyObject_GC_TRACK(im);
+ return (PyObject *)im;
+}
+
+/* Descriptors for PyMethod attributes */
+
+/* im_class, im_func and im_self are stored in the PyMethod object */
+
+#define OFF(x) offsetof(PyMethodObject, x)
+
+static PyMemberDef instancemethod_memberlist[] = {
+ {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED,
+ "the class associated with a method"},
+ {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,
+ "the function (or other callable) implementing a method"},
+ {"__func__", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,
+ "the function (or other callable) implementing a method"},
+ {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,
+ "the instance to which a method is bound; None for unbound methods"},
+ {"__self__", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,
+ "the instance to which a method is bound; None for unbound methods"},
+ {NULL} /* Sentinel */
+};
+
+/* Christian Tismer argued convincingly that method attributes should
+ (nearly) always override function attributes.
+ The one exception is __doc__; there's a default __doc__ which
+ should only be used for the class, not for instances */
+
+static PyObject *
+instancemethod_get_doc(PyMethodObject *im, void *context)
+{
+ static PyObject *docstr;
+ if (docstr == NULL) {
+ docstr= PyString_InternFromString("__doc__");
+ if (docstr == NULL)
+ return NULL;
+ }
+ return PyObject_GetAttr(im->im_func, docstr);
+}
+
+static PyGetSetDef instancemethod_getset[] = {
+ {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
+ {0}
+};
+
+static PyObject *
+instancemethod_getattro(PyObject *obj, PyObject *name)
+{
+ PyMethodObject *im = (PyMethodObject *)obj;
+ PyTypeObject *tp = obj->ob_type;
+ PyObject *descr = NULL;
+
+ if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
+ if (tp->tp_dict == NULL) {
+ if (PyType_Ready(tp) < 0)
+ return NULL;
+ }
+ descr = _PyType_Lookup(tp, name);
+ }
+
+ if (descr != NULL) {
+ descrgetfunc f = TP_DESCR_GET(descr->ob_type);
+ if (f != NULL)
+ return f(descr, obj, (PyObject *)obj->ob_type);
+ else {
+ Py_INCREF(descr);
+ return descr;
+ }
+ }
+
+ return PyObject_GetAttr(im->im_func, name);
+}
+
+PyDoc_STRVAR(instancemethod_doc,
+"instancemethod(function, instance, class)\n\
+\n\
+Create an instance method object.");
+
+static PyObject *
+instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+ PyObject *func;
+ PyObject *self;
+ PyObject *classObj = NULL;
+
+ if (!_PyArg_NoKeywords("instancemethod", kw))
+ return NULL;
+ if (!PyArg_UnpackTuple(args, "instancemethod", 2, 3,
+ &func, &self, &classObj))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "first argument must be callable");
+ return NULL;
+ }
+ if (self == Py_None)
+ self = NULL;
+ if (self == NULL && classObj == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "unbound methods must have non-NULL im_class");
+ return NULL;
+ }
+
+ return PyMethod_New(func, self, classObj);
+}
+
+static void
+instancemethod_dealloc(register PyMethodObject *im)
+{
+ _PyObject_GC_UNTRACK(im);
+ if (im->im_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *)im);
+ Py_DECREF(im->im_func);
+ Py_XDECREF(im->im_self);
+ Py_XDECREF(im->im_class);
+ if (numfree < PyMethod_MAXFREELIST) {
+ im->im_self = (PyObject *)free_list;
+ free_list = im;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(im);
+ }
+}
+
+static int
+instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
+{
+ int cmp;
+ cmp = PyObject_Compare(a->im_func, b->im_func);
+ if (cmp)
+ return cmp;
+
+ if (a->im_self == b->im_self)
+ return 0;
+ if (a->im_self == NULL || b->im_self == NULL)
+ return (a->im_self < b->im_self) ? -1 : 1;
+ else
+ return PyObject_Compare(a->im_self, b->im_self);
+}
+
+static PyObject *
+instancemethod_repr(PyMethodObject *a)
+{
+ PyObject *self = a->im_self;
+ PyObject *func = a->im_func;
+ PyObject *klass = a->im_class;
+ PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
+ char *sfuncname = "?", *sklassname = "?";
+
+ funcname = PyObject_GetAttrString(func, "__name__");
+ if (funcname == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ }
+ else if (!PyString_Check(funcname)) {
+ Py_DECREF(funcname);
+ funcname = NULL;
+ }
+ else
+ sfuncname = PyString_AS_STRING(funcname);
+ if (klass == NULL)
+ klassname = NULL;
+ else {
+ klassname = PyObject_GetAttrString(klass, "__name__");
+ if (klassname == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return NULL;
+ PyErr_Clear();
+ }
+ else if (!PyString_Check(klassname)) {
+ Py_DECREF(klassname);
+ klassname = NULL;
+ }
+ else
+ sklassname = PyString_AS_STRING(klassname);
+ }
+ if (self == NULL)
+ result = PyString_FromFormat("<unbound method %s.%s>",
+ sklassname, sfuncname);
+ else {
+ /* XXX Shouldn't use repr() here! */
+ PyObject *selfrepr = PyObject_Repr(self);
+ if (selfrepr == NULL)
+ goto fail;
+ if (!PyString_Check(selfrepr)) {
+ Py_DECREF(selfrepr);
+ goto fail;
+ }
+ result = PyString_FromFormat("<bound method %s.%s of %s>",
+ sklassname, sfuncname,
+ PyString_AS_STRING(selfrepr));
+ Py_DECREF(selfrepr);
+ }
+ fail:
+ Py_XDECREF(funcname);
+ Py_XDECREF(klassname);
+ return result;
+}
+
+static long
+instancemethod_hash(PyMethodObject *a)
+{
+ long x, y;
+ if (a->im_self == NULL)
+ x = PyObject_Hash(Py_None);
+ else
+ x = PyObject_Hash(a->im_self);
+ if (x == -1)
+ return -1;
+ y = PyObject_Hash(a->im_func);
+ if (y == -1)
+ return -1;
+ x = x ^ y;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+static int
+instancemethod_traverse(PyMethodObject *im, visitproc visit, void *arg)
+{
+ Py_VISIT(im->im_func);
+ Py_VISIT(im->im_self);
+ Py_VISIT(im->im_class);
+ return 0;
+}
+
+static void
+getclassname(PyObject *klass, char *buf, int bufsize)
+{
+ PyObject *name;
+
+ assert(bufsize > 1);
+ strcpy(buf, "?"); /* Default outcome */
+ if (klass == NULL)
+ return;
+ name = PyObject_GetAttrString(klass, "__name__");
+ if (name == NULL) {
+ /* This function cannot return an exception */
+ PyErr_Clear();
+ return;
+ }
+ if (PyString_Check(name)) {
+ strncpy(buf, PyString_AS_STRING(name), bufsize);
+ buf[bufsize-1] = '\0';
+ }
+ Py_DECREF(name);
+}
+
+static void
+getinstclassname(PyObject *inst, char *buf, int bufsize)
+{
+ PyObject *klass;
+
+ if (inst == NULL) {
+ assert(bufsize > 0 && (size_t)bufsize > strlen("nothing"));
+ strcpy(buf, "nothing");
+ return;
+ }
+
+ klass = PyObject_GetAttrString(inst, "__class__");
+ if (klass == NULL) {
+ /* This function cannot return an exception */
+ PyErr_Clear();
+ klass = (PyObject *)(inst->ob_type);
+ Py_INCREF(klass);
+ }
+ getclassname(klass, buf, bufsize);
+ Py_XDECREF(klass);
+}
+
+static PyObject *
+instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ PyObject *self = PyMethod_GET_SELF(func);
+ PyObject *klass = PyMethod_GET_CLASS(func);
+ PyObject *result;
+
+ func = PyMethod_GET_FUNCTION(func);
+ if (self == NULL) {
+ /* Unbound methods must be called with an instance of
+ the class (or a derived class) as first argument */
+ int ok;
+ if (PyTuple_Size(arg) >= 1)
+ self = PyTuple_GET_ITEM(arg, 0);
+ if (self == NULL)
+ ok = 0;
+ else {
+ ok = PyObject_IsInstance(self, klass);
+ if (ok < 0)
+ return NULL;
+ }
+ if (!ok) {
+ char clsbuf[256];
+ char instbuf[256];
+ getclassname(klass, clsbuf, sizeof(clsbuf));
+ getinstclassname(self, instbuf, sizeof(instbuf));
+ PyErr_Format(PyExc_TypeError,
+ "unbound method %s%s must be called with "
+ "%s instance as first argument "
+ "(got %s%s instead)",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ clsbuf,
+ instbuf,
+ self == NULL ? "" : " instance");
+ return NULL;
+ }
+ Py_INCREF(arg);
+ }
+ else {
+ Py_ssize_t argcount = PyTuple_Size(arg);
+ PyObject *newarg = PyTuple_New(argcount + 1);
+ int i;
+ if (newarg == NULL)
+ return NULL;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(newarg, 0, self);
+ for (i = 0; i < argcount; i++) {
+ PyObject *v = PyTuple_GET_ITEM(arg, i);
+ Py_XINCREF(v);
+ PyTuple_SET_ITEM(newarg, i+1, v);
+ }
+ arg = newarg;
+ }
+ result = PyObject_Call((PyObject *)func, arg, kw);
+ Py_DECREF(arg);
+ return result;
+}
+
+static PyObject *
+instancemethod_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
+{
+ /* Don't rebind an already bound method, or an unbound method
+ of a class that's not a base class of cls. */
+
+ if (PyMethod_GET_SELF(meth) != NULL) {
+ /* Already bound */
+ Py_INCREF(meth);
+ return meth;
+ }
+ /* No, it is an unbound method */
+ if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {
+ /* Do subclass test. If it fails, return meth unchanged. */
+ int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth));
+ if (ok < 0)
+ return NULL;
+ if (!ok) {
+ Py_INCREF(meth);
+ return meth;
+ }
+ }
+ /* Bind it to obj */
+ return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls);
+}
+
+PyTypeObject PyMethod_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "instancemethod",
+ sizeof(PyMethodObject),
+ 0,
+ (destructor)instancemethod_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)instancemethod_compare, /* tp_compare */
+ (reprfunc)instancemethod_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)instancemethod_hash, /* tp_hash */
+ instancemethod_call, /* tp_call */
+ 0, /* tp_str */
+ instancemethod_getattro, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ instancemethod_doc, /* tp_doc */
+ (traverseproc)instancemethod_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ instancemethod_memberlist, /* tp_members */
+ instancemethod_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ instancemethod_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ instancemethod_new, /* tp_new */
+};
+
+/* Clear out the free list */
+
+int
+PyMethod_ClearFreeList(void)
+{
+ int freelist_size = numfree;
+
+ while (free_list) {
+ PyMethodObject *im = free_list;
+ free_list = (PyMethodObject *)(im->im_self);
+ PyObject_GC_Del(im);
+ numfree--;
+ }
+ assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyMethod_Fini(void)
+{
+ (void)PyMethod_ClearFreeList();
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/cobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/cobject.c
new file mode 100644
index 0000000000..e287444f8f
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/cobject.c
@@ -0,0 +1,172 @@
+
+/* Wrap void* pointers to be passed between C modules */
+
+#include "Python.h"
+
+
+/* Declarations for objects of type PyCObject */
+
+typedef void (*destructor1)(void *);
+typedef void (*destructor2)(void *, void*);
+
+static int cobject_deprecation_warning(void)
+{
+ return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
+ "Please use capsule objects instead.", 1);
+}
+
+
+PyObject *
+PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
+{
+ PyCObject *self;
+
+ if (cobject_deprecation_warning()) {
+ return NULL;
+ }
+
+ self = PyObject_NEW(PyCObject, &PyCObject_Type);
+ if (self == NULL)
+ return NULL;
+ self->cobject=cobj;
+ self->destructor=destr;
+ self->desc=NULL;
+
+ return (PyObject *)self;
+}
+
+PyObject *
+PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
+ void (*destr)(void *, void *))
+{
+ PyCObject *self;
+
+ if (cobject_deprecation_warning()) {
+ return NULL;
+ }
+
+ if (!desc) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyCObject_FromVoidPtrAndDesc called with null"
+ " description");
+ return NULL;
+ }
+ self = PyObject_NEW(PyCObject, &PyCObject_Type);
+ if (self == NULL)
+ return NULL;
+ self->cobject = cobj;
+ self->destructor = (destructor1)destr;
+ self->desc = desc;
+
+ return (PyObject *)self;
+}
+
+void *
+PyCObject_AsVoidPtr(PyObject *self)
+{
+ if (self) {
+ if (PyCapsule_CheckExact(self)) {
+ const char *name = PyCapsule_GetName(self);
+ return (void *)PyCapsule_GetPointer(self, name);
+ }
+ if (self->ob_type == &PyCObject_Type)
+ return ((PyCObject *)self)->cobject;
+ PyErr_SetString(PyExc_TypeError,
+ "PyCObject_AsVoidPtr with non-C-object");
+ }
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "PyCObject_AsVoidPtr called with null pointer");
+ return NULL;
+}
+
+void *
+PyCObject_GetDesc(PyObject *self)
+{
+ if (self) {
+ if (self->ob_type == &PyCObject_Type)
+ return ((PyCObject *)self)->desc;
+ PyErr_SetString(PyExc_TypeError,
+ "PyCObject_GetDesc with non-C-object");
+ }
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "PyCObject_GetDesc called with null pointer");
+ return NULL;
+}
+
+void *
+PyCObject_Import(char *module_name, char *name)
+{
+ PyObject *m, *c;
+ void *r = NULL;
+
+ if ((m = PyImport_ImportModule(module_name))) {
+ if ((c = PyObject_GetAttrString(m,name))) {
+ r = PyCObject_AsVoidPtr(c);
+ Py_DECREF(c);
+ }
+ Py_DECREF(m);
+ }
+ return r;
+}
+
+int
+PyCObject_SetVoidPtr(PyObject *self, void *cobj)
+{
+ PyCObject* cself = (PyCObject*)self;
+ if (cself == NULL || !PyCObject_Check(cself) ||
+ cself->destructor != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid call to PyCObject_SetVoidPtr");
+ return 0;
+ }
+ cself->cobject = cobj;
+ return 1;
+}
+
+static void
+PyCObject_dealloc(PyCObject *self)
+{
+ if (self->destructor) {
+ if(self->desc)
+ ((destructor2)(self->destructor))(self->cobject, self->desc);
+ else
+ (self->destructor)(self->cobject);
+ }
+ PyObject_DEL(self);
+}
+
+
+PyDoc_STRVAR(PyCObject_Type__doc__,
+"C objects to be exported from one extension module to another\n\
+\n\
+C objects are used for communication between extension modules. They\n\
+provide a way for an extension module to export a C interface to other\n\
+extension modules, so that extension modules can use the Python import\n\
+mechanism to link to one another.");
+
+PyTypeObject PyCObject_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "PyCObject", /*tp_name*/
+ sizeof(PyCObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyCObject_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ 0, /*tp_flags*/
+ PyCObject_Type__doc__ /*tp_doc*/
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/codeobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/codeobject.c
new file mode 100644
index 0000000000..a2bb1781c8
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/codeobject.c
@@ -0,0 +1,581 @@
+#include "Python.h"
+#include "code.h"
+#include "structmember.h"
+
+#define NAME_CHARS \
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+
+/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
+
+static int
+all_name_chars(unsigned char *s)
+{
+ static char ok_name_char[256];
+ static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
+
+ if (ok_name_char[*name_chars] == 0) {
+ unsigned char *p;
+ for (p = name_chars; *p; p++)
+ ok_name_char[*p] = 1;
+ }
+ while (*s) {
+ if (ok_name_char[*s++] == 0)
+ return 0;
+ }
+ return 1;
+}
+
+static void
+intern_strings(PyObject *tuple)
+{
+ Py_ssize_t i;
+
+ for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
+ PyObject *v = PyTuple_GET_ITEM(tuple, i);
+ if (v == NULL || !PyString_CheckExact(v)) {
+ Py_FatalError("non-string found in code slot");
+ }
+ PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
+ }
+}
+
+
+PyCodeObject *
+PyCode_New(int argcount, int nlocals, int stacksize, int flags,
+ PyObject *code, PyObject *consts, PyObject *names,
+ PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+ PyObject *filename, PyObject *name, int firstlineno,
+ PyObject *lnotab)
+{
+ PyCodeObject *co;
+ Py_ssize_t i;
+ /* Check argument types */
+ if (argcount < 0 || nlocals < 0 ||
+ code == NULL ||
+ consts == NULL || !PyTuple_Check(consts) ||
+ names == NULL || !PyTuple_Check(names) ||
+ varnames == NULL || !PyTuple_Check(varnames) ||
+ freevars == NULL || !PyTuple_Check(freevars) ||
+ cellvars == NULL || !PyTuple_Check(cellvars) ||
+ name == NULL || !PyString_Check(name) ||
+ filename == NULL || !PyString_Check(filename) ||
+ lnotab == NULL || !PyString_Check(lnotab) ||
+ !PyObject_CheckReadBuffer(code)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ intern_strings(names);
+ intern_strings(varnames);
+ intern_strings(freevars);
+ intern_strings(cellvars);
+ /* Intern selected string constants */
+ for (i = PyTuple_Size(consts); --i >= 0; ) {
+ PyObject *v = PyTuple_GetItem(consts, i);
+ if (!PyString_Check(v))
+ continue;
+ if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
+ continue;
+ PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
+ }
+ co = PyObject_NEW(PyCodeObject, &PyCode_Type);
+ if (co != NULL) {
+ co->co_argcount = argcount;
+ co->co_nlocals = nlocals;
+ co->co_stacksize = stacksize;
+ co->co_flags = flags;
+ Py_INCREF(code);
+ co->co_code = code;
+ Py_INCREF(consts);
+ co->co_consts = consts;
+ Py_INCREF(names);
+ co->co_names = names;
+ Py_INCREF(varnames);
+ co->co_varnames = varnames;
+ Py_INCREF(freevars);
+ co->co_freevars = freevars;
+ Py_INCREF(cellvars);
+ co->co_cellvars = cellvars;
+ Py_INCREF(filename);
+ co->co_filename = filename;
+ Py_INCREF(name);
+ co->co_name = name;
+ co->co_firstlineno = firstlineno;
+ Py_INCREF(lnotab);
+ co->co_lnotab = lnotab;
+ co->co_zombieframe = NULL;
+ co->co_weakreflist = NULL;
+ }
+ return co;
+}
+
+PyCodeObject *
+PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
+{
+ static PyObject *emptystring = NULL;
+ static PyObject *nulltuple = NULL;
+ PyObject *filename_ob = NULL;
+ PyObject *funcname_ob = NULL;
+ PyCodeObject *result = NULL;
+ if (emptystring == NULL) {
+ emptystring = PyString_FromString("");
+ if (emptystring == NULL)
+ goto failed;
+ }
+ if (nulltuple == NULL) {
+ nulltuple = PyTuple_New(0);
+ if (nulltuple == NULL)
+ goto failed;
+ }
+ funcname_ob = PyString_FromString(funcname);
+ if (funcname_ob == NULL)
+ goto failed;
+ filename_ob = PyString_FromString(filename);
+ if (filename_ob == NULL)
+ goto failed;
+
+ result = PyCode_New(0, /* argcount */
+ 0, /* nlocals */
+ 0, /* stacksize */
+ 0, /* flags */
+ emptystring, /* code */
+ nulltuple, /* consts */
+ nulltuple, /* names */
+ nulltuple, /* varnames */
+ nulltuple, /* freevars */
+ nulltuple, /* cellvars */
+ filename_ob, /* filename */
+ funcname_ob, /* name */
+ firstlineno, /* firstlineno */
+ emptystring /* lnotab */
+ );
+
+failed:
+ Py_XDECREF(funcname_ob);
+ Py_XDECREF(filename_ob);
+ return result;
+}
+
+#define OFF(x) offsetof(PyCodeObject, x)
+
+static PyMemberDef code_memberlist[] = {
+ {"co_argcount", T_INT, OFF(co_argcount), READONLY},
+ {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
+ {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
+ {"co_flags", T_INT, OFF(co_flags), READONLY},
+ {"co_code", T_OBJECT, OFF(co_code), READONLY},
+ {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
+ {"co_names", T_OBJECT, OFF(co_names), READONLY},
+ {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
+ {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
+ {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
+ {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
+ {"co_name", T_OBJECT, OFF(co_name), READONLY},
+ {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
+ {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
+ {NULL} /* Sentinel */
+};
+
+/* Helper for code_new: return a shallow copy of a tuple that is
+ guaranteed to contain exact strings, by converting string subclasses
+ to exact strings and complaining if a non-string is found. */
+static PyObject*
+validate_and_copy_tuple(PyObject *tup)
+{
+ PyObject *newtuple;
+ PyObject *item;
+ Py_ssize_t i, len;
+
+ len = PyTuple_GET_SIZE(tup);
+ newtuple = PyTuple_New(len);
+ if (newtuple == NULL)
+ return NULL;
+
+ for (i = 0; i < len; i++) {
+ item = PyTuple_GET_ITEM(tup, i);
+ if (PyString_CheckExact(item)) {
+ Py_INCREF(item);
+ }
+ else if (!PyString_Check(item)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "name tuples must contain only "
+ "strings, not '%.500s'",
+ item->ob_type->tp_name);
+ Py_DECREF(newtuple);
+ return NULL;
+ }
+ else {
+ item = PyString_FromStringAndSize(
+ PyString_AS_STRING(item),
+ PyString_GET_SIZE(item));
+ if (item == NULL) {
+ Py_DECREF(newtuple);
+ return NULL;
+ }
+ }
+ PyTuple_SET_ITEM(newtuple, i, item);
+ }
+
+ return newtuple;
+}
+
+PyDoc_STRVAR(code_doc,
+"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
+ varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
+\n\
+Create a code object. Not for the faint of heart.");
+
+static PyObject *
+code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ int argcount;
+ int nlocals;
+ int stacksize;
+ int flags;
+ PyObject *co = NULL;
+ PyObject *code;
+ PyObject *consts;
+ PyObject *names, *ournames = NULL;
+ PyObject *varnames, *ourvarnames = NULL;
+ PyObject *freevars = NULL, *ourfreevars = NULL;
+ PyObject *cellvars = NULL, *ourcellvars = NULL;
+ PyObject *filename;
+ PyObject *name;
+ int firstlineno;
+ PyObject *lnotab;
+
+ if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
+ &argcount, &nlocals, &stacksize, &flags,
+ &code,
+ &PyTuple_Type, &consts,
+ &PyTuple_Type, &names,
+ &PyTuple_Type, &varnames,
+ &filename, &name,
+ &firstlineno, &lnotab,
+ &PyTuple_Type, &freevars,
+ &PyTuple_Type, &cellvars))
+ return NULL;
+
+ if (argcount < 0) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "code: argcount must not be negative");
+ goto cleanup;
+ }
+
+ if (nlocals < 0) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "code: nlocals must not be negative");
+ goto cleanup;
+ }
+
+ ournames = validate_and_copy_tuple(names);
+ if (ournames == NULL)
+ goto cleanup;
+ ourvarnames = validate_and_copy_tuple(varnames);
+ if (ourvarnames == NULL)
+ goto cleanup;
+ if (freevars)
+ ourfreevars = validate_and_copy_tuple(freevars);
+ else
+ ourfreevars = PyTuple_New(0);
+ if (ourfreevars == NULL)
+ goto cleanup;
+ if (cellvars)
+ ourcellvars = validate_and_copy_tuple(cellvars);
+ else
+ ourcellvars = PyTuple_New(0);
+ if (ourcellvars == NULL)
+ goto cleanup;
+
+ co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
+ code, consts, ournames, ourvarnames,
+ ourfreevars, ourcellvars, filename,
+ name, firstlineno, lnotab);
+ cleanup:
+ Py_XDECREF(ournames);
+ Py_XDECREF(ourvarnames);
+ Py_XDECREF(ourfreevars);
+ Py_XDECREF(ourcellvars);
+ return co;
+}
+
+static void
+code_dealloc(PyCodeObject *co)
+{
+ Py_XDECREF(co->co_code);
+ Py_XDECREF(co->co_consts);
+ Py_XDECREF(co->co_names);
+ Py_XDECREF(co->co_varnames);
+ Py_XDECREF(co->co_freevars);
+ Py_XDECREF(co->co_cellvars);
+ Py_XDECREF(co->co_filename);
+ Py_XDECREF(co->co_name);
+ Py_XDECREF(co->co_lnotab);
+ if (co->co_zombieframe != NULL)
+ PyObject_GC_Del(co->co_zombieframe);
+ if (co->co_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject*)co);
+ PyObject_DEL(co);
+}
+
+static PyObject *
+code_repr(PyCodeObject *co)
+{
+ char buf[500];
+ int lineno = -1;
+ char *filename = "???";
+ char *name = "???";
+
+ if (co->co_firstlineno != 0)
+ lineno = co->co_firstlineno;
+ if (co->co_filename && PyString_Check(co->co_filename))
+ filename = PyString_AS_STRING(co->co_filename);
+ if (co->co_name && PyString_Check(co->co_name))
+ name = PyString_AS_STRING(co->co_name);
+ PyOS_snprintf(buf, sizeof(buf),
+ "<code object %.100s at %p, file \"%.300s\", line %d>",
+ name, co, filename, lineno);
+ return PyString_FromString(buf);
+}
+
+static int
+code_compare(PyCodeObject *co, PyCodeObject *cp)
+{
+ int cmp;
+ cmp = PyObject_Compare(co->co_name, cp->co_name);
+ if (cmp) return cmp;
+ cmp = co->co_argcount - cp->co_argcount;
+ if (cmp) goto normalize;
+ cmp = co->co_nlocals - cp->co_nlocals;
+ if (cmp) goto normalize;
+ cmp = co->co_flags - cp->co_flags;
+ if (cmp) goto normalize;
+ cmp = co->co_firstlineno - cp->co_firstlineno;
+ if (cmp) goto normalize;
+ cmp = PyObject_Compare(co->co_code, cp->co_code);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_consts, cp->co_consts);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_names, cp->co_names);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
+ return cmp;
+
+ normalize:
+ if (cmp > 0)
+ return 1;
+ else if (cmp < 0)
+ return -1;
+ else
+ return 0;
+}
+
+static PyObject *
+code_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyCodeObject *co, *cp;
+ int eq;
+ PyObject *res;
+
+ if ((op != Py_EQ && op != Py_NE) ||
+ !PyCode_Check(self) ||
+ !PyCode_Check(other)) {
+
+ /* Py3K warning if types are not equal and comparison
+ isn't == or != */
+ if (PyErr_WarnPy3k("code inequality comparisons not supported "
+ "in 3.x", 1) < 0) {
+ return NULL;
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ co = (PyCodeObject *)self;
+ cp = (PyCodeObject *)other;
+
+ eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = co->co_argcount == cp->co_argcount;
+ if (!eq) goto unequal;
+ eq = co->co_nlocals == cp->co_nlocals;
+ if (!eq) goto unequal;
+ eq = co->co_flags == cp->co_flags;
+ if (!eq) goto unequal;
+ eq = co->co_firstlineno == cp->co_firstlineno;
+ if (!eq) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
+ if (eq <= 0) goto unequal;
+ eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
+ if (eq <= 0) goto unequal;
+
+ if (op == Py_EQ)
+ res = Py_True;
+ else
+ res = Py_False;
+ goto done;
+
+ unequal:
+ if (eq < 0)
+ return NULL;
+ if (op == Py_NE)
+ res = Py_True;
+ else
+ res = Py_False;
+
+ done:
+ Py_INCREF(res);
+ return res;
+}
+
+static long
+code_hash(PyCodeObject *co)
+{
+ long h, h0, h1, h2, h3, h4, h5, h6;
+ h0 = PyObject_Hash(co->co_name);
+ if (h0 == -1) return -1;
+ h1 = PyObject_Hash(co->co_code);
+ if (h1 == -1) return -1;
+ h2 = PyObject_Hash(co->co_consts);
+ if (h2 == -1) return -1;
+ h3 = PyObject_Hash(co->co_names);
+ if (h3 == -1) return -1;
+ h4 = PyObject_Hash(co->co_varnames);
+ if (h4 == -1) return -1;
+ h5 = PyObject_Hash(co->co_freevars);
+ if (h5 == -1) return -1;
+ h6 = PyObject_Hash(co->co_cellvars);
+ if (h6 == -1) return -1;
+ h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
+ co->co_argcount ^ co->co_nlocals ^ co->co_flags;
+ if (h == -1) h = -2;
+ return h;
+}
+
+/* XXX code objects need to participate in GC? */
+
+PyTypeObject PyCode_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "code",
+ sizeof(PyCodeObject),
+ 0,
+ (destructor)code_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)code_compare, /* tp_compare */
+ (reprfunc)code_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)code_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 */
+ code_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ code_richcompare, /* tp_richcompare */
+ offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ code_memberlist, /* 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 */
+ code_new, /* tp_new */
+};
+
+/* Use co_lnotab to compute the line number from a bytecode index, addrq. See
+ lnotab_notes.txt for the details of the lnotab representation.
+*/
+
+int
+PyCode_Addr2Line(PyCodeObject *co, int addrq)
+{
+ int size = PyString_Size(co->co_lnotab) / 2;
+ unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
+ int line = co->co_firstlineno;
+ int addr = 0;
+ while (--size >= 0) {
+ addr += *p++;
+ if (addr > addrq)
+ break;
+ line += *p++;
+ }
+ return line;
+}
+
+/* Update *bounds to describe the first and one-past-the-last instructions in
+ the same line as lasti. Return the number of that line. */
+int
+_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
+{
+ int size, addr, line;
+ unsigned char* p;
+
+ p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
+ size = PyString_GET_SIZE(co->co_lnotab) / 2;
+
+ addr = 0;
+ line = co->co_firstlineno;
+ assert(line > 0);
+
+ /* possible optimization: if f->f_lasti == instr_ub
+ (likely to be a common case) then we already know
+ instr_lb -- if we stored the matching value of p
+ somwhere we could skip the first while loop. */
+
+ /* See lnotab_notes.txt for the description of
+ co_lnotab. A point to remember: increments to p
+ come in (addr, line) pairs. */
+
+ bounds->ap_lower = 0;
+ while (size > 0) {
+ if (addr + *p > lasti)
+ break;
+ addr += *p++;
+ if (*p)
+ bounds->ap_lower = addr;
+ line += *p++;
+ --size;
+ }
+
+ if (size > 0) {
+ while (--size >= 0) {
+ addr += *p++;
+ if (*p++)
+ break;
+ }
+ bounds->ap_upper = addr;
+ }
+ else {
+ bounds->ap_upper = INT_MAX;
+ }
+
+ return line;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/complexobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/complexobject.c
new file mode 100644
index 0000000000..200534c4a3
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/complexobject.c
@@ -0,0 +1,1357 @@
+
+/* Complex object implementation */
+
+/* Borrows heavily from floatobject.c */
+
+/* Submitted by Jim Hugunin */
+
+#include "Python.h"
+#include "structmember.h"
+
+#ifndef WITHOUT_COMPLEX
+
+/* Precisions used by repr() and str(), respectively.
+
+ The repr() precision (17 significant decimal digits) is the minimal number
+ that is guaranteed to have enough precision so that if the number is read
+ back in the exact same binary value is recreated. This is true for IEEE
+ floating point by design, and also happens to work for all other modern
+ hardware.
+
+ The str() precision is chosen so that in most cases, the rounding noise
+ created by various operations is suppressed, while giving plenty of
+ precision for practical use.
+*/
+
+#define PREC_REPR 17
+#define PREC_STR 12
+
+/* elementary operations on complex numbers */
+
+static Py_complex c_1 = {1., 0.};
+
+Py_complex
+c_sum(Py_complex a, Py_complex b)
+{
+ Py_complex r;
+ r.real = a.real + b.real;
+ r.imag = a.imag + b.imag;
+ return r;
+}
+
+Py_complex
+c_diff(Py_complex a, Py_complex b)
+{
+ Py_complex r;
+ r.real = a.real - b.real;
+ r.imag = a.imag - b.imag;
+ return r;
+}
+
+Py_complex
+c_neg(Py_complex a)
+{
+ Py_complex r;
+ r.real = -a.real;
+ r.imag = -a.imag;
+ return r;
+}
+
+Py_complex
+c_prod(Py_complex a, Py_complex b)
+{
+ Py_complex r;
+ r.real = a.real*b.real - a.imag*b.imag;
+ r.imag = a.real*b.imag + a.imag*b.real;
+ return r;
+}
+
+Py_complex
+c_quot(Py_complex a, Py_complex b)
+{
+ /******************************************************************
+ This was the original algorithm. It's grossly prone to spurious
+ overflow and underflow errors. It also merrily divides by 0 despite
+ checking for that(!). The code still serves a doc purpose here, as
+ the algorithm following is a simple by-cases transformation of this
+ one:
+
+ Py_complex r;
+ double d = b.real*b.real + b.imag*b.imag;
+ if (d == 0.)
+ errno = EDOM;
+ r.real = (a.real*b.real + a.imag*b.imag)/d;
+ r.imag = (a.imag*b.real - a.real*b.imag)/d;
+ return r;
+ ******************************************************************/
+
+ /* This algorithm is better, and is pretty obvious: first divide the
+ * numerators and denominator by whichever of {b.real, b.imag} has
+ * larger magnitude. The earliest reference I found was to CACM
+ * Algorithm 116 (Complex Division, Robert L. Smith, Stanford
+ * University). As usual, though, we're still ignoring all IEEE
+ * endcases.
+ */
+ Py_complex r; /* the result */
+ const double abs_breal = b.real < 0 ? -b.real : b.real;
+ const double abs_bimag = b.imag < 0 ? -b.imag : b.imag;
+
+ if (abs_breal >= abs_bimag) {
+ /* divide tops and bottom by b.real */
+ if (abs_breal == 0.0) {
+ errno = EDOM;
+ r.real = r.imag = 0.0;
+ }
+ else {
+ const double ratio = b.imag / b.real;
+ const double denom = b.real + b.imag * ratio;
+ r.real = (a.real + a.imag * ratio) / denom;
+ r.imag = (a.imag - a.real * ratio) / denom;
+ }
+ }
+ else if (abs_bimag >= abs_breal) {
+ /* divide tops and bottom by b.imag */
+ const double ratio = b.real / b.imag;
+ const double denom = b.real * ratio + b.imag;
+ assert(b.imag != 0.0);
+ r.real = (a.real * ratio + a.imag) / denom;
+ r.imag = (a.imag * ratio - a.real) / denom;
+ }
+ else {
+ /* At least one of b.real or b.imag is a NaN */
+ r.real = r.imag = Py_NAN;
+ }
+ return r;
+}
+
+Py_complex
+c_pow(Py_complex a, Py_complex b)
+{
+ Py_complex r;
+ double vabs,len,at,phase;
+ if (b.real == 0. && b.imag == 0.) {
+ r.real = 1.;
+ r.imag = 0.;
+ }
+ else if (a.real == 0. && a.imag == 0.) {
+ if (b.imag != 0. || b.real < 0.)
+ errno = EDOM;
+ r.real = 0.;
+ r.imag = 0.;
+ }
+ else {
+ vabs = hypot(a.real,a.imag);
+ len = pow(vabs,b.real);
+ at = atan2(a.imag, a.real);
+ phase = at*b.real;
+ if (b.imag != 0.0) {
+ len /= exp(at*b.imag);
+ phase += b.imag*log(vabs);
+ }
+ r.real = len*cos(phase);
+ r.imag = len*sin(phase);
+ }
+ return r;
+}
+
+static Py_complex
+c_powu(Py_complex x, long n)
+{
+ Py_complex r, p;
+ long mask = 1;
+ r = c_1;
+ p = x;
+ while (mask > 0 && n >= mask) {
+ if (n & mask)
+ r = c_prod(r,p);
+ mask <<= 1;
+ p = c_prod(p,p);
+ }
+ return r;
+}
+
+static Py_complex
+c_powi(Py_complex x, long n)
+{
+ Py_complex cn;
+
+ if (n > 100 || n < -100) {
+ cn.real = (double) n;
+ cn.imag = 0.;
+ return c_pow(x,cn);
+ }
+ else if (n > 0)
+ return c_powu(x,n);
+ else
+ return c_quot(c_1,c_powu(x,-n));
+
+}
+
+double
+c_abs(Py_complex z)
+{
+ /* sets errno = ERANGE on overflow; otherwise errno = 0 */
+ double result;
+
+ if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
+ /* C99 rules: if either the real or the imaginary part is an
+ infinity, return infinity, even if the other part is a
+ NaN. */
+ if (Py_IS_INFINITY(z.real)) {
+ result = fabs(z.real);
+ errno = 0;
+ return result;
+ }
+ if (Py_IS_INFINITY(z.imag)) {
+ result = fabs(z.imag);
+ errno = 0;
+ return result;
+ }
+ /* either the real or imaginary part is a NaN,
+ and neither is infinite. Result should be NaN. */
+ return Py_NAN;
+ }
+ result = hypot(z.real, z.imag);
+ if (!Py_IS_FINITE(result))
+ errno = ERANGE;
+ else
+ errno = 0;
+ return result;
+}
+
+static PyObject *
+complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
+{
+ PyObject *op;
+
+ op = type->tp_alloc(type, 0);
+ if (op != NULL)
+ ((PyComplexObject *)op)->cval = cval;
+ return op;
+}
+
+PyObject *
+PyComplex_FromCComplex(Py_complex cval)
+{
+ register PyComplexObject *op;
+
+ /* Inline PyObject_New */
+ op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
+ if (op == NULL)
+ return PyErr_NoMemory();
+ PyObject_INIT(op, &PyComplex_Type);
+ op->cval = cval;
+ return (PyObject *) op;
+}
+
+static PyObject *
+complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
+{
+ Py_complex c;
+ c.real = real;
+ c.imag = imag;
+ return complex_subtype_from_c_complex(type, c);
+}
+
+PyObject *
+PyComplex_FromDoubles(double real, double imag)
+{
+ Py_complex c;
+ c.real = real;
+ c.imag = imag;
+ return PyComplex_FromCComplex(c);
+}
+
+double
+PyComplex_RealAsDouble(PyObject *op)
+{
+ if (PyComplex_Check(op)) {
+ return ((PyComplexObject *)op)->cval.real;
+ }
+ else {
+ return PyFloat_AsDouble(op);
+ }
+}
+
+double
+PyComplex_ImagAsDouble(PyObject *op)
+{
+ if (PyComplex_Check(op)) {
+ return ((PyComplexObject *)op)->cval.imag;
+ }
+ else {
+ return 0.0;
+ }
+}
+
+static PyObject *
+try_complex_special_method(PyObject *op) {
+ PyObject *f;
+ static PyObject *complexstr;
+
+ if (complexstr == NULL) {
+ complexstr = PyString_InternFromString("__complex__");
+ if (complexstr == NULL)
+ return NULL;
+ }
+ if (PyInstance_Check(op)) {
+ f = PyObject_GetAttr(op, complexstr);
+ if (f == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
+ if (f == NULL && PyErr_Occurred())
+ return NULL;
+ }
+ if (f != NULL) {
+ PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
+ Py_DECREF(f);
+ return res;
+ }
+ return NULL;
+}
+
+Py_complex
+PyComplex_AsCComplex(PyObject *op)
+{
+ Py_complex cv;
+ PyObject *newop = NULL;
+
+ assert(op);
+ /* If op is already of type PyComplex_Type, return its value */
+ if (PyComplex_Check(op)) {
+ return ((PyComplexObject *)op)->cval;
+ }
+ /* If not, use op's __complex__ method, if it exists */
+
+ /* return -1 on failure */
+ cv.real = -1.;
+ cv.imag = 0.;
+
+ newop = try_complex_special_method(op);
+
+ if (newop) {
+ if (!PyComplex_Check(newop)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__complex__ should return a complex object");
+ Py_DECREF(newop);
+ return cv;
+ }
+ cv = ((PyComplexObject *)newop)->cval;
+ Py_DECREF(newop);
+ return cv;
+ }
+ else if (PyErr_Occurred()) {
+ return cv;
+ }
+ /* If neither of the above works, interpret op as a float giving the
+ real part of the result, and fill in the imaginary part as 0. */
+ else {
+ /* PyFloat_AsDouble will return -1 on failure */
+ cv.real = PyFloat_AsDouble(op);
+ return cv;
+ }
+}
+
+static void
+complex_dealloc(PyObject *op)
+{
+ op->ob_type->tp_free(op);
+}
+
+
+static PyObject *
+complex_format(PyComplexObject *v, int precision, char format_code)
+{
+ PyObject *result = NULL;
+ Py_ssize_t len;
+
+ /* If these are non-NULL, they'll need to be freed. */
+ char *pre = NULL;
+ char *im = NULL;
+ char *buf = NULL;
+
+ /* These do not need to be freed. re is either an alias
+ for pre or a pointer to a constant. lead and tail
+ are pointers to constants. */
+ char *re = NULL;
+ char *lead = "";
+ char *tail = "";
+
+ if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
+ re = "";
+ im = PyOS_double_to_string(v->cval.imag, format_code,
+ precision, 0, NULL);
+ if (!im) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ } else {
+ /* Format imaginary part with sign, real part without */
+ pre = PyOS_double_to_string(v->cval.real, format_code,
+ precision, 0, NULL);
+ if (!pre) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ re = pre;
+
+ im = PyOS_double_to_string(v->cval.imag, format_code,
+ precision, Py_DTSF_SIGN, NULL);
+ if (!im) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ lead = "(";
+ tail = ")";
+ }
+ /* Alloc the final buffer. Add one for the "j" in the format string,
+ and one for the trailing zero. */
+ len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
+ buf = PyMem_Malloc(len);
+ if (!buf) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail);
+ result = PyString_FromString(buf);
+ done:
+ PyMem_Free(im);
+ PyMem_Free(pre);
+ PyMem_Free(buf);
+
+ return result;
+}
+
+static int
+complex_print(PyComplexObject *v, FILE *fp, int flags)
+{
+ PyObject *formatv;
+ char *buf;
+ if (flags & Py_PRINT_RAW)
+ formatv = complex_format(v, PyFloat_STR_PRECISION, 'g');
+ else
+ formatv = complex_format(v, 0, 'r');
+ if (formatv == NULL)
+ return -1;
+ buf = PyString_AS_STRING(formatv);
+ Py_BEGIN_ALLOW_THREADS
+ fputs(buf, fp);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(formatv);
+ return 0;
+}
+
+static PyObject *
+complex_repr(PyComplexObject *v)
+{
+ return complex_format(v, 0, 'r');
+}
+
+static PyObject *
+complex_str(PyComplexObject *v)
+{
+ return complex_format(v, PyFloat_STR_PRECISION, 'g');
+}
+
+static long
+complex_hash(PyComplexObject *v)
+{
+ long hashreal, hashimag, combined;
+ hashreal = _Py_HashDouble(v->cval.real);
+ if (hashreal == -1)
+ return -1;
+ hashimag = _Py_HashDouble(v->cval.imag);
+ if (hashimag == -1)
+ return -1;
+ /* Note: if the imaginary part is 0, hashimag is 0 now,
+ * so the following returns hashreal unchanged. This is
+ * important because numbers of different types that
+ * compare equal must have the same hash value, so that
+ * hash(x + 0*j) must equal hash(x).
+ */
+ combined = hashreal + 1000003 * hashimag;
+ if (combined == -1)
+ combined = -2;
+ return combined;
+}
+
+/* This macro may return! */
+#define TO_COMPLEX(obj, c) \
+ if (PyComplex_Check(obj)) \
+ c = ((PyComplexObject *)(obj))->cval; \
+ else if (to_complex(&(obj), &(c)) < 0) \
+ return (obj)
+
+static int
+to_complex(PyObject **pobj, Py_complex *pc)
+{
+ PyObject *obj = *pobj;
+
+ pc->real = pc->imag = 0.0;
+ if (PyInt_Check(obj)) {
+ pc->real = PyInt_AS_LONG(obj);
+ return 0;
+ }
+ if (PyLong_Check(obj)) {
+ pc->real = PyLong_AsDouble(obj);
+ if (pc->real == -1.0 && PyErr_Occurred()) {
+ *pobj = NULL;
+ return -1;
+ }
+ return 0;
+ }
+ if (PyFloat_Check(obj)) {
+ pc->real = PyFloat_AsDouble(obj);
+ return 0;
+ }
+ Py_INCREF(Py_NotImplemented);
+ *pobj = Py_NotImplemented;
+ return -1;
+}
+
+
+static PyObject *
+complex_add(PyObject *v, PyObject *w)
+{
+ Py_complex result;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ PyFPE_START_PROTECT("complex_add", return 0)
+ result = c_sum(a, b);
+ PyFPE_END_PROTECT(result)
+ return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_sub(PyObject *v, PyObject *w)
+{
+ Py_complex result;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);;
+ PyFPE_START_PROTECT("complex_sub", return 0)
+ result = c_diff(a, b);
+ PyFPE_END_PROTECT(result)
+ return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_mul(PyObject *v, PyObject *w)
+{
+ Py_complex result;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ PyFPE_START_PROTECT("complex_mul", return 0)
+ result = c_prod(a, b);
+ PyFPE_END_PROTECT(result)
+ return PyComplex_FromCComplex(result);
+}
+
+static PyObject *
+complex_div(PyObject *v, PyObject *w)
+{
+ Py_complex quot;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ PyFPE_START_PROTECT("complex_div", return 0)
+ errno = 0;
+ quot = c_quot(a, b);
+ PyFPE_END_PROTECT(quot)
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
+ return NULL;
+ }
+ return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_classic_div(PyObject *v, PyObject *w)
+{
+ Py_complex quot;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ if (Py_DivisionWarningFlag >= 2 &&
+ PyErr_Warn(PyExc_DeprecationWarning,
+ "classic complex division") < 0)
+ return NULL;
+
+ PyFPE_START_PROTECT("complex_classic_div", return 0)
+ errno = 0;
+ quot = c_quot(a, b);
+ PyFPE_END_PROTECT(quot)
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
+ return NULL;
+ }
+ return PyComplex_FromCComplex(quot);
+}
+
+static PyObject *
+complex_remainder(PyObject *v, PyObject *w)
+{
+ Py_complex div, mod;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ if (PyErr_Warn(PyExc_DeprecationWarning,
+ "complex divmod(), // and % are deprecated") < 0)
+ return NULL;
+
+ errno = 0;
+ div = c_quot(a, b); /* The raw divisor value. */
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
+ return NULL;
+ }
+ div.real = floor(div.real); /* Use the floor of the real part. */
+ div.imag = 0.0;
+ mod = c_diff(a, c_prod(b, div));
+
+ return PyComplex_FromCComplex(mod);
+}
+
+
+static PyObject *
+complex_divmod(PyObject *v, PyObject *w)
+{
+ Py_complex div, mod;
+ PyObject *d, *m, *z;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ if (PyErr_Warn(PyExc_DeprecationWarning,
+ "complex divmod(), // and % are deprecated") < 0)
+ return NULL;
+
+ errno = 0;
+ div = c_quot(a, b); /* The raw divisor value. */
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
+ return NULL;
+ }
+ div.real = floor(div.real); /* Use the floor of the real part. */
+ div.imag = 0.0;
+ mod = c_diff(a, c_prod(b, div));
+ d = PyComplex_FromCComplex(div);
+ m = PyComplex_FromCComplex(mod);
+ z = PyTuple_Pack(2, d, m);
+ Py_XDECREF(d);
+ Py_XDECREF(m);
+ return z;
+}
+
+static PyObject *
+complex_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+ Py_complex p;
+ Py_complex exponent;
+ long int_exponent;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ if (z!=Py_None) {
+ PyErr_SetString(PyExc_ValueError, "complex modulo");
+ return NULL;
+ }
+ PyFPE_START_PROTECT("complex_pow", return 0)
+ errno = 0;
+ exponent = b;
+ int_exponent = (long)exponent.real;
+ if (exponent.imag == 0. && exponent.real == int_exponent)
+ p = c_powi(a,int_exponent);
+ else
+ p = c_pow(a,exponent);
+
+ PyFPE_END_PROTECT(p)
+ Py_ADJUST_ERANGE2(p.real, p.imag);
+ if (errno == EDOM) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "0.0 to a negative or complex power");
+ return NULL;
+ }
+ else if (errno == ERANGE) {
+ PyErr_SetString(PyExc_OverflowError,
+ "complex exponentiation");
+ return NULL;
+ }
+ return PyComplex_FromCComplex(p);
+}
+
+static PyObject *
+complex_int_div(PyObject *v, PyObject *w)
+{
+ PyObject *t, *r;
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
+ if (PyErr_Warn(PyExc_DeprecationWarning,
+ "complex divmod(), // and % are deprecated") < 0)
+ return NULL;
+
+ t = complex_divmod(v, w);
+ if (t != NULL) {
+ r = PyTuple_GET_ITEM(t, 0);
+ Py_INCREF(r);
+ Py_DECREF(t);
+ return r;
+ }
+ return NULL;
+}
+
+static PyObject *
+complex_neg(PyComplexObject *v)
+{
+ Py_complex neg;
+ neg.real = -v->cval.real;
+ neg.imag = -v->cval.imag;
+ return PyComplex_FromCComplex(neg);
+}
+
+static PyObject *
+complex_pos(PyComplexObject *v)
+{
+ if (PyComplex_CheckExact(v)) {
+ Py_INCREF(v);
+ return (PyObject *)v;
+ }
+ else
+ return PyComplex_FromCComplex(v->cval);
+}
+
+static PyObject *
+complex_abs(PyComplexObject *v)
+{
+ double result;
+
+ PyFPE_START_PROTECT("complex_abs", return 0)
+ result = c_abs(v->cval);
+ PyFPE_END_PROTECT(result)
+
+ if (errno == ERANGE) {
+ PyErr_SetString(PyExc_OverflowError,
+ "absolute value too large");
+ return NULL;
+ }
+ return PyFloat_FromDouble(result);
+}
+
+static int
+complex_nonzero(PyComplexObject *v)
+{
+ return v->cval.real != 0.0 || v->cval.imag != 0.0;
+}
+
+static int
+complex_coerce(PyObject **pv, PyObject **pw)
+{
+ Py_complex cval;
+ cval.imag = 0.;
+ if (PyInt_Check(*pw)) {
+ cval.real = (double)PyInt_AsLong(*pw);
+ *pw = PyComplex_FromCComplex(cval);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyLong_Check(*pw)) {
+ cval.real = PyLong_AsDouble(*pw);
+ if (cval.real == -1.0 && PyErr_Occurred())
+ return -1;
+ *pw = PyComplex_FromCComplex(cval);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyFloat_Check(*pw)) {
+ cval.real = PyFloat_AsDouble(*pw);
+ *pw = PyComplex_FromCComplex(cval);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyComplex_Check(*pw)) {
+ Py_INCREF(*pv);
+ Py_INCREF(*pw);
+ return 0;
+ }
+ return 1; /* Can't do it */
+}
+
+static PyObject *
+complex_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+ Py_complex i;
+ int equal;
+
+ if (op != Py_EQ && op != Py_NE) {
+ /* for backwards compatibility, comparisons with non-numbers return
+ * NotImplemented. Only comparisons with core numeric types raise
+ * TypeError.
+ */
+ if (PyInt_Check(w) || PyLong_Check(w) ||
+ PyFloat_Check(w) || PyComplex_Check(w)) {
+ PyErr_SetString(PyExc_TypeError,
+ "no ordering relation is defined "
+ "for complex numbers");
+ return NULL;
+ }
+ goto Unimplemented;
+ }
+
+ assert(PyComplex_Check(v));
+ TO_COMPLEX(v, i);
+
+ if (PyInt_Check(w) || PyLong_Check(w)) {
+ /* Check for 0.0 imaginary part first to avoid the rich
+ * comparison when possible.
+ */
+ if (i.imag == 0.0) {
+ PyObject *j, *sub_res;
+ j = PyFloat_FromDouble(i.real);
+ if (j == NULL)
+ return NULL;
+
+ sub_res = PyObject_RichCompare(j, w, op);
+ Py_DECREF(j);
+ return sub_res;
+ }
+ else {
+ equal = 0;
+ }
+ }
+ else if (PyFloat_Check(w)) {
+ equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0);
+ }
+ else if (PyComplex_Check(w)) {
+ Py_complex j;
+
+ TO_COMPLEX(w, j);
+ equal = (i.real == j.real && i.imag == j.imag);
+ }
+ else {
+ goto Unimplemented;
+ }
+
+ if (equal == (op == Py_EQ))
+ res = Py_True;
+ else
+ res = Py_False;
+
+ Py_INCREF(res);
+ return res;
+
+ Unimplemented:
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *
+complex_int(PyObject *v)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "can't convert complex to int");
+ return NULL;
+}
+
+static PyObject *
+complex_long(PyObject *v)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "can't convert complex to long");
+ return NULL;
+}
+
+static PyObject *
+complex_float(PyObject *v)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "can't convert complex to float");
+ return NULL;
+}
+
+static PyObject *
+complex_conjugate(PyObject *self)
+{
+ Py_complex c;
+ c = ((PyComplexObject *)self)->cval;
+ c.imag = -c.imag;
+ return PyComplex_FromCComplex(c);
+}
+
+PyDoc_STRVAR(complex_conjugate_doc,
+"complex.conjugate() -> complex\n"
+"\n"
+"Return the complex conjugate of its argument. (3-4j).conjugate() == 3+4j.");
+
+static PyObject *
+complex_getnewargs(PyComplexObject *v)
+{
+ Py_complex c = v->cval;
+ return Py_BuildValue("(dd)", c.real, c.imag);
+}
+
+PyDoc_STRVAR(complex__format__doc,
+"complex.__format__() -> str\n"
+"\n"
+"Convert to a string according to format_spec.");
+
+static PyObject *
+complex__format__(PyObject* self, PyObject* args)
+{
+ PyObject *format_spec;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+ if (PyBytes_Check(format_spec))
+ return _PyComplex_FormatAdvanced(self,
+ PyBytes_AS_STRING(format_spec),
+ PyBytes_GET_SIZE(format_spec));
+ if (PyUnicode_Check(format_spec)) {
+ /* Convert format_spec to a str */
+ PyObject *result;
+ PyObject *str_spec = PyObject_Str(format_spec);
+
+ if (str_spec == NULL)
+ return NULL;
+
+ result = _PyComplex_FormatAdvanced(self,
+ PyBytes_AS_STRING(str_spec),
+ PyBytes_GET_SIZE(str_spec));
+
+ Py_DECREF(str_spec);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+ return NULL;
+}
+
+#if 0
+static PyObject *
+complex_is_finite(PyObject *self)
+{
+ Py_complex c;
+ c = ((PyComplexObject *)self)->cval;
+ return PyBool_FromLong((long)(Py_IS_FINITE(c.real) &&
+ Py_IS_FINITE(c.imag)));
+}
+
+PyDoc_STRVAR(complex_is_finite_doc,
+"complex.is_finite() -> bool\n"
+"\n"
+"Returns True if the real and the imaginary part is finite.");
+#endif
+
+static PyMethodDef complex_methods[] = {
+ {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS,
+ complex_conjugate_doc},
+#if 0
+ {"is_finite", (PyCFunction)complex_is_finite, METH_NOARGS,
+ complex_is_finite_doc},
+#endif
+ {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS},
+ {"__format__", (PyCFunction)complex__format__,
+ METH_VARARGS, complex__format__doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMemberDef complex_members[] = {
+ {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), READONLY,
+ "the real part of a complex number"},
+ {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), READONLY,
+ "the imaginary part of a complex number"},
+ {0},
+};
+
+static PyObject *
+complex_subtype_from_string(PyTypeObject *type, PyObject *v)
+{
+ const char *s, *start;
+ char *end;
+ double x=0.0, y=0.0, z;
+ int got_bracket=0;
+#ifdef Py_USING_UNICODE
+ char *s_buffer = NULL;
+#endif
+ Py_ssize_t len;
+
+ if (PyString_Check(v)) {
+ s = PyString_AS_STRING(v);
+ len = PyString_GET_SIZE(v);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(v)) {
+ s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+ if (s_buffer == NULL)
+ return PyErr_NoMemory();
+ if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+ PyUnicode_GET_SIZE(v),
+ s_buffer,
+ NULL))
+ goto error;
+ s = s_buffer;
+ len = strlen(s);
+ }
+#endif
+ else if (PyObject_AsCharBuffer(v, &s, &len)) {
+ PyErr_SetString(PyExc_TypeError,
+ "complex() arg is not a string");
+ return NULL;
+ }
+
+ /* position on first nonblank */
+ start = s;
+ while (Py_ISSPACE(*s))
+ s++;
+ if (*s == '(') {
+ /* Skip over possible bracket from repr(). */
+ got_bracket = 1;
+ s++;
+ while (Py_ISSPACE(*s))
+ s++;
+ }
+
+ /* a valid complex string usually takes one of the three forms:
+
+ <float> - real part only
+ <float>j - imaginary part only
+ <float><signed-float>j - real and imaginary parts
+
+ where <float> represents any numeric string that's accepted by the
+ float constructor (including 'nan', 'inf', 'infinity', etc.), and
+ <signed-float> is any string of the form <float> whose first
+ character is '+' or '-'.
+
+ For backwards compatibility, the extra forms
+
+ <float><sign>j
+ <sign>j
+ j
+
+ are also accepted, though support for these forms may be removed from
+ a future version of Python.
+ */
+
+ /* first look for forms starting with <float> */
+ z = PyOS_string_to_double(s, &end, NULL);
+ if (z == -1.0 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_ValueError))
+ PyErr_Clear();
+ else
+ goto error;
+ }
+ if (end != s) {
+ /* all 4 forms starting with <float> land here */
+ s = end;
+ if (*s == '+' || *s == '-') {
+ /* <float><signed-float>j | <float><sign>j */
+ x = z;
+ y = PyOS_string_to_double(s, &end, NULL);
+ if (y == -1.0 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_ValueError))
+ PyErr_Clear();
+ else
+ goto error;
+ }
+ if (end != s)
+ /* <float><signed-float>j */
+ s = end;
+ else {
+ /* <float><sign>j */
+ y = *s == '+' ? 1.0 : -1.0;
+ s++;
+ }
+ if (!(*s == 'j' || *s == 'J'))
+ goto parse_error;
+ s++;
+ }
+ else if (*s == 'j' || *s == 'J') {
+ /* <float>j */
+ s++;
+ y = z;
+ }
+ else
+ /* <float> */
+ x = z;
+ }
+ else {
+ /* not starting with <float>; must be <sign>j or j */
+ if (*s == '+' || *s == '-') {
+ /* <sign>j */
+ y = *s == '+' ? 1.0 : -1.0;
+ s++;
+ }
+ else
+ /* j */
+ y = 1.0;
+ if (!(*s == 'j' || *s == 'J'))
+ goto parse_error;
+ s++;
+ }
+
+ /* trailing whitespace and closing bracket */
+ while (Py_ISSPACE(*s))
+ s++;
+ if (got_bracket) {
+ /* if there was an opening parenthesis, then the corresponding
+ closing parenthesis should be right here */
+ if (*s != ')')
+ goto parse_error;
+ s++;
+ while (Py_ISSPACE(*s))
+ s++;
+ }
+
+ /* we should now be at the end of the string */
+ if (s-start != len)
+ goto parse_error;
+
+
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return complex_subtype_from_doubles(type, x, y);
+
+ parse_error:
+ PyErr_SetString(PyExc_ValueError,
+ "complex() arg is a malformed string");
+ error:
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return NULL;
+}
+
+static PyObject *
+complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *r, *i, *tmp;
+ PyNumberMethods *nbr, *nbi = NULL;
+ Py_complex cr, ci;
+ int own_r = 0;
+ int cr_is_complex = 0;
+ int ci_is_complex = 0;
+ static char *kwlist[] = {"real", "imag", 0};
+
+ r = Py_False;
+ i = NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist,
+ &r, &i))
+ return NULL;
+
+ /* Special-case for a single argument when type(arg) is complex. */
+ if (PyComplex_CheckExact(r) && i == NULL &&
+ type == &PyComplex_Type) {
+ /* Note that we can't know whether it's safe to return
+ a complex *subclass* instance as-is, hence the restriction
+ to exact complexes here. If either the input or the
+ output is a complex subclass, it will be handled below
+ as a non-orthogonal vector. */
+ Py_INCREF(r);
+ return r;
+ }
+ if (PyString_Check(r) || PyUnicode_Check(r)) {
+ if (i != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "complex() can't take second arg"
+ " if first is a string");
+ return NULL;
+ }
+ return complex_subtype_from_string(type, r);
+ }
+ if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) {
+ PyErr_SetString(PyExc_TypeError,
+ "complex() second arg can't be a string");
+ return NULL;
+ }
+
+ tmp = try_complex_special_method(r);
+ if (tmp) {
+ r = tmp;
+ own_r = 1;
+ }
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
+
+ nbr = r->ob_type->tp_as_number;
+ if (i != NULL)
+ nbi = i->ob_type->tp_as_number;
+ if (nbr == NULL || nbr->nb_float == NULL ||
+ ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) {
+ PyErr_SetString(PyExc_TypeError,
+ "complex() argument must be a string or a number");
+ if (own_r) {
+ Py_DECREF(r);
+ }
+ return NULL;
+ }
+
+ /* If we get this far, then the "real" and "imag" parts should
+ both be treated as numbers, and the constructor should return a
+ complex number equal to (real + imag*1j).
+
+ Note that we do NOT assume the input to already be in canonical
+ form; the "real" and "imag" parts might themselves be complex
+ numbers, which slightly complicates the code below. */
+ if (PyComplex_Check(r)) {
+ /* Note that if r is of a complex subtype, we're only
+ retaining its real & imag parts here, and the return
+ value is (properly) of the builtin complex type. */
+ cr = ((PyComplexObject*)r)->cval;
+ cr_is_complex = 1;
+ if (own_r) {
+ Py_DECREF(r);
+ }
+ }
+ else {
+ /* The "real" part really is entirely real, and contributes
+ nothing in the imaginary direction.
+ Just treat it as a double. */
+ tmp = PyNumber_Float(r);
+ if (own_r) {
+ /* r was a newly created complex number, rather
+ than the original "real" argument. */
+ Py_DECREF(r);
+ }
+ if (tmp == NULL)
+ return NULL;
+ if (!PyFloat_Check(tmp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "float(r) didn't return a float");
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ cr.real = PyFloat_AsDouble(tmp);
+ cr.imag = 0.0; /* Shut up compiler warning */
+ Py_DECREF(tmp);
+ }
+ if (i == NULL) {
+ ci.real = 0.0;
+ }
+ else if (PyComplex_Check(i)) {
+ ci = ((PyComplexObject*)i)->cval;
+ ci_is_complex = 1;
+ } else {
+ /* The "imag" part really is entirely imaginary, and
+ contributes nothing in the real direction.
+ Just treat it as a double. */
+ tmp = (*nbi->nb_float)(i);
+ if (tmp == NULL)
+ return NULL;
+ ci.real = PyFloat_AsDouble(tmp);
+ Py_DECREF(tmp);
+ }
+ /* If the input was in canonical form, then the "real" and "imag"
+ parts are real numbers, so that ci.imag and cr.imag are zero.
+ We need this correction in case they were not real numbers. */
+
+ if (ci_is_complex) {
+ cr.real -= ci.imag;
+ }
+ if (cr_is_complex) {
+ ci.real += cr.imag;
+ }
+ return complex_subtype_from_doubles(type, cr.real, ci.real);
+}
+
+PyDoc_STRVAR(complex_doc,
+"complex(real[, imag]) -> complex number\n"
+"\n"
+"Create a complex number from a real part and an optional imaginary part.\n"
+"This is equivalent to (real + imag*1j) where imag defaults to 0.");
+
+static PyNumberMethods complex_as_number = {
+ (binaryfunc)complex_add, /* nb_add */
+ (binaryfunc)complex_sub, /* nb_subtract */
+ (binaryfunc)complex_mul, /* nb_multiply */
+ (binaryfunc)complex_classic_div, /* nb_divide */
+ (binaryfunc)complex_remainder, /* nb_remainder */
+ (binaryfunc)complex_divmod, /* nb_divmod */
+ (ternaryfunc)complex_pow, /* nb_power */
+ (unaryfunc)complex_neg, /* nb_negative */
+ (unaryfunc)complex_pos, /* nb_positive */
+ (unaryfunc)complex_abs, /* nb_absolute */
+ (inquiry)complex_nonzero, /* nb_nonzero */
+ 0, /* nb_invert */
+ 0, /* nb_lshift */
+ 0, /* nb_rshift */
+ 0, /* nb_and */
+ 0, /* nb_xor */
+ 0, /* nb_or */
+ complex_coerce, /* nb_coerce */
+ complex_int, /* nb_int */
+ complex_long, /* nb_long */
+ complex_float, /* nb_float */
+ 0, /* nb_oct */
+ 0, /* nb_hex */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply*/
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ (binaryfunc)complex_int_div, /* nb_floor_divide */
+ (binaryfunc)complex_div, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+};
+
+PyTypeObject PyComplex_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "complex",
+ sizeof(PyComplexObject),
+ 0,
+ complex_dealloc, /* tp_dealloc */
+ (printfunc)complex_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)complex_repr, /* tp_repr */
+ &complex_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)complex_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)complex_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ complex_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ complex_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ complex_methods, /* tp_methods */
+ complex_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 */
+ PyType_GenericAlloc, /* tp_alloc */
+ complex_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/descrobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/descrobject.c
new file mode 100644
index 0000000000..62daf49ed5
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/descrobject.c
@@ -0,0 +1,1440 @@
+/* Descriptors -- a new, flexible way to describe attributes */
+
+#include "Python.h"
+#include "structmember.h" /* Why is this not included in Python.h? */
+
+static void
+descr_dealloc(PyDescrObject *descr)
+{
+ _PyObject_GC_UNTRACK(descr);
+ Py_XDECREF(descr->d_type);
+ Py_XDECREF(descr->d_name);
+ PyObject_GC_Del(descr);
+}
+
+static char *
+descr_name(PyDescrObject *descr)
+{
+ if (descr->d_name != NULL && PyString_Check(descr->d_name))
+ return PyString_AS_STRING(descr->d_name);
+ else
+ return "?";
+}
+
+static PyObject *
+descr_repr(PyDescrObject *descr, char *format)
+{
+ return PyString_FromFormat(format, descr_name(descr),
+ descr->d_type->tp_name);
+}
+
+static PyObject *
+method_repr(PyMethodDescrObject *descr)
+{
+ return descr_repr((PyDescrObject *)descr,
+ "<method '%s' of '%s' objects>");
+}
+
+static PyObject *
+member_repr(PyMemberDescrObject *descr)
+{
+ return descr_repr((PyDescrObject *)descr,
+ "<member '%s' of '%s' objects>");
+}
+
+static PyObject *
+getset_repr(PyGetSetDescrObject *descr)
+{
+ return descr_repr((PyDescrObject *)descr,
+ "<attribute '%s' of '%s' objects>");
+}
+
+static PyObject *
+wrapperdescr_repr(PyWrapperDescrObject *descr)
+{
+ return descr_repr((PyDescrObject *)descr,
+ "<slot wrapper '%s' of '%s' objects>");
+}
+
+static int
+descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
+{
+ if (obj == NULL) {
+ Py_INCREF(descr);
+ *pres = (PyObject *)descr;
+ return 1;
+ }
+ if (!PyObject_TypeCheck(obj, descr->d_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' for '%s' objects "
+ "doesn't apply to '%s' object",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ obj->ob_type->tp_name);
+ *pres = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+static PyObject *
+classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+ /* Ensure a valid type. Class methods ignore obj. */
+ if (type == NULL) {
+ if (obj != NULL)
+ type = (PyObject *)obj->ob_type;
+ else {
+ /* Wot - no type?! */
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' for type '%s' "
+ "needs either an object or a type",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return NULL;
+ }
+ }
+ if (!PyType_Check(type)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' for type '%s' "
+ "needs a type, not a '%s' as arg 2",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ type->ob_type->tp_name);
+ return NULL;
+ }
+ if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' for type '%s' "
+ "doesn't apply to type '%s'",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ ((PyTypeObject *)type)->tp_name);
+ return NULL;
+ }
+ return PyCFunction_New(descr->d_method, type);
+}
+
+static PyObject *
+method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
+{
+ PyObject *res;
+
+ if (descr_check((PyDescrObject *)descr, obj, &res))
+ return res;
+ return PyCFunction_New(descr->d_method, obj);
+}
+
+static PyObject *
+member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
+{
+ PyObject *res;
+
+ if (descr_check((PyDescrObject *)descr, obj, &res))
+ return res;
+ return PyMember_GetOne((char *)obj, descr->d_member);
+}
+
+static PyObject *
+getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
+{
+ PyObject *res;
+
+ if (descr_check((PyDescrObject *)descr, obj, &res))
+ return res;
+ if (descr->d_getset->get != NULL)
+ return descr->d_getset->get(obj, descr->d_getset->closure);
+ PyErr_Format(PyExc_AttributeError,
+ "attribute '%.300s' of '%.100s' objects is not readable",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return NULL;
+}
+
+static PyObject *
+wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
+{
+ PyObject *res;
+
+ if (descr_check((PyDescrObject *)descr, obj, &res))
+ return res;
+ return PyWrapper_New((PyObject *)descr, obj);
+}
+
+static int
+descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
+ int *pres)
+{
+ assert(obj != NULL);
+ if (!PyObject_TypeCheck(obj, descr->d_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%.200s' for '%.100s' objects "
+ "doesn't apply to '%.100s' object",
+ descr_name(descr),
+ descr->d_type->tp_name,
+ obj->ob_type->tp_name);
+ *pres = -1;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
+{
+ int res;
+
+ if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+ return res;
+ return PyMember_SetOne((char *)obj, descr->d_member, value);
+}
+
+static int
+getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
+{
+ int res;
+
+ if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
+ return res;
+ if (descr->d_getset->set != NULL)
+ return descr->d_getset->set(obj, value,
+ descr->d_getset->closure);
+ PyErr_Format(PyExc_AttributeError,
+ "attribute '%.300s' of '%.100s' objects is not writable",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return -1;
+}
+
+static PyObject *
+methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t argc;
+ PyObject *self, *func, *result;
+
+ /* Make sure that the first argument is acceptable as 'self' */
+ assert(PyTuple_Check(args));
+ argc = PyTuple_GET_SIZE(args);
+ if (argc < 1) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%.300s' of '%.100s' "
+ "object needs an argument",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return NULL;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type))) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%.200s' "
+ "requires a '%.100s' object "
+ "but received a '%.100s'",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ self->ob_type->tp_name);
+ return NULL;
+ }
+
+ func = PyCFunction_New(descr->d_method, self);
+ if (func == NULL)
+ return NULL;
+ args = PyTuple_GetSlice(args, 1, argc);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ Py_DECREF(args);
+ Py_DECREF(func);
+ return result;
+}
+
+static PyObject *
+classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
+ PyObject *kwds)
+{
+ Py_ssize_t argc;
+ PyObject *self, *func, *result;
+
+ /* Make sure that the first argument is acceptable as 'self' */
+ assert(PyTuple_Check(args));
+ argc = PyTuple_GET_SIZE(args);
+ if (argc < 1) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' of '%.100s' "
+ "object needs an argument",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return NULL;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ if (!PyType_Check(self)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' requires a type "
+ "but received a '%.100s'",
+ descr_name((PyDescrObject *)descr),
+ self->ob_type->tp_name);
+ return NULL;
+ }
+ if (!PyType_IsSubtype((PyTypeObject *)self, descr->d_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%s' "
+ "requires a subtype of '%.100s' "
+ "but received '%.100s",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ self->ob_type->tp_name);
+ return NULL;
+ }
+
+ func = PyCFunction_New(descr->d_method, self);
+ if (func == NULL)
+ return NULL;
+ args = PyTuple_GetSlice(args, 1, argc);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ Py_DECREF(func);
+ Py_DECREF(args);
+ return result;
+}
+
+static PyObject *
+wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t argc;
+ PyObject *self, *func, *result;
+
+ /* Make sure that the first argument is acceptable as 'self' */
+ assert(PyTuple_Check(args));
+ argc = PyTuple_GET_SIZE(args);
+ if (argc < 1) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%.300s' of '%.100s' "
+ "object needs an argument",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name);
+ return NULL;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type))) {
+ PyErr_Format(PyExc_TypeError,
+ "descriptor '%.200s' "
+ "requires a '%.100s' object "
+ "but received a '%.100s'",
+ descr_name((PyDescrObject *)descr),
+ descr->d_type->tp_name,
+ self->ob_type->tp_name);
+ return NULL;
+ }
+
+ func = PyWrapper_New((PyObject *)descr, self);
+ if (func == NULL)
+ return NULL;
+ args = PyTuple_GetSlice(args, 1, argc);
+ if (args == NULL) {
+ Py_DECREF(func);
+ return NULL;
+ }
+ result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ Py_DECREF(args);
+ Py_DECREF(func);
+ return result;
+}
+
+static PyObject *
+method_get_doc(PyMethodDescrObject *descr, void *closure)
+{
+ if (descr->d_method->ml_doc == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(descr->d_method->ml_doc);
+}
+
+static PyMemberDef descr_members[] = {
+ {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY},
+ {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY},
+ {0}
+};
+
+static PyGetSetDef method_getset[] = {
+ {"__doc__", (getter)method_get_doc},
+ {0}
+};
+
+static PyObject *
+member_get_doc(PyMemberDescrObject *descr, void *closure)
+{
+ if (descr->d_member->doc == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(descr->d_member->doc);
+}
+
+static PyGetSetDef member_getset[] = {
+ {"__doc__", (getter)member_get_doc},
+ {0}
+};
+
+static PyObject *
+getset_get_doc(PyGetSetDescrObject *descr, void *closure)
+{
+ if (descr->d_getset->doc == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(descr->d_getset->doc);
+}
+
+static PyGetSetDef getset_getset[] = {
+ {"__doc__", (getter)getset_get_doc},
+ {0}
+};
+
+static PyObject *
+wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
+{
+ if (descr->d_base->doc == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyString_FromString(descr->d_base->doc);
+}
+
+static PyGetSetDef wrapperdescr_getset[] = {
+ {"__doc__", (getter)wrapperdescr_get_doc},
+ {0}
+};
+
+static int
+descr_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ PyDescrObject *descr = (PyDescrObject *)self;
+ Py_VISIT(descr->d_type);
+ return 0;
+}
+
+static PyTypeObject PyMethodDescr_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "method_descriptor",
+ sizeof(PyMethodDescrObject),
+ 0,
+ (destructor)descr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)method_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)methoddescr_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ descr_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ descr_members, /* tp_members */
+ method_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)method_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+/* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
+static PyTypeObject PyClassMethodDescr_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "classmethod_descriptor",
+ sizeof(PyMethodDescrObject),
+ 0,
+ (destructor)descr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)method_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)classmethoddescr_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ descr_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ descr_members, /* tp_members */
+ method_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)classmethod_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+PyTypeObject PyMemberDescr_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "member_descriptor",
+ sizeof(PyMemberDescrObject),
+ 0,
+ (destructor)descr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)member_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 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ descr_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ descr_members, /* tp_members */
+ member_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)member_get, /* tp_descr_get */
+ (descrsetfunc)member_set, /* tp_descr_set */
+};
+
+PyTypeObject PyGetSetDescr_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "getset_descriptor",
+ sizeof(PyGetSetDescrObject),
+ 0,
+ (destructor)descr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)getset_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 | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ descr_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ descr_members, /* tp_members */
+ getset_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)getset_get, /* tp_descr_get */
+ (descrsetfunc)getset_set, /* tp_descr_set */
+};
+
+PyTypeObject PyWrapperDescr_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "wrapper_descriptor",
+ sizeof(PyWrapperDescrObject),
+ 0,
+ (destructor)descr_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)wrapperdescr_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)wrapperdescr_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ descr_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ descr_members, /* tp_members */
+ wrapperdescr_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+static PyDescrObject *
+descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
+{
+ PyDescrObject *descr;
+
+ descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
+ if (descr != NULL) {
+ Py_XINCREF(type);
+ descr->d_type = type;
+ descr->d_name = PyString_InternFromString(name);
+ if (descr->d_name == NULL) {
+ Py_DECREF(descr);
+ descr = NULL;
+ }
+ }
+ return descr;
+}
+
+PyObject *
+PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
+{
+ PyMethodDescrObject *descr;
+
+ descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
+ type, method->ml_name);
+ if (descr != NULL)
+ descr->d_method = method;
+ return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
+{
+ PyMethodDescrObject *descr;
+
+ descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
+ type, method->ml_name);
+ if (descr != NULL)
+ descr->d_method = method;
+ return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
+{
+ PyMemberDescrObject *descr;
+
+ descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type,
+ type, member->name);
+ if (descr != NULL)
+ descr->d_member = member;
+ return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
+{
+ PyGetSetDescrObject *descr;
+
+ descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
+ type, getset->name);
+ if (descr != NULL)
+ descr->d_getset = getset;
+ return (PyObject *)descr;
+}
+
+PyObject *
+PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
+{
+ PyWrapperDescrObject *descr;
+
+ descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
+ type, base->name);
+ if (descr != NULL) {
+ descr->d_base = base;
+ descr->d_wrapped = wrapped;
+ }
+ return (PyObject *)descr;
+}
+
+
+/* --- Readonly proxy for dictionaries (actually any mapping) --- */
+
+/* This has no reason to be in this file except that adding new files is a
+ bit of a pain */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *dict;
+} proxyobject;
+
+static Py_ssize_t
+proxy_len(proxyobject *pp)
+{
+ return PyObject_Size(pp->dict);
+}
+
+static PyObject *
+proxy_getitem(proxyobject *pp, PyObject *key)
+{
+ return PyObject_GetItem(pp->dict, key);
+}
+
+static PyMappingMethods proxy_as_mapping = {
+ (lenfunc)proxy_len, /* mp_length */
+ (binaryfunc)proxy_getitem, /* mp_subscript */
+ 0, /* mp_ass_subscript */
+};
+
+static int
+proxy_contains(proxyobject *pp, PyObject *key)
+{
+ return PyDict_Contains(pp->dict, key);
+}
+
+static PySequenceMethods proxy_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)proxy_contains, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+static PyObject *
+proxy_has_key(proxyobject *pp, PyObject *key)
+{
+ int res = PyDict_Contains(pp->dict, key);
+ if (res < 0)
+ return NULL;
+ return PyBool_FromLong(res);
+}
+
+static PyObject *
+proxy_get(proxyobject *pp, PyObject *args)
+{
+ PyObject *key, *def = Py_None;
+
+ if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
+ return NULL;
+ return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
+}
+
+static PyObject *
+proxy_keys(proxyobject *pp)
+{
+ return PyMapping_Keys(pp->dict);
+}
+
+static PyObject *
+proxy_values(proxyobject *pp)
+{
+ return PyMapping_Values(pp->dict);
+}
+
+static PyObject *
+proxy_items(proxyobject *pp)
+{
+ return PyMapping_Items(pp->dict);
+}
+
+static PyObject *
+proxy_iterkeys(proxyobject *pp)
+{
+ return PyObject_CallMethod(pp->dict, "iterkeys", NULL);
+}
+
+static PyObject *
+proxy_itervalues(proxyobject *pp)
+{
+ return PyObject_CallMethod(pp->dict, "itervalues", NULL);
+}
+
+static PyObject *
+proxy_iteritems(proxyobject *pp)
+{
+ return PyObject_CallMethod(pp->dict, "iteritems", NULL);
+}
+static PyObject *
+proxy_copy(proxyobject *pp)
+{
+ return PyObject_CallMethod(pp->dict, "copy", NULL);
+}
+
+static PyMethodDef proxy_methods[] = {
+ {"has_key", (PyCFunction)proxy_has_key, METH_O,
+ PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")},
+ {"get", (PyCFunction)proxy_get, METH_VARARGS,
+ PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d."
+ " d defaults to None.")},
+ {"keys", (PyCFunction)proxy_keys, METH_NOARGS,
+ PyDoc_STR("D.keys() -> list of D's keys")},
+ {"values", (PyCFunction)proxy_values, METH_NOARGS,
+ PyDoc_STR("D.values() -> list of D's values")},
+ {"items", (PyCFunction)proxy_items, METH_NOARGS,
+ PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")},
+ {"iterkeys", (PyCFunction)proxy_iterkeys, METH_NOARGS,
+ PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")},
+ {"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS,
+ PyDoc_STR("D.itervalues() -> an iterator over the values of D")},
+ {"iteritems", (PyCFunction)proxy_iteritems, METH_NOARGS,
+ PyDoc_STR("D.iteritems() ->"
+ " an iterator over the (key, value) items of D")},
+ {"copy", (PyCFunction)proxy_copy, METH_NOARGS,
+ PyDoc_STR("D.copy() -> a shallow copy of D")},
+ {0}
+};
+
+static void
+proxy_dealloc(proxyobject *pp)
+{
+ _PyObject_GC_UNTRACK(pp);
+ Py_DECREF(pp->dict);
+ PyObject_GC_Del(pp);
+}
+
+static PyObject *
+proxy_getiter(proxyobject *pp)
+{
+ return PyObject_GetIter(pp->dict);
+}
+
+static PyObject *
+proxy_str(proxyobject *pp)
+{
+ return PyObject_Str(pp->dict);
+}
+
+static PyObject *
+proxy_repr(proxyobject *pp)
+{
+ PyObject *dictrepr;
+ PyObject *result;
+
+ dictrepr = PyObject_Repr(pp->dict);
+ if (dictrepr == NULL)
+ return NULL;
+ result = PyString_FromFormat("dict_proxy(%s)", PyString_AS_STRING(dictrepr));
+ Py_DECREF(dictrepr);
+ return result;
+}
+
+static int
+proxy_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ proxyobject *pp = (proxyobject *)self;
+ Py_VISIT(pp->dict);
+ return 0;
+}
+
+static int
+proxy_compare(proxyobject *v, PyObject *w)
+{
+ return PyObject_Compare(v->dict, w);
+}
+
+static PyObject *
+proxy_richcompare(proxyobject *v, PyObject *w, int op)
+{
+ return PyObject_RichCompare(v->dict, w, op);
+}
+
+PyTypeObject PyDictProxy_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dictproxy", /* tp_name */
+ sizeof(proxyobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)proxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)proxy_compare, /* tp_compare */
+ (reprfunc)proxy_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &proxy_as_sequence, /* tp_as_sequence */
+ &proxy_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)proxy_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ proxy_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)proxy_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)proxy_getiter, /* tp_iter */
+ 0, /* tp_iternext */
+ proxy_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+PyObject *
+PyDictProxy_New(PyObject *dict)
+{
+ proxyobject *pp;
+
+ pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type);
+ if (pp != NULL) {
+ Py_INCREF(dict);
+ pp->dict = dict;
+ _PyObject_GC_TRACK(pp);
+ }
+ return (PyObject *)pp;
+}
+
+
+/* --- Wrapper object for "slot" methods --- */
+
+/* This has no reason to be in this file except that adding new files is a
+ bit of a pain */
+
+typedef struct {
+ PyObject_HEAD
+ PyWrapperDescrObject *descr;
+ PyObject *self;
+} wrapperobject;
+
+static void
+wrapper_dealloc(wrapperobject *wp)
+{
+ PyObject_GC_UnTrack(wp);
+ Py_TRASHCAN_SAFE_BEGIN(wp)
+ Py_XDECREF(wp->descr);
+ Py_XDECREF(wp->self);
+ PyObject_GC_Del(wp);
+ Py_TRASHCAN_SAFE_END(wp)
+}
+
+static int
+wrapper_compare(wrapperobject *a, wrapperobject *b)
+{
+ if (a->descr == b->descr)
+ return PyObject_Compare(a->self, b->self);
+ else
+ return (a->descr < b->descr) ? -1 : 1;
+}
+
+static long
+wrapper_hash(wrapperobject *wp)
+{
+ int x, y;
+ x = _Py_HashPointer(wp->descr);
+ if (x == -1)
+ return -1;
+ y = PyObject_Hash(wp->self);
+ if (y == -1)
+ return -1;
+ x = x ^ y;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+static PyObject *
+wrapper_repr(wrapperobject *wp)
+{
+ return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>",
+ wp->descr->d_base->name,
+ wp->self->ob_type->tp_name,
+ wp->self);
+}
+
+static PyMemberDef wrapper_members[] = {
+ {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY},
+ {0}
+};
+
+static PyObject *
+wrapper_objclass(wrapperobject *wp)
+{
+ PyObject *c = (PyObject *)wp->descr->d_type;
+
+ Py_INCREF(c);
+ return c;
+}
+
+static PyObject *
+wrapper_name(wrapperobject *wp)
+{
+ char *s = wp->descr->d_base->name;
+
+ return PyString_FromString(s);
+}
+
+static PyObject *
+wrapper_doc(wrapperobject *wp)
+{
+ char *s = wp->descr->d_base->doc;
+
+ if (s == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else {
+ return PyString_FromString(s);
+ }
+}
+
+static PyGetSetDef wrapper_getsets[] = {
+ {"__objclass__", (getter)wrapper_objclass},
+ {"__name__", (getter)wrapper_name},
+ {"__doc__", (getter)wrapper_doc},
+ {0}
+};
+
+static PyObject *
+wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
+{
+ wrapperfunc wrapper = wp->descr->d_base->wrapper;
+ PyObject *self = wp->self;
+
+ if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
+ wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
+ return (*wk)(self, args, wp->descr->d_wrapped, kwds);
+ }
+
+ if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) {
+ PyErr_Format(PyExc_TypeError,
+ "wrapper %s doesn't take keyword arguments",
+ wp->descr->d_base->name);
+ return NULL;
+ }
+ return (*wrapper)(self, args, wp->descr->d_wrapped);
+}
+
+static int
+wrapper_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ wrapperobject *wp = (wrapperobject *)self;
+ Py_VISIT(wp->descr);
+ Py_VISIT(wp->self);
+ return 0;
+}
+
+static PyTypeObject wrappertype = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "method-wrapper", /* tp_name */
+ sizeof(wrapperobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)wrapper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)wrapper_compare, /* tp_compare */
+ (reprfunc)wrapper_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)wrapper_hash, /* tp_hash */
+ (ternaryfunc)wrapper_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ wrapper_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ wrapper_members, /* tp_members */
+ wrapper_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+PyObject *
+PyWrapper_New(PyObject *d, PyObject *self)
+{
+ wrapperobject *wp;
+ PyWrapperDescrObject *descr;
+
+ assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
+ descr = (PyWrapperDescrObject *)d;
+ assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type)));
+
+ wp = PyObject_GC_New(wrapperobject, &wrappertype);
+ if (wp != NULL) {
+ Py_INCREF(descr);
+ wp->descr = descr;
+ Py_INCREF(self);
+ wp->self = self;
+ _PyObject_GC_TRACK(wp);
+ }
+ return (PyObject *)wp;
+}
+
+
+/* A built-in 'property' type */
+
+/*
+ class property(object):
+
+ def __init__(self, fget=None, fset=None, fdel=None, doc=None):
+ if doc is None and fget is not None and hasattr(fget, "__doc__"):
+ doc = fget.__doc__
+ self.__get = fget
+ self.__set = fset
+ self.__del = fdel
+ self.__doc__ = doc
+
+ def __get__(self, inst, type=None):
+ if inst is None:
+ return self
+ if self.__get is None:
+ raise AttributeError, "unreadable attribute"
+ return self.__get(inst)
+
+ def __set__(self, inst, value):
+ if self.__set is None:
+ raise AttributeError, "can't set attribute"
+ return self.__set(inst, value)
+
+ def __delete__(self, inst):
+ if self.__del is None:
+ raise AttributeError, "can't delete attribute"
+ return self.__del(inst)
+
+*/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *prop_get;
+ PyObject *prop_set;
+ PyObject *prop_del;
+ PyObject *prop_doc;
+ int getter_doc;
+} propertyobject;
+
+static PyObject * property_copy(PyObject *, PyObject *, PyObject *,
+ PyObject *);
+
+static PyMemberDef property_members[] = {
+ {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY},
+ {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY},
+ {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY},
+ {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY},
+ {0}
+};
+
+
+PyDoc_STRVAR(getter_doc,
+ "Descriptor to change the getter on a property.");
+
+static PyObject *
+property_getter(PyObject *self, PyObject *getter)
+{
+ return property_copy(self, getter, NULL, NULL);
+}
+
+
+PyDoc_STRVAR(setter_doc,
+ "Descriptor to change the setter on a property.");
+
+static PyObject *
+property_setter(PyObject *self, PyObject *setter)
+{
+ return property_copy(self, NULL, setter, NULL);
+}
+
+
+PyDoc_STRVAR(deleter_doc,
+ "Descriptor to change the deleter on a property.");
+
+static PyObject *
+property_deleter(PyObject *self, PyObject *deleter)
+{
+ return property_copy(self, NULL, NULL, deleter);
+}
+
+
+static PyMethodDef property_methods[] = {
+ {"getter", property_getter, METH_O, getter_doc},
+ {"setter", property_setter, METH_O, setter_doc},
+ {"deleter", property_deleter, METH_O, deleter_doc},
+ {0}
+};
+
+
+static void
+property_dealloc(PyObject *self)
+{
+ propertyobject *gs = (propertyobject *)self;
+
+ _PyObject_GC_UNTRACK(self);
+ Py_XDECREF(gs->prop_get);
+ Py_XDECREF(gs->prop_set);
+ Py_XDECREF(gs->prop_del);
+ Py_XDECREF(gs->prop_doc);
+ self->ob_type->tp_free(self);
+}
+
+static PyObject *
+property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ propertyobject *gs = (propertyobject *)self;
+
+ if (obj == NULL || obj == Py_None) {
+ Py_INCREF(self);
+ return self;
+ }
+ if (gs->prop_get == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
+ return NULL;
+ }
+ return PyObject_CallFunction(gs->prop_get, "(O)", obj);
+}
+
+static int
+property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+ propertyobject *gs = (propertyobject *)self;
+ PyObject *func, *res;
+
+ if (value == NULL)
+ func = gs->prop_del;
+ else
+ func = gs->prop_set;
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ value == NULL ?
+ "can't delete attribute" :
+ "can't set attribute");
+ return -1;
+ }
+ if (value == NULL)
+ res = PyObject_CallFunction(func, "(O)", obj);
+ else
+ res = PyObject_CallFunction(func, "(OO)", obj, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static PyObject *
+property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)
+{
+ propertyobject *pold = (propertyobject *)old;
+ PyObject *new, *type, *doc;
+
+ type = PyObject_Type(old);
+ if (type == NULL)
+ return NULL;
+
+ if (get == NULL || get == Py_None) {
+ Py_XDECREF(get);
+ get = pold->prop_get ? pold->prop_get : Py_None;
+ }
+ if (set == NULL || set == Py_None) {
+ Py_XDECREF(set);
+ set = pold->prop_set ? pold->prop_set : Py_None;
+ }
+ if (del == NULL || del == Py_None) {
+ Py_XDECREF(del);
+ del = pold->prop_del ? pold->prop_del : Py_None;
+ }
+ if (pold->getter_doc && get != Py_None) {
+ /* make _init use __doc__ from getter */
+ doc = Py_None;
+ }
+ else {
+ doc = pold->prop_doc ? pold->prop_doc : Py_None;
+ }
+
+ new = PyObject_CallFunction(type, "OOOO", get, set, del, doc);
+ Py_DECREF(type);
+ if (new == NULL)
+ return NULL;
+ return new;
+}
+
+static int
+property_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
+ static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
+ propertyobject *prop = (propertyobject *)self;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
+ kwlist, &get, &set, &del, &doc))
+ return -1;
+
+ if (get == Py_None)
+ get = NULL;
+ if (set == Py_None)
+ set = NULL;
+ if (del == Py_None)
+ del = NULL;
+
+ Py_XINCREF(get);
+ Py_XINCREF(set);
+ Py_XINCREF(del);
+ Py_XINCREF(doc);
+
+ prop->prop_get = get;
+ prop->prop_set = set;
+ prop->prop_del = del;
+ prop->prop_doc = doc;
+ prop->getter_doc = 0;
+
+ /* if no docstring given and the getter has one, use that one */
+ if ((doc == NULL || doc == Py_None) && get != NULL) {
+ PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
+ if (get_doc) {
+ if (Py_TYPE(self) == &PyProperty_Type) {
+ Py_XDECREF(prop->prop_doc);
+ prop->prop_doc = get_doc;
+ }
+ else {
+ /* If this is a property subclass, put __doc__
+ in dict of the subclass instance instead,
+ otherwise it gets shadowed by __doc__ in the
+ class's dict. */
+ int err = PyObject_SetAttrString(self, "__doc__", get_doc);
+ Py_DECREF(get_doc);
+ if (err < 0)
+ return -1;
+ }
+ prop->getter_doc = 1;
+ }
+ else if (PyErr_ExceptionMatches(PyExc_Exception)) {
+ PyErr_Clear();
+ }
+ else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+PyDoc_STRVAR(property_doc,
+"property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n"
+"\n"
+"fget is a function to be used for getting an attribute value, and likewise\n"
+"fset is a function for setting, and fdel a function for del'ing, an\n"
+"attribute. Typical use is to define a managed attribute x:\n\n"
+"class C(object):\n"
+" def getx(self): return self._x\n"
+" def setx(self, value): self._x = value\n"
+" def delx(self): del self._x\n"
+" x = property(getx, setx, delx, \"I'm the 'x' property.\")\n"
+"\n"
+"Decorators make defining new properties or modifying existing ones easy:\n\n"
+"class C(object):\n"
+" @property\n"
+" def x(self):\n"
+" \"I am the 'x' property.\"\n"
+" return self._x\n"
+" @x.setter\n"
+" def x(self, value):\n"
+" self._x = value\n"
+" @x.deleter\n"
+" def x(self):\n"
+" del self._x\n"
+);
+
+static int
+property_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ propertyobject *pp = (propertyobject *)self;
+ Py_VISIT(pp->prop_get);
+ Py_VISIT(pp->prop_set);
+ Py_VISIT(pp->prop_del);
+ Py_VISIT(pp->prop_doc);
+ return 0;
+}
+
+PyTypeObject PyProperty_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "property", /* tp_name */
+ sizeof(propertyobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ property_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ property_doc, /* tp_doc */
+ property_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ property_methods, /* tp_methods */
+ property_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ property_descr_get, /* tp_descr_get */
+ property_descr_set, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ property_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/dictnotes.txt b/AppPkg/Applications/Python/Python-2.7.10/Objects/dictnotes.txt
new file mode 100644
index 0000000000..60a04c85f7
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/dictnotes.txt
@@ -0,0 +1,270 @@
+NOTES ON OPTIMIZING DICTIONARIES
+================================
+
+
+Principal Use Cases for Dictionaries
+------------------------------------
+
+Passing keyword arguments
+ Typically, one read and one write for 1 to 3 elements.
+ Occurs frequently in normal python code.
+
+Class method lookup
+ Dictionaries vary in size with 8 to 16 elements being common.
+ Usually written once with many lookups.
+ When base classes are used, there are many failed lookups
+ followed by a lookup in a base class.
+
+Instance attribute lookup and Global variables
+ Dictionaries vary in size. 4 to 10 elements are common.
+ Both reads and writes are common.
+
+Builtins
+ Frequent reads. Almost never written.
+ Size 126 interned strings (as of Py2.3b1).
+ A few keys are accessed much more frequently than others.
+
+Uniquification
+ Dictionaries of any size. Bulk of work is in creation.
+ Repeated writes to a smaller set of keys.
+ Single read of each key.
+ Some use cases have two consecutive accesses to the same key.
+
+ * Removing duplicates from a sequence.
+ dict.fromkeys(seqn).keys()
+
+ * Counting elements in a sequence.
+ for e in seqn:
+ d[e] = d.get(e,0) + 1
+
+ * Accumulating references in a dictionary of lists:
+
+ for pagenumber, page in enumerate(pages):
+ for word in page:
+ d.setdefault(word, []).append(pagenumber)
+
+ Note, the second example is a use case characterized by a get and set
+ to the same key. There are similar use cases with a __contains__
+ followed by a get, set, or del to the same key. Part of the
+ justification for d.setdefault is combining the two lookups into one.
+
+Membership Testing
+ Dictionaries of any size. Created once and then rarely changes.
+ Single write to each key.
+ Many calls to __contains__() or has_key().
+ Similar access patterns occur with replacement dictionaries
+ such as with the % formatting operator.
+
+Dynamic Mappings
+ Characterized by deletions interspersed with adds and replacements.
+ Performance benefits greatly from the re-use of dummy entries.
+
+
+Data Layout (assuming a 32-bit box with 64 bytes per cache line)
+----------------------------------------------------------------
+
+Smalldicts (8 entries) are attached to the dictobject structure
+and the whole group nearly fills two consecutive cache lines.
+
+Larger dicts use the first half of the dictobject structure (one cache
+line) and a separate, continuous block of entries (at 12 bytes each
+for a total of 5.333 entries per cache line).
+
+
+Tunable Dictionary Parameters
+-----------------------------
+
+* PyDict_MINSIZE. Currently set to 8.
+ Must be a power of two. New dicts have to zero-out every cell.
+ Each additional 8 consumes 1.5 cache lines. Increasing improves
+ the sparseness of small dictionaries but costs time to read in
+ the additional cache lines if they are not already in cache.
+ That case is common when keyword arguments are passed.
+
+* Maximum dictionary load in PyDict_SetItem. Currently set to 2/3.
+ Increasing this ratio makes dictionaries more dense resulting
+ in more collisions. Decreasing it improves sparseness at the
+ expense of spreading entries over more cache lines and at the
+ cost of total memory consumed.
+
+ The load test occurs in highly time sensitive code. Efforts
+ to make the test more complex (for example, varying the load
+ for different sizes) have degraded performance.
+
+* Growth rate upon hitting maximum load. Currently set to *2.
+ Raising this to *4 results in half the number of resizes,
+ less effort to resize, better sparseness for some (but not
+ all dict sizes), and potentially doubles memory consumption
+ depending on the size of the dictionary. Setting to *4
+ eliminates every other resize step.
+
+* Maximum sparseness (minimum dictionary load). What percentage
+ of entries can be unused before the dictionary shrinks to
+ free up memory and speed up iteration? (The current CPython
+ code does not represent this parameter directly.)
+
+* Shrinkage rate upon exceeding maximum sparseness. The current
+ CPython code never even checks sparseness when deleting a
+ key. When a new key is added, it resizes based on the number
+ of active keys, so that the addition may trigger shrinkage
+ rather than growth.
+
+Tune-ups should be measured across a broad range of applications and
+use cases. A change to any parameter will help in some situations and
+hurt in others. The key is to find settings that help the most common
+cases and do the least damage to the less common cases. Results will
+vary dramatically depending on the exact number of keys, whether the
+keys are all strings, whether reads or writes dominate, the exact
+hash values of the keys (some sets of values have fewer collisions than
+others). Any one test or benchmark is likely to prove misleading.
+
+While making a dictionary more sparse reduces collisions, it impairs
+iteration and key listing. Those methods loop over every potential
+entry. Doubling the size of dictionary results in twice as many
+non-overlapping memory accesses for keys(), items(), values(),
+__iter__(), iterkeys(), iteritems(), itervalues(), and update().
+Also, every dictionary iterates at least twice, once for the memset()
+when it is created and once by dealloc().
+
+Dictionary operations involving only a single key can be O(1) unless
+resizing is possible. By checking for a resize only when the
+dictionary can grow (and may *require* resizing), other operations
+remain O(1), and the odds of resize thrashing or memory fragmentation
+are reduced. In particular, an algorithm that empties a dictionary
+by repeatedly invoking .pop will see no resizing, which might
+not be necessary at all because the dictionary is eventually
+discarded entirely.
+
+
+Results of Cache Locality Experiments
+-------------------------------------
+
+When an entry is retrieved from memory, 4.333 adjacent entries are also
+retrieved into a cache line. Since accessing items in cache is *much*
+cheaper than a cache miss, an enticing idea is to probe the adjacent
+entries as a first step in collision resolution. Unfortunately, the
+introduction of any regularity into collision searches results in more
+collisions than the current random chaining approach.
+
+Exploiting cache locality at the expense of additional collisions fails
+to payoff when the entries are already loaded in cache (the expense
+is paid with no compensating benefit). This occurs in small dictionaries
+where the whole dictionary fits into a pair of cache lines. It also
+occurs frequently in large dictionaries which have a common access pattern
+where some keys are accessed much more frequently than others. The
+more popular entries *and* their collision chains tend to remain in cache.
+
+To exploit cache locality, change the collision resolution section
+in lookdict() and lookdict_string(). Set i^=1 at the top of the
+loop and move the i = (i << 2) + i + perturb + 1 to an unrolled
+version of the loop.
+
+This optimization strategy can be leveraged in several ways:
+
+* If the dictionary is kept sparse (through the tunable parameters),
+then the occurrence of additional collisions is lessened.
+
+* If lookdict() and lookdict_string() are specialized for small dicts
+and for largedicts, then the versions for large_dicts can be given
+an alternate search strategy without increasing collisions in small dicts
+which already have the maximum benefit of cache locality.
+
+* If the use case for a dictionary is known to have a random key
+access pattern (as opposed to a more common pattern with a Zipf's law
+distribution), then there will be more benefit for large dictionaries
+because any given key is no more likely than another to already be
+in cache.
+
+* In use cases with paired accesses to the same key, the second access
+is always in cache and gets no benefit from efforts to further improve
+cache locality.
+
+Optimizing the Search of Small Dictionaries
+-------------------------------------------
+
+If lookdict() and lookdict_string() are specialized for smaller dictionaries,
+then a custom search approach can be implemented that exploits the small
+search space and cache locality.
+
+* The simplest example is a linear search of contiguous entries. This is
+ simple to implement, guaranteed to terminate rapidly, never searches
+ the same entry twice, and precludes the need to check for dummy entries.
+
+* A more advanced example is a self-organizing search so that the most
+ frequently accessed entries get probed first. The organization
+ adapts if the access pattern changes over time. Treaps are ideally
+ suited for self-organization with the most common entries at the
+ top of the heap and a rapid binary search pattern. Most probes and
+ results are all located at the top of the tree allowing them all to
+ be located in one or two cache lines.
+
+* Also, small dictionaries may be made more dense, perhaps filling all
+ eight cells to take the maximum advantage of two cache lines.
+
+
+Strategy Pattern
+----------------
+
+Consider allowing the user to set the tunable parameters or to select a
+particular search method. Since some dictionary use cases have known
+sizes and access patterns, the user may be able to provide useful hints.
+
+1) For example, if membership testing or lookups dominate runtime and memory
+ is not at a premium, the user may benefit from setting the maximum load
+ ratio at 5% or 10% instead of the usual 66.7%. This will sharply
+ curtail the number of collisions but will increase iteration time.
+ The builtin namespace is a prime example of a dictionary that can
+ benefit from being highly sparse.
+
+2) Dictionary creation time can be shortened in cases where the ultimate
+ size of the dictionary is known in advance. The dictionary can be
+ pre-sized so that no resize operations are required during creation.
+ Not only does this save resizes, but the key insertion will go
+ more quickly because the first half of the keys will be inserted into
+ a more sparse environment than before. The preconditions for this
+ strategy arise whenever a dictionary is created from a key or item
+ sequence and the number of *unique* keys is known.
+
+3) If the key space is large and the access pattern is known to be random,
+ then search strategies exploiting cache locality can be fruitful.
+ The preconditions for this strategy arise in simulations and
+ numerical analysis.
+
+4) If the keys are fixed and the access pattern strongly favors some of
+ the keys, then the entries can be stored contiguously and accessed
+ with a linear search or treap. This exploits knowledge of the data,
+ cache locality, and a simplified search routine. It also eliminates
+ the need to test for dummy entries on each probe. The preconditions
+ for this strategy arise in symbol tables and in the builtin dictionary.
+
+
+Readonly Dictionaries
+---------------------
+Some dictionary use cases pass through a build stage and then move to a
+more heavily exercised lookup stage with no further changes to the
+dictionary.
+
+An idea that emerged on python-dev is to be able to convert a dictionary
+to a read-only state. This can help prevent programming errors and also
+provide knowledge that can be exploited for lookup optimization.
+
+The dictionary can be immediately rebuilt (eliminating dummy entries),
+resized (to an appropriate level of sparseness), and the keys can be
+jostled (to minimize collisions). The lookdict() routine can then
+eliminate the test for dummy entries (saving about 1/4 of the time
+spent in the collision resolution loop).
+
+An additional possibility is to insert links into the empty spaces
+so that dictionary iteration can proceed in len(d) steps instead of
+(mp->mask + 1) steps. Alternatively, a separate tuple of keys can be
+kept just for iteration.
+
+
+Caching Lookups
+---------------
+The idea is to exploit key access patterns by anticipating future lookups
+based on previous lookups.
+
+The simplest incarnation is to save the most recently accessed entry.
+This gives optimal performance for use cases where every get is followed
+by a set or del to the same key.
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/dictobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/dictobject.c
new file mode 100644
index 0000000000..c6bfc28629
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/dictobject.c
@@ -0,0 +1,3248 @@
+
+/* Dictionary object implementation using a hash table */
+
+/* The distribution includes a separate file, Objects/dictnotes.txt,
+ describing explorations into dictionary design and optimization.
+ It covers typical dictionary use patterns, the parameters for
+ tuning dictionaries, and several ideas for possible optimizations.
+*/
+
+#include "Python.h"
+
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+ PyObject *tup;
+ tup = PyTuple_Pack(1, arg);
+ if (!tup)
+ return; /* caller will expect error to be set anyway */
+ PyErr_SetObject(PyExc_KeyError, tup);
+ Py_DECREF(tup);
+}
+
+/* Define this out if you don't want conversion statistics on exit. */
+#undef SHOW_CONVERSION_COUNTS
+
+/* See large comment block below. This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/*
+Major subtleties ahead: Most hash schemes depend on having a "good" hash
+function, in the sense of simulating randomness. Python doesn't: its most
+important hash functions (for strings and ints) are very regular in common
+cases:
+
+>>> map(hash, (0, 1, 2, 3))
+[0, 1, 2, 3]
+>>> map(hash, ("namea", "nameb", "namec", "named"))
+[-1658398457, -1658398460, -1658398459, -1658398462]
+>>>
+
+This isn't necessarily bad! To the contrary, in a table of size 2**i, taking
+the low-order i bits as the initial table index is extremely fast, and there
+are no collisions at all for dicts indexed by a contiguous range of ints.
+The same is approximately true when keys are "consecutive" strings. So this
+gives better-than-random behavior in common cases, and that's very desirable.
+
+OTOH, when collisions occur, the tendency to fill contiguous slices of the
+hash table makes a good collision resolution strategy crucial. Taking only
+the last i bits of the hash code is also vulnerable: for example, consider
+[i << 16 for i in range(20000)] as a set of keys. Since ints are their own
+hash codes, and this fits in a dict of size 2**15, the last 15 bits of every
+hash code are all 0: they *all* map to the same table index.
+
+But catering to unusual cases should not slow the usual ones, so we just take
+the last i bits anyway. It's up to collision resolution to do the rest. If
+we *usually* find the key we're looking for on the first try (and, it turns
+out, we usually do -- the table load factor is kept under 2/3, so the odds
+are solidly in our favor), then it makes best sense to keep the initial index
+computation dirt cheap.
+
+The first half of collision resolution is to visit table indices via this
+recurrence:
+
+ j = ((5*j) + 1) mod 2**i
+
+For any initial j in range(2**i), repeating that 2**i times generates each
+int in range(2**i) exactly once (see any text on random-number generation for
+proof). By itself, this doesn't help much: like linear probing (setting
+j += 1, or j -= 1, on each loop trip), it scans the table entries in a fixed
+order. This would be bad, except that's not the only thing we do, and it's
+actually *good* in the common cases where hash keys are consecutive. In an
+example that's really too small to make this entirely clear, for a table of
+size 2**3 the order of indices is:
+
+ 0 -> 1 -> 6 -> 7 -> 4 -> 5 -> 2 -> 3 -> 0 [and here it's repeating]
+
+If two things come in at index 5, the first place we look after is index 2,
+not 6, so if another comes in at index 6 the collision at 5 didn't hurt it.
+Linear probing is deadly in this case because there the fixed probe order
+is the *same* as the order consecutive keys are likely to arrive. But it's
+extremely unlikely hash codes will follow a 5*j+1 recurrence by accident,
+and certain that consecutive hash codes do not.
+
+The other half of the strategy is to get the other bits of the hash code
+into play. This is done by initializing a (unsigned) vrbl "perturb" to the
+full hash code, and changing the recurrence to:
+
+ j = (5*j) + 1 + perturb;
+ perturb >>= PERTURB_SHIFT;
+ use j % 2**i as the next table index;
+
+Now the probe sequence depends (eventually) on every bit in the hash code,
+and the pseudo-scrambling property of recurring on 5*j+1 is more valuable,
+because it quickly magnifies small differences in the bits that didn't affect
+the initial index. Note that because perturb is unsigned, if the recurrence
+is executed often enough perturb eventually becomes and remains 0. At that
+point (very rarely reached) the recurrence is on (just) 5*j+1 again, and
+that's certain to find an empty slot eventually (since it generates every int
+in range(2**i), and we make sure there's always at least one empty slot).
+
+Selecting a good value for PERTURB_SHIFT is a balancing act. You want it
+small so that the high bits of the hash code continue to affect the probe
+sequence across iterations; but you want it large so that in really bad cases
+the high-order hash bits have an effect on early iterations. 5 was "the
+best" in minimizing total collisions across experiments Tim Peters ran (on
+both normal and pathological cases), but 4 and 6 weren't significantly worse.
+
+Historical: Reimer Behrends contributed the idea of using a polynomial-based
+approach, using repeated multiplication by x in GF(2**n) where an irreducible
+polynomial for each table size was chosen such that x was a primitive root.
+Christian Tismer later extended that to use division by x instead, as an
+efficient way to get the high bits of the hash code into play. This scheme
+also gave excellent collision statistics, but was more expensive: two
+if-tests were required inside the loop; computing "the next" index took about
+the same number of operations but without as much potential parallelism
+(e.g., computing 5*j can go on at the same time as computing 1+perturb in the
+above, and then shifting perturb can be done while the table index is being
+masked); and the PyDictObject struct required a member to hold the table's
+polynomial. In Tim's experiments the current scheme ran faster, produced
+equally good collision statistics, needed less code & used less memory.
+
+Theoretical Python 2.5 headache: hash codes are only C "long", but
+sizeof(Py_ssize_t) > sizeof(long) may be possible. In that case, and if a
+dict is genuinely huge, then only the slots directly reachable via indexing
+by a C long can be the first slot in a probe sequence. The probe sequence
+will still eventually reach every slot in the table, but the collision rate
+on initial probes may be much higher than this scheme was designed for.
+Getting a hash code as fat as Py_ssize_t is the only real cure. But in
+practice, this probably won't make a lick of difference for many years (at
+which point everyone will have terabytes of RAM on 64-bit boxes).
+*/
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to newPyDictObject() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PyDict_Dummy(void)
+{
+ return dummy;
+}
+#endif
+
+/* forward declarations */
+static PyDictEntry *
+lookdict_string(PyDictObject *mp, PyObject *key, long hash);
+
+#ifdef SHOW_CONVERSION_COUNTS
+static long created = 0L;
+static long converted = 0L;
+
+static void
+show_counts(void)
+{
+ fprintf(stderr, "created %ld string dicts\n", created);
+ fprintf(stderr, "converted %ld to normal dicts\n", converted);
+ fprintf(stderr, "%.2f%% conversion rate\n", (100.0*converted)/created);
+}
+#endif
+
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+ fprintf(stderr, "Dict allocations: %" PY_FORMAT_SIZE_T "d\n",
+ count_alloc);
+ fprintf(stderr, "Dict reuse through freelist: %" PY_FORMAT_SIZE_T
+ "d\n", count_reuse);
+ fprintf(stderr, "%.2f%% reuse rate\n\n",
+ (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
+/* Debug statistic to count GC tracking of dicts */
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+ fprintf(stderr, "Dicts created: %" PY_FORMAT_SIZE_T "d\n",
+ count_tracked + count_untracked);
+ fprintf(stderr, "Dicts tracked by the GC: %" PY_FORMAT_SIZE_T
+ "d\n", count_tracked);
+ fprintf(stderr, "%.2f%% dict tracking rate\n\n",
+ (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
+/* Initialization macros.
+ There are two ways to create a dict: PyDict_New() is the main C API
+ function, and the tp_new slot maps to dict_new(). In the latter case we
+ can save a little time over what PyDict_New does because it's guaranteed
+ that the PyDictObject struct is already zeroed out.
+ Everyone except dict_new() should use EMPTY_TO_MINSIZE (unless they have
+ an excellent reason not to).
+*/
+
+#define INIT_NONZERO_DICT_SLOTS(mp) do { \
+ (mp)->ma_table = (mp)->ma_smalltable; \
+ (mp)->ma_mask = PyDict_MINSIZE - 1; \
+ } while(0)
+
+#define EMPTY_TO_MINSIZE(mp) do { \
+ memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \
+ (mp)->ma_used = (mp)->ma_fill = 0; \
+ INIT_NONZERO_DICT_SLOTS(mp); \
+ } while(0)
+
+/* Dictionary reuse scheme to save calls to malloc, free, and memset */
+#ifndef PyDict_MAXFREELIST
+#define PyDict_MAXFREELIST 80
+#endif
+static PyDictObject *free_list[PyDict_MAXFREELIST];
+static int numfree = 0;
+
+void
+PyDict_Fini(void)
+{
+ PyDictObject *op;
+
+ while (numfree) {
+ op = free_list[--numfree];
+ assert(PyDict_CheckExact(op));
+ PyObject_GC_Del(op);
+ }
+}
+
+PyObject *
+PyDict_New(void)
+{
+ register PyDictObject *mp;
+ if (dummy == NULL) { /* Auto-initialize dummy */
+ dummy = PyString_FromString("<dummy key>");
+ if (dummy == NULL)
+ return NULL;
+#ifdef SHOW_CONVERSION_COUNTS
+ Py_AtExit(show_counts);
+#endif
+#ifdef SHOW_ALLOC_COUNT
+ Py_AtExit(show_alloc);
+#endif
+#ifdef SHOW_TRACK_COUNT
+ Py_AtExit(show_track);
+#endif
+ }
+ if (numfree) {
+ mp = free_list[--numfree];
+ assert (mp != NULL);
+ assert (Py_TYPE(mp) == &PyDict_Type);
+ _Py_NewReference((PyObject *)mp);
+ if (mp->ma_fill) {
+ EMPTY_TO_MINSIZE(mp);
+ } else {
+ /* At least set ma_table and ma_mask; these are wrong
+ if an empty but presized dict is added to freelist */
+ INIT_NONZERO_DICT_SLOTS(mp);
+ }
+ assert (mp->ma_used == 0);
+ assert (mp->ma_table == mp->ma_smalltable);
+ assert (mp->ma_mask == PyDict_MINSIZE - 1);
+#ifdef SHOW_ALLOC_COUNT
+ count_reuse++;
+#endif
+ } else {
+ mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
+ if (mp == NULL)
+ return NULL;
+ EMPTY_TO_MINSIZE(mp);
+#ifdef SHOW_ALLOC_COUNT
+ count_alloc++;
+#endif
+ }
+ mp->ma_lookup = lookdict_string;
+#ifdef SHOW_TRACK_COUNT
+ count_untracked++;
+#endif
+#ifdef SHOW_CONVERSION_COUNTS
+ ++created;
+#endif
+ return (PyObject *)mp;
+}
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained earlier.
+
+All arithmetic on hash should ignore overflow.
+
+(The details in this version are due to Tim Peters, building on many past
+contributions by Reimer Behrends, Jyrki Alakuijala, Vladimir Marangozov and
+Christian Tismer).
+
+lookdict() is general-purpose, and may return NULL if (and only if) a
+comparison raises an exception (this was new in Python 2.5).
+lookdict_string() below is specialized to string keys, comparison of which can
+never raise an exception; that function can never return NULL. For both, when
+the key isn't found a PyDictEntry* is returned for which the me_value field is
+NULL; this is the slot in the dict at which the key would have been found, and
+the caller can (if it wishes) add the <key, value> pair to the returned
+PyDictEntry*.
+*/
+static PyDictEntry *
+lookdict(PyDictObject *mp, PyObject *key, register long hash)
+{
+ register size_t i;
+ register size_t perturb;
+ register PyDictEntry *freeslot;
+ register size_t mask = (size_t)mp->ma_mask;
+ PyDictEntry *ep0 = mp->ma_table;
+ register PyDictEntry *ep;
+ register int cmp;
+ PyObject *startkey;
+
+ i = (size_t)hash & mask;
+ ep = &ep0[i];
+ if (ep->me_key == NULL || ep->me_key == key)
+ return ep;
+
+ if (ep->me_key == dummy)
+ freeslot = ep;
+ else {
+ if (ep->me_hash == hash) {
+ startkey = ep->me_key;
+ Py_INCREF(startkey);
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ Py_DECREF(startkey);
+ if (cmp < 0)
+ return NULL;
+ if (ep0 == mp->ma_table && ep->me_key == startkey) {
+ if (cmp > 0)
+ return ep;
+ }
+ else {
+ /* The compare did major nasty stuff to the
+ * dict: start over.
+ * XXX A clever adversary could prevent this
+ * XXX from terminating.
+ */
+ return lookdict(mp, key, hash);
+ }
+ }
+ freeslot = NULL;
+ }
+
+ /* In the loop, me_key == dummy is by far (factor of 100s) the
+ least likely outcome, so test for that last. */
+ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ ep = &ep0[i & mask];
+ if (ep->me_key == NULL)
+ return freeslot == NULL ? ep : freeslot;
+ if (ep->me_key == key)
+ return ep;
+ if (ep->me_hash == hash && ep->me_key != dummy) {
+ startkey = ep->me_key;
+ Py_INCREF(startkey);
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ Py_DECREF(startkey);
+ if (cmp < 0)
+ return NULL;
+ if (ep0 == mp->ma_table && ep->me_key == startkey) {
+ if (cmp > 0)
+ return ep;
+ }
+ else {
+ /* The compare did major nasty stuff to the
+ * dict: start over.
+ * XXX A clever adversary could prevent this
+ * XXX from terminating.
+ */
+ return lookdict(mp, key, hash);
+ }
+ }
+ else if (ep->me_key == dummy && freeslot == NULL)
+ freeslot = ep;
+ }
+ assert(0); /* NOT REACHED */
+ return 0;
+}
+
+/*
+ * Hacked up version of lookdict which can assume keys are always strings;
+ * this assumption allows testing for errors during PyObject_RichCompareBool()
+ * to be dropped; string-string comparisons never raise exceptions. This also
+ * means we don't need to go through PyObject_RichCompareBool(); we can always
+ * use _PyString_Eq() directly.
+ *
+ * This is valuable because dicts with only string keys are very common.
+ */
+static PyDictEntry *
+lookdict_string(PyDictObject *mp, PyObject *key, register long hash)
+{
+ register size_t i;
+ register size_t perturb;
+ register PyDictEntry *freeslot;
+ register size_t mask = (size_t)mp->ma_mask;
+ PyDictEntry *ep0 = mp->ma_table;
+ register PyDictEntry *ep;
+
+ /* Make sure this function doesn't have to handle non-string keys,
+ including subclasses of str; e.g., one reason to subclass
+ strings is to override __eq__, and for speed we don't cater to
+ that here. */
+ if (!PyString_CheckExact(key)) {
+#ifdef SHOW_CONVERSION_COUNTS
+ ++converted;
+#endif
+ mp->ma_lookup = lookdict;
+ return lookdict(mp, key, hash);
+ }
+ i = hash & mask;
+ ep = &ep0[i];
+ if (ep->me_key == NULL || ep->me_key == key)
+ return ep;
+ if (ep->me_key == dummy)
+ freeslot = ep;
+ else {
+ if (ep->me_hash == hash && _PyString_Eq(ep->me_key, key))
+ return ep;
+ freeslot = NULL;
+ }
+
+ /* In the loop, me_key == dummy is by far (factor of 100s) the
+ least likely outcome, so test for that last. */
+ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ ep = &ep0[i & mask];
+ if (ep->me_key == NULL)
+ return freeslot == NULL ? ep : freeslot;
+ if (ep->me_key == key
+ || (ep->me_hash == hash
+ && ep->me_key != dummy
+ && _PyString_Eq(ep->me_key, key)))
+ return ep;
+ if (ep->me_key == dummy && freeslot == NULL)
+ freeslot = ep;
+ }
+ assert(0); /* NOT REACHED */
+ return 0;
+}
+
+#ifdef SHOW_TRACK_COUNT
+#define INCREASE_TRACK_COUNT \
+ (count_tracked++, count_untracked--);
+#define DECREASE_TRACK_COUNT \
+ (count_tracked--, count_untracked++);
+#else
+#define INCREASE_TRACK_COUNT
+#define DECREASE_TRACK_COUNT
+#endif
+
+#define MAINTAIN_TRACKING(mp, key, value) \
+ do { \
+ if (!_PyObject_GC_IS_TRACKED(mp)) { \
+ if (_PyObject_GC_MAY_BE_TRACKED(key) || \
+ _PyObject_GC_MAY_BE_TRACKED(value)) { \
+ _PyObject_GC_TRACK(mp); \
+ INCREASE_TRACK_COUNT \
+ } \
+ } \
+ } while(0)
+
+void
+_PyDict_MaybeUntrack(PyObject *op)
+{
+ PyDictObject *mp;
+ PyObject *value;
+ Py_ssize_t mask, i;
+ PyDictEntry *ep;
+
+ if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+ return;
+
+ mp = (PyDictObject *) op;
+ ep = mp->ma_table;
+ mask = mp->ma_mask;
+ for (i = 0; i <= mask; i++) {
+ if ((value = ep[i].me_value) == NULL)
+ continue;
+ if (_PyObject_GC_MAY_BE_TRACKED(value) ||
+ _PyObject_GC_MAY_BE_TRACKED(ep[i].me_key))
+ return;
+ }
+ DECREASE_TRACK_COUNT
+ _PyObject_GC_UNTRACK(op);
+}
+
+/*
+Internal routine to insert a new item into the table when you have entry object.
+Used by insertdict.
+*/
+static int
+insertdict_by_entry(register PyDictObject *mp, PyObject *key, long hash,
+ PyDictEntry *ep, PyObject *value)
+{
+ PyObject *old_value;
+
+ MAINTAIN_TRACKING(mp, key, value);
+ if (ep->me_value != NULL) {
+ old_value = ep->me_value;
+ ep->me_value = value;
+ Py_DECREF(old_value); /* which **CAN** re-enter */
+ Py_DECREF(key);
+ }
+ else {
+ if (ep->me_key == NULL)
+ mp->ma_fill++;
+ else {
+ assert(ep->me_key == dummy);
+ Py_DECREF(dummy);
+ }
+ ep->me_key = key;
+ ep->me_hash = (Py_ssize_t)hash;
+ ep->me_value = value;
+ mp->ma_used++;
+ }
+ return 0;
+}
+
+
+/*
+Internal routine to insert a new item into the table.
+Used both by the internal resize routine and by the public insert routine.
+Eats a reference to key and one to value.
+Returns -1 if an error occurred, or 0 on success.
+*/
+static int
+insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
+{
+ register PyDictEntry *ep;
+
+ assert(mp->ma_lookup != NULL);
+ ep = mp->ma_lookup(mp, key, hash);
+ if (ep == NULL) {
+ Py_DECREF(key);
+ Py_DECREF(value);
+ return -1;
+ }
+ return insertdict_by_entry(mp, key, hash, ep, value);
+}
+
+/*
+Internal routine used by dictresize() to insert an item which is
+known to be absent from the dict. This routine also assumes that
+the dict contains no deleted entries. Besides the performance benefit,
+using insertdict() in dictresize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key` and `value`.
+*/
+static void
+insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
+ PyObject *value)
+{
+ register size_t i;
+ register size_t perturb;
+ register size_t mask = (size_t)mp->ma_mask;
+ PyDictEntry *ep0 = mp->ma_table;
+ register PyDictEntry *ep;
+
+ MAINTAIN_TRACKING(mp, key, value);
+ i = hash & mask;
+ ep = &ep0[i];
+ for (perturb = hash; ep->me_key != NULL; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ ep = &ep0[i & mask];
+ }
+ assert(ep->me_value == NULL);
+ mp->ma_fill++;
+ ep->me_key = key;
+ ep->me_hash = (Py_ssize_t)hash;
+ ep->me_value = value;
+ mp->ma_used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+items again. When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+dictresize(PyDictObject *mp, Py_ssize_t minused)
+{
+ Py_ssize_t newsize;
+ PyDictEntry *oldtable, *newtable, *ep;
+ Py_ssize_t i;
+ int is_oldtable_malloced;
+ PyDictEntry small_copy[PyDict_MINSIZE];
+
+ assert(minused >= 0);
+
+ /* Find the smallest table size > minused. */
+ for (newsize = PyDict_MINSIZE;
+ newsize <= minused && newsize > 0;
+ newsize <<= 1)
+ ;
+ if (newsize <= 0) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ /* Get space for a new table. */
+ oldtable = mp->ma_table;
+ assert(oldtable != NULL);
+ is_oldtable_malloced = oldtable != mp->ma_smalltable;
+
+ if (newsize == PyDict_MINSIZE) {
+ /* A large table is shrinking, or we can't get any smaller. */
+ newtable = mp->ma_smalltable;
+ if (newtable == oldtable) {
+ if (mp->ma_fill == mp->ma_used) {
+ /* No dummies, so no point doing anything. */
+ return 0;
+ }
+ /* We're not going to resize it, but rebuild the
+ table anyway to purge old dummy entries.
+ Subtle: This is *necessary* if fill==size,
+ as lookdict needs at least one virgin slot to
+ terminate failing searches. If fill < size, it's
+ merely desirable, as dummies slow searches. */
+ assert(mp->ma_fill > mp->ma_used);
+ memcpy(small_copy, oldtable, sizeof(small_copy));
+ oldtable = small_copy;
+ }
+ }
+ else {
+ newtable = PyMem_NEW(PyDictEntry, newsize);
+ if (newtable == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ }
+
+ /* Make the dict empty, using the new table. */
+ assert(newtable != oldtable);
+ mp->ma_table = newtable;
+ mp->ma_mask = newsize - 1;
+ memset(newtable, 0, sizeof(PyDictEntry) * newsize);
+ mp->ma_used = 0;
+ i = mp->ma_fill;
+ mp->ma_fill = 0;
+
+ /* Copy the data over; this is refcount-neutral for active entries;
+ dummy entries aren't copied over, of course */
+ for (ep = oldtable; i > 0; ep++) {
+ if (ep->me_value != NULL) { /* active entry */
+ --i;
+ insertdict_clean(mp, ep->me_key, (long)ep->me_hash,
+ ep->me_value);
+ }
+ else if (ep->me_key != NULL) { /* dummy entry */
+ --i;
+ assert(ep->me_key == dummy);
+ Py_DECREF(ep->me_key);
+ }
+ /* else key == value == NULL: nothing to do */
+ }
+
+ if (is_oldtable_malloced)
+ PyMem_DEL(oldtable);
+ return 0;
+}
+
+/* Create a new dictionary pre-sized to hold an estimated number of elements.
+ Underestimates are okay because the dictionary will resize as necessary.
+ Overestimates just mean the dictionary will be more sparse than usual.
+*/
+
+PyObject *
+_PyDict_NewPresized(Py_ssize_t minused)
+{
+ PyObject *op = PyDict_New();
+
+ if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) {
+ Py_DECREF(op);
+ return NULL;
+ }
+ return op;
+}
+
+/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
+ * that may occur (originally dicts supported only string keys, and exceptions
+ * weren't possible). So, while the original intent was that a NULL return
+ * meant the key wasn't present, in reality it can mean that, or that an error
+ * (suppressed) occurred while computing the key's hash, or that some error
+ * (suppressed) occurred when comparing keys in the dict's internal probe
+ * sequence. A nasty example of the latter is when a Python-coded comparison
+ * function hits a stack-depth error, which can cause this to return NULL
+ * even if the key is present.
+ */
+PyObject *
+PyDict_GetItem(PyObject *op, PyObject *key)
+{
+ long hash;
+ PyDictObject *mp = (PyDictObject *)op;
+ PyDictEntry *ep;
+ PyThreadState *tstate;
+ if (!PyDict_Check(op))
+ return NULL;
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1)
+ {
+ hash = PyObject_Hash(key);
+ if (hash == -1) {
+ PyErr_Clear();
+ return NULL;
+ }
+ }
+
+ /* We can arrive here with a NULL tstate during initialization: try
+ running "python -Wi" for an example related to string interning.
+ Let's just hope that no exception occurs then... This must be
+ _PyThreadState_Current and not PyThreadState_GET() because in debug
+ mode, the latter complains if tstate is NULL. */
+ tstate = _PyThreadState_Current;
+ if (tstate != NULL && tstate->curexc_type != NULL) {
+ /* preserve the existing exception */
+ PyObject *err_type, *err_value, *err_tb;
+ PyErr_Fetch(&err_type, &err_value, &err_tb);
+ ep = (mp->ma_lookup)(mp, key, hash);
+ /* ignore errors */
+ PyErr_Restore(err_type, err_value, err_tb);
+ if (ep == NULL)
+ return NULL;
+ }
+ else {
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL) {
+ PyErr_Clear();
+ return NULL;
+ }
+ }
+ return ep->me_value;
+}
+
+static int
+dict_set_item_by_hash_or_entry(register PyObject *op, PyObject *key,
+ long hash, PyDictEntry *ep, PyObject *value)
+{
+ register PyDictObject *mp;
+ register Py_ssize_t n_used;
+
+ mp = (PyDictObject *)op;
+ assert(mp->ma_fill <= mp->ma_mask); /* at least one empty slot */
+ n_used = mp->ma_used;
+ Py_INCREF(value);
+ Py_INCREF(key);
+ if (ep == NULL) {
+ if (insertdict(mp, key, hash, value) != 0)
+ return -1;
+ }
+ else {
+ if (insertdict_by_entry(mp, key, hash, ep, value) != 0)
+ return -1;
+ }
+ /* If we added a key, we can safely resize. Otherwise just return!
+ * If fill >= 2/3 size, adjust size. Normally, this doubles or
+ * quaduples the size, but it's also possible for the dict to shrink
+ * (if ma_fill is much larger than ma_used, meaning a lot of dict
+ * keys have been * deleted).
+ *
+ * Quadrupling the size improves average dictionary sparseness
+ * (reducing collisions) at the cost of some memory and iteration
+ * speed (which loops over every possible entry). It also halves
+ * the number of expensive resize operations in a growing dictionary.
+ *
+ * Very large dictionaries (over 50K items) use doubling instead.
+ * This may help applications with severe memory constraints.
+ */
+ if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2))
+ return 0;
+ return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used);
+}
+
+/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
+ * dictionary if it's merely replacing the value for an existing key.
+ * This means that it's safe to loop over a dictionary with PyDict_Next()
+ * and occasionally replace a value -- but you can't insert new keys or
+ * remove them.
+ */
+int
+PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
+{
+ register long hash;
+
+ if (!PyDict_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ assert(key);
+ assert(value);
+ if (PyString_CheckExact(key)) {
+ hash = ((PyStringObject *)key)->ob_shash;
+ if (hash == -1)
+ hash = PyObject_Hash(key);
+ }
+ else {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ return dict_set_item_by_hash_or_entry(op, key, hash, NULL, value);
+}
+
+int
+PyDict_DelItem(PyObject *op, PyObject *key)
+{
+ register PyDictObject *mp;
+ register long hash;
+ register PyDictEntry *ep;
+ PyObject *old_value, *old_key;
+
+ if (!PyDict_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ assert(key);
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ mp = (PyDictObject *)op;
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return -1;
+ if (ep->me_value == NULL) {
+ set_key_error(key);
+ return -1;
+ }
+ old_key = ep->me_key;
+ Py_INCREF(dummy);
+ ep->me_key = dummy;
+ old_value = ep->me_value;
+ ep->me_value = NULL;
+ mp->ma_used--;
+ Py_DECREF(old_value);
+ Py_DECREF(old_key);
+ return 0;
+}
+
+void
+PyDict_Clear(PyObject *op)
+{
+ PyDictObject *mp;
+ PyDictEntry *ep, *table;
+ int table_is_malloced;
+ Py_ssize_t fill;
+ PyDictEntry small_copy[PyDict_MINSIZE];
+#ifdef Py_DEBUG
+ Py_ssize_t i, n;
+#endif
+
+ if (!PyDict_Check(op))
+ return;
+ mp = (PyDictObject *)op;
+#ifdef Py_DEBUG
+ n = mp->ma_mask + 1;
+ i = 0;
+#endif
+
+ table = mp->ma_table;
+ assert(table != NULL);
+ table_is_malloced = table != mp->ma_smalltable;
+
+ /* This is delicate. During the process of clearing the dict,
+ * decrefs can cause the dict to mutate. To avoid fatal confusion
+ * (voice of experience), we have to make the dict empty before
+ * clearing the slots, and never refer to anything via mp->xxx while
+ * clearing.
+ */
+ fill = mp->ma_fill;
+ if (table_is_malloced)
+ EMPTY_TO_MINSIZE(mp);
+
+ else if (fill > 0) {
+ /* It's a small table with something that needs to be cleared.
+ * Afraid the only safe way is to copy the dict entries into
+ * another small table first.
+ */
+ memcpy(small_copy, table, sizeof(small_copy));
+ table = small_copy;
+ EMPTY_TO_MINSIZE(mp);
+ }
+ /* else it's a small table that's already empty */
+
+ /* Now we can finally clear things. If C had refcounts, we could
+ * assert that the refcount on table is 1 now, i.e. that this function
+ * has unique access to it, so decref side-effects can't alter it.
+ */
+ for (ep = table; fill > 0; ++ep) {
+#ifdef Py_DEBUG
+ assert(i < n);
+ ++i;
+#endif
+ if (ep->me_key) {
+ --fill;
+ Py_DECREF(ep->me_key);
+ Py_XDECREF(ep->me_value);
+ }
+#ifdef Py_DEBUG
+ else
+ assert(ep->me_value == NULL);
+#endif
+ }
+
+ if (table_is_malloced)
+ PyMem_DEL(table);
+}
+
+/*
+ * Iterate over a dict. Use like so:
+ *
+ * Py_ssize_t i;
+ * PyObject *key, *value;
+ * i = 0; # important! i should not otherwise be changed by you
+ * while (PyDict_Next(yourdict, &i, &key, &value)) {
+ * Refer to borrowed references in key and value.
+ * }
+ *
+ * CAUTION: In general, it isn't safe to use PyDict_Next in a loop that
+ * mutates the dict. One exception: it is safe if the loop merely changes
+ * the values associated with the keys (but doesn't insert new keys or
+ * delete keys), via PyDict_SetItem().
+ */
+int
+PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
+{
+ register Py_ssize_t i;
+ register Py_ssize_t mask;
+ register PyDictEntry *ep;
+
+ if (!PyDict_Check(op))
+ return 0;
+ i = *ppos;
+ if (i < 0)
+ return 0;
+ ep = ((PyDictObject *)op)->ma_table;
+ mask = ((PyDictObject *)op)->ma_mask;
+ while (i <= mask && ep[i].me_value == NULL)
+ i++;
+ *ppos = i+1;
+ if (i > mask)
+ return 0;
+ if (pkey)
+ *pkey = ep[i].me_key;
+ if (pvalue)
+ *pvalue = ep[i].me_value;
+ return 1;
+}
+
+/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/
+int
+_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash)
+{
+ register Py_ssize_t i;
+ register Py_ssize_t mask;
+ register PyDictEntry *ep;
+
+ if (!PyDict_Check(op))
+ return 0;
+ i = *ppos;
+ if (i < 0)
+ return 0;
+ ep = ((PyDictObject *)op)->ma_table;
+ mask = ((PyDictObject *)op)->ma_mask;
+ while (i <= mask && ep[i].me_value == NULL)
+ i++;
+ *ppos = i+1;
+ if (i > mask)
+ return 0;
+ *phash = (long)(ep[i].me_hash);
+ if (pkey)
+ *pkey = ep[i].me_key;
+ if (pvalue)
+ *pvalue = ep[i].me_value;
+ return 1;
+}
+
+/* Methods */
+
+static void
+dict_dealloc(register PyDictObject *mp)
+{
+ register PyDictEntry *ep;
+ Py_ssize_t fill = mp->ma_fill;
+ PyObject_GC_UnTrack(mp);
+ Py_TRASHCAN_SAFE_BEGIN(mp)
+ for (ep = mp->ma_table; fill > 0; ep++) {
+ if (ep->me_key) {
+ --fill;
+ Py_DECREF(ep->me_key);
+ Py_XDECREF(ep->me_value);
+ }
+ }
+ if (mp->ma_table != mp->ma_smalltable)
+ PyMem_DEL(mp->ma_table);
+ if (numfree < PyDict_MAXFREELIST && Py_TYPE(mp) == &PyDict_Type)
+ free_list[numfree++] = mp;
+ else
+ Py_TYPE(mp)->tp_free((PyObject *)mp);
+ Py_TRASHCAN_SAFE_END(mp)
+}
+
+static int
+dict_print(register PyDictObject *mp, register FILE *fp, register int flags)
+{
+ register Py_ssize_t i;
+ register Py_ssize_t any;
+ int status;
+
+ status = Py_ReprEnter((PyObject*)mp);
+ if (status != 0) {
+ if (status < 0)
+ return status;
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "{...}");
+ Py_END_ALLOW_THREADS
+ return 0;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "{");
+ Py_END_ALLOW_THREADS
+ any = 0;
+ for (i = 0; i <= mp->ma_mask; i++) {
+ PyDictEntry *ep = mp->ma_table + i;
+ PyObject *pvalue = ep->me_value;
+ if (pvalue != NULL) {
+ /* Prevent PyObject_Repr from deleting value during
+ key format */
+ Py_INCREF(pvalue);
+ if (any++ > 0) {
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, ", ");
+ Py_END_ALLOW_THREADS
+ }
+ if (PyObject_Print((PyObject *)ep->me_key, fp, 0)!=0) {
+ Py_DECREF(pvalue);
+ Py_ReprLeave((PyObject*)mp);
+ return -1;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, ": ");
+ Py_END_ALLOW_THREADS
+ if (PyObject_Print(pvalue, fp, 0) != 0) {
+ Py_DECREF(pvalue);
+ Py_ReprLeave((PyObject*)mp);
+ return -1;
+ }
+ Py_DECREF(pvalue);
+ }
+ }
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "}");
+ Py_END_ALLOW_THREADS
+ Py_ReprLeave((PyObject*)mp);
+ return 0;
+}
+
+static PyObject *
+dict_repr(PyDictObject *mp)
+{
+ Py_ssize_t i;
+ PyObject *s, *temp, *colon = NULL;
+ PyObject *pieces = NULL, *result = NULL;
+ PyObject *key, *value;
+
+ i = Py_ReprEnter((PyObject *)mp);
+ if (i != 0) {
+ return i > 0 ? PyString_FromString("{...}") : NULL;
+ }
+
+ if (mp->ma_used == 0) {
+ result = PyString_FromString("{}");
+ goto Done;
+ }
+
+ pieces = PyList_New(0);
+ if (pieces == NULL)
+ goto Done;
+
+ colon = PyString_FromString(": ");
+ if (colon == NULL)
+ goto Done;
+
+ /* Do repr() on each key+value pair, and insert ": " between them.
+ Note that repr may mutate the dict. */
+ i = 0;
+ while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
+ int status;
+ /* Prevent repr from deleting value during key format. */
+ Py_INCREF(value);
+ s = PyObject_Repr(key);
+ PyString_Concat(&s, colon);
+ PyString_ConcatAndDel(&s, PyObject_Repr(value));
+ Py_DECREF(value);
+ if (s == NULL)
+ goto Done;
+ status = PyList_Append(pieces, s);
+ Py_DECREF(s); /* append created a new ref */
+ if (status < 0)
+ goto Done;
+ }
+
+ /* Add "{}" decorations to the first and last items. */
+ assert(PyList_GET_SIZE(pieces) > 0);
+ s = PyString_FromString("{");
+ if (s == NULL)
+ goto Done;
+ temp = PyList_GET_ITEM(pieces, 0);
+ PyString_ConcatAndDel(&s, temp);
+ PyList_SET_ITEM(pieces, 0, s);
+ if (s == NULL)
+ goto Done;
+
+ s = PyString_FromString("}");
+ if (s == NULL)
+ goto Done;
+ temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+ PyString_ConcatAndDel(&temp, s);
+ PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+ if (temp == NULL)
+ goto Done;
+
+ /* Paste them all together with ", " between. */
+ s = PyString_FromString(", ");
+ if (s == NULL)
+ goto Done;
+ result = _PyString_Join(s, pieces);
+ Py_DECREF(s);
+
+Done:
+ Py_XDECREF(pieces);
+ Py_XDECREF(colon);
+ Py_ReprLeave((PyObject *)mp);
+ return result;
+}
+
+static Py_ssize_t
+dict_length(PyDictObject *mp)
+{
+ return mp->ma_used;
+}
+
+static PyObject *
+dict_subscript(PyDictObject *mp, register PyObject *key)
+{
+ PyObject *v;
+ long hash;
+ PyDictEntry *ep;
+ assert(mp->ma_table != NULL);
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return NULL;
+ v = ep->me_value;
+ if (v == NULL) {
+ if (!PyDict_CheckExact(mp)) {
+ /* Look up __missing__ method if we're a subclass. */
+ PyObject *missing, *res;
+ static PyObject *missing_str = NULL;
+ missing = _PyObject_LookupSpecial((PyObject *)mp,
+ "__missing__",
+ &missing_str);
+ if (missing != NULL) {
+ res = PyObject_CallFunctionObjArgs(missing,
+ key, NULL);
+ Py_DECREF(missing);
+ return res;
+ }
+ else if (PyErr_Occurred())
+ return NULL;
+ }
+ set_key_error(key);
+ return NULL;
+ }
+ else
+ Py_INCREF(v);
+ return v;
+}
+
+static int
+dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w)
+{
+ if (w == NULL)
+ return PyDict_DelItem((PyObject *)mp, v);
+ else
+ return PyDict_SetItem((PyObject *)mp, v, w);
+}
+
+static PyMappingMethods dict_as_mapping = {
+ (lenfunc)dict_length, /*mp_length*/
+ (binaryfunc)dict_subscript, /*mp_subscript*/
+ (objobjargproc)dict_ass_sub, /*mp_ass_subscript*/
+};
+
+static PyObject *
+dict_keys(register PyDictObject *mp)
+{
+ register PyObject *v;
+ register Py_ssize_t i, j;
+ PyDictEntry *ep;
+ Py_ssize_t mask, n;
+
+ again:
+ n = mp->ma_used;
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ if (n != mp->ma_used) {
+ /* Durnit. The allocations caused the dict to resize.
+ * Just start over, this shouldn't normally happen.
+ */
+ Py_DECREF(v);
+ goto again;
+ }
+ ep = mp->ma_table;
+ mask = mp->ma_mask;
+ for (i = 0, j = 0; i <= mask; i++) {
+ if (ep[i].me_value != NULL) {
+ PyObject *key = ep[i].me_key;
+ Py_INCREF(key);
+ PyList_SET_ITEM(v, j, key);
+ j++;
+ }
+ }
+ assert(j == n);
+ return v;
+}
+
+static PyObject *
+dict_values(register PyDictObject *mp)
+{
+ register PyObject *v;
+ register Py_ssize_t i, j;
+ PyDictEntry *ep;
+ Py_ssize_t mask, n;
+
+ again:
+ n = mp->ma_used;
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ if (n != mp->ma_used) {
+ /* Durnit. The allocations caused the dict to resize.
+ * Just start over, this shouldn't normally happen.
+ */
+ Py_DECREF(v);
+ goto again;
+ }
+ ep = mp->ma_table;
+ mask = mp->ma_mask;
+ for (i = 0, j = 0; i <= mask; i++) {
+ if (ep[i].me_value != NULL) {
+ PyObject *value = ep[i].me_value;
+ Py_INCREF(value);
+ PyList_SET_ITEM(v, j, value);
+ j++;
+ }
+ }
+ assert(j == n);
+ return v;
+}
+
+static PyObject *
+dict_items(register PyDictObject *mp)
+{
+ register PyObject *v;
+ register Py_ssize_t i, j, n;
+ Py_ssize_t mask;
+ PyObject *item, *key, *value;
+ PyDictEntry *ep;
+
+ /* Preallocate the list of tuples, to avoid allocations during
+ * the loop over the items, which could trigger GC, which
+ * could resize the dict. :-(
+ */
+ again:
+ n = mp->ma_used;
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ item = PyTuple_New(2);
+ if (item == NULL) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_SET_ITEM(v, i, item);
+ }
+ if (n != mp->ma_used) {
+ /* Durnit. The allocations caused the dict to resize.
+ * Just start over, this shouldn't normally happen.
+ */
+ Py_DECREF(v);
+ goto again;
+ }
+ /* Nothing we do below makes any function calls. */
+ ep = mp->ma_table;
+ mask = mp->ma_mask;
+ for (i = 0, j = 0; i <= mask; i++) {
+ if ((value=ep[i].me_value) != NULL) {
+ key = ep[i].me_key;
+ item = PyList_GET_ITEM(v, j);
+ Py_INCREF(key);
+ PyTuple_SET_ITEM(item, 0, key);
+ Py_INCREF(value);
+ PyTuple_SET_ITEM(item, 1, value);
+ j++;
+ }
+ }
+ assert(j == n);
+ return v;
+}
+
+static PyObject *
+dict_fromkeys(PyObject *cls, PyObject *args)
+{
+ PyObject *seq;
+ PyObject *value = Py_None;
+ PyObject *it; /* iter(seq) */
+ PyObject *key;
+ PyObject *d;
+ int status;
+
+ if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value))
+ return NULL;
+
+ d = PyObject_CallObject(cls, NULL);
+ if (d == NULL)
+ return NULL;
+
+ if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) {
+ if (PyDict_CheckExact(seq)) {
+ PyDictObject *mp = (PyDictObject *)d;
+ PyObject *oldvalue;
+ Py_ssize_t pos = 0;
+ PyObject *key;
+ long hash;
+
+ if (dictresize(mp, Py_SIZE(seq))) {
+ Py_DECREF(d);
+ return NULL;
+ }
+
+ while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
+ Py_INCREF(key);
+ Py_INCREF(value);
+ if (insertdict(mp, key, hash, value)) {
+ Py_DECREF(d);
+ return NULL;
+ }
+ }
+ return d;
+ }
+ if (PyAnySet_CheckExact(seq)) {
+ PyDictObject *mp = (PyDictObject *)d;
+ Py_ssize_t pos = 0;
+ PyObject *key;
+ long hash;
+
+ if (dictresize(mp, PySet_GET_SIZE(seq))) {
+ Py_DECREF(d);
+ return NULL;
+ }
+
+ while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
+ Py_INCREF(key);
+ Py_INCREF(value);
+ if (insertdict(mp, key, hash, value)) {
+ Py_DECREF(d);
+ return NULL;
+ }
+ }
+ return d;
+ }
+ }
+
+ it = PyObject_GetIter(seq);
+ if (it == NULL){
+ Py_DECREF(d);
+ return NULL;
+ }
+
+ if (PyDict_CheckExact(d)) {
+ while ((key = PyIter_Next(it)) != NULL) {
+ status = PyDict_SetItem(d, key, value);
+ Py_DECREF(key);
+ if (status < 0)
+ goto Fail;
+ }
+ } else {
+ while ((key = PyIter_Next(it)) != NULL) {
+ status = PyObject_SetItem(d, key, value);
+ Py_DECREF(key);
+ if (status < 0)
+ goto Fail;
+ }
+ }
+
+ if (PyErr_Occurred())
+ goto Fail;
+ Py_DECREF(it);
+ return d;
+
+Fail:
+ Py_DECREF(it);
+ Py_DECREF(d);
+ return NULL;
+}
+
+static int
+dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methname)
+{
+ PyObject *arg = NULL;
+ int result = 0;
+
+ if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg))
+ result = -1;
+
+ else if (arg != NULL) {
+ if (PyObject_HasAttrString(arg, "keys"))
+ result = PyDict_Merge(self, arg, 1);
+ else
+ result = PyDict_MergeFromSeq2(self, arg, 1);
+ }
+ if (result == 0 && kwds != NULL)
+ result = PyDict_Merge(self, kwds, 1);
+ return result;
+}
+
+static PyObject *
+dict_update(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ if (dict_update_common(self, args, kwds, "update") != -1)
+ Py_RETURN_NONE;
+ return NULL;
+}
+
+/* Update unconditionally replaces existing items.
+ Merge has a 3rd argument 'override'; if set, it acts like Update,
+ otherwise it leaves existing items unchanged.
+
+ PyDict_{Update,Merge} update/merge from a mapping object.
+
+ PyDict_MergeFromSeq2 updates/merges from any iterable object
+ producing iterable objects of length 2.
+*/
+
+int
+PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override)
+{
+ PyObject *it; /* iter(seq2) */
+ Py_ssize_t i; /* index into seq2 of current element */
+ PyObject *item; /* seq2[i] */
+ PyObject *fast; /* item as a 2-tuple or 2-list */
+
+ assert(d != NULL);
+ assert(PyDict_Check(d));
+ assert(seq2 != NULL);
+
+ it = PyObject_GetIter(seq2);
+ if (it == NULL)
+ return -1;
+
+ for (i = 0; ; ++i) {
+ PyObject *key, *value;
+ Py_ssize_t n;
+
+ fast = NULL;
+ item = PyIter_Next(it);
+ if (item == NULL) {
+ if (PyErr_Occurred())
+ goto Fail;
+ break;
+ }
+
+ /* Convert item to sequence, and verify length 2. */
+ fast = PySequence_Fast(item, "");
+ if (fast == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError,
+ "cannot convert dictionary update "
+ "sequence element #%zd to a sequence",
+ i);
+ goto Fail;
+ }
+ n = PySequence_Fast_GET_SIZE(fast);
+ if (n != 2) {
+ PyErr_Format(PyExc_ValueError,
+ "dictionary update sequence element #%zd "
+ "has length %zd; 2 is required",
+ i, n);
+ goto Fail;
+ }
+
+ /* Update/merge with this (key, value) pair. */
+ key = PySequence_Fast_GET_ITEM(fast, 0);
+ value = PySequence_Fast_GET_ITEM(fast, 1);
+ if (override || PyDict_GetItem(d, key) == NULL) {
+ int status = PyDict_SetItem(d, key, value);
+ if (status < 0)
+ goto Fail;
+ }
+ Py_DECREF(fast);
+ Py_DECREF(item);
+ }
+
+ i = 0;
+ goto Return;
+Fail:
+ Py_XDECREF(item);
+ Py_XDECREF(fast);
+ i = -1;
+Return:
+ Py_DECREF(it);
+ return Py_SAFE_DOWNCAST(i, Py_ssize_t, int);
+}
+
+int
+PyDict_Update(PyObject *a, PyObject *b)
+{
+ return PyDict_Merge(a, b, 1);
+}
+
+int
+PyDict_Merge(PyObject *a, PyObject *b, int override)
+{
+ register PyDictObject *mp, *other;
+ register Py_ssize_t i;
+ PyDictEntry *entry;
+
+ /* We accept for the argument either a concrete dictionary object,
+ * or an abstract "mapping" object. For the former, we can do
+ * things quite efficiently. For the latter, we only require that
+ * PyMapping_Keys() and PyObject_GetItem() be supported.
+ */
+ if (a == NULL || !PyDict_Check(a) || b == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ mp = (PyDictObject*)a;
+ if (PyDict_Check(b)) {
+ other = (PyDictObject*)b;
+ if (other == mp || other->ma_used == 0)
+ /* a.update(a) or a.update({}); nothing to do */
+ return 0;
+ if (mp->ma_used == 0)
+ /* Since the target dict is empty, PyDict_GetItem()
+ * always returns NULL. Setting override to 1
+ * skips the unnecessary test.
+ */
+ override = 1;
+ /* Do one big resize at the start, rather than
+ * incrementally resizing as we insert new items. Expect
+ * that there will be no (or few) overlapping keys.
+ */
+ if ((mp->ma_fill + other->ma_used)*3 >= (mp->ma_mask+1)*2) {
+ if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
+ return -1;
+ }
+ for (i = 0; i <= other->ma_mask; i++) {
+ entry = &other->ma_table[i];
+ if (entry->me_value != NULL &&
+ (override ||
+ PyDict_GetItem(a, entry->me_key) == NULL)) {
+ Py_INCREF(entry->me_key);
+ Py_INCREF(entry->me_value);
+ if (insertdict(mp, entry->me_key,
+ (long)entry->me_hash,
+ entry->me_value) != 0)
+ return -1;
+ }
+ }
+ }
+ else {
+ /* Do it the generic, slower way */
+ PyObject *keys = PyMapping_Keys(b);
+ PyObject *iter;
+ PyObject *key, *value;
+ int status;
+
+ if (keys == NULL)
+ /* Docstring says this is equivalent to E.keys() so
+ * if E doesn't have a .keys() method we want
+ * AttributeError to percolate up. Might as well
+ * do the same for any other error.
+ */
+ return -1;
+
+ iter = PyObject_GetIter(keys);
+ Py_DECREF(keys);
+ if (iter == NULL)
+ return -1;
+
+ for (key = PyIter_Next(iter); key; key = PyIter_Next(iter)) {
+ if (!override && PyDict_GetItem(a, key) != NULL) {
+ Py_DECREF(key);
+ continue;
+ }
+ value = PyObject_GetItem(b, key);
+ if (value == NULL) {
+ Py_DECREF(iter);
+ Py_DECREF(key);
+ return -1;
+ }
+ status = PyDict_SetItem(a, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (status < 0) {
+ Py_DECREF(iter);
+ return -1;
+ }
+ }
+ Py_DECREF(iter);
+ if (PyErr_Occurred())
+ /* Iterator completed, via error */
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+dict_copy(register PyDictObject *mp)
+{
+ return PyDict_Copy((PyObject*)mp);
+}
+
+PyObject *
+PyDict_Copy(PyObject *o)
+{
+ PyObject *copy;
+
+ if (o == NULL || !PyDict_Check(o)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ copy = PyDict_New();
+ if (copy == NULL)
+ return NULL;
+ if (PyDict_Merge(copy, o, 1) == 0)
+ return copy;
+ Py_DECREF(copy);
+ return NULL;
+}
+
+Py_ssize_t
+PyDict_Size(PyObject *mp)
+{
+ if (mp == NULL || !PyDict_Check(mp)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return ((PyDictObject *)mp)->ma_used;
+}
+
+PyObject *
+PyDict_Keys(PyObject *mp)
+{
+ if (mp == NULL || !PyDict_Check(mp)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return dict_keys((PyDictObject *)mp);
+}
+
+PyObject *
+PyDict_Values(PyObject *mp)
+{
+ if (mp == NULL || !PyDict_Check(mp)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return dict_values((PyDictObject *)mp);
+}
+
+PyObject *
+PyDict_Items(PyObject *mp)
+{
+ if (mp == NULL || !PyDict_Check(mp)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return dict_items((PyDictObject *)mp);
+}
+
+/* Subroutine which returns the smallest key in a for which b's value
+ is different or absent. The value is returned too, through the
+ pval argument. Both are NULL if no key in a is found for which b's status
+ differs. The refcounts on (and only on) non-NULL *pval and function return
+ values must be decremented by the caller (characterize() increments them
+ to ensure that mutating comparison and PyDict_GetItem calls can't delete
+ them before the caller is done looking at them). */
+
+static PyObject *
+characterize(PyDictObject *a, PyDictObject *b, PyObject **pval)
+{
+ PyObject *akey = NULL; /* smallest key in a s.t. a[akey] != b[akey] */
+ PyObject *aval = NULL; /* a[akey] */
+ Py_ssize_t i;
+ int cmp;
+
+ for (i = 0; i <= a->ma_mask; i++) {
+ PyObject *thiskey, *thisaval, *thisbval;
+ if (a->ma_table[i].me_value == NULL)
+ continue;
+ thiskey = a->ma_table[i].me_key;
+ Py_INCREF(thiskey); /* keep alive across compares */
+ if (akey != NULL) {
+ cmp = PyObject_RichCompareBool(akey, thiskey, Py_LT);
+ if (cmp < 0) {
+ Py_DECREF(thiskey);
+ goto Fail;
+ }
+ if (cmp > 0 ||
+ i > a->ma_mask ||
+ a->ma_table[i].me_value == NULL)
+ {
+ /* Not the *smallest* a key; or maybe it is
+ * but the compare shrunk the dict so we can't
+ * find its associated value anymore; or
+ * maybe it is but the compare deleted the
+ * a[thiskey] entry.
+ */
+ Py_DECREF(thiskey);
+ continue;
+ }
+ }
+
+ /* Compare a[thiskey] to b[thiskey]; cmp <- true iff equal. */
+ thisaval = a->ma_table[i].me_value;
+ assert(thisaval);
+ Py_INCREF(thisaval); /* keep alive */
+ thisbval = PyDict_GetItem((PyObject *)b, thiskey);
+ if (thisbval == NULL)
+ cmp = 0;
+ else {
+ /* both dicts have thiskey: same values? */
+ cmp = PyObject_RichCompareBool(
+ thisaval, thisbval, Py_EQ);
+ if (cmp < 0) {
+ Py_DECREF(thiskey);
+ Py_DECREF(thisaval);
+ goto Fail;
+ }
+ }
+ if (cmp == 0) {
+ /* New winner. */
+ Py_XDECREF(akey);
+ Py_XDECREF(aval);
+ akey = thiskey;
+ aval = thisaval;
+ }
+ else {
+ Py_DECREF(thiskey);
+ Py_DECREF(thisaval);
+ }
+ }
+ *pval = aval;
+ return akey;
+
+Fail:
+ Py_XDECREF(akey);
+ Py_XDECREF(aval);
+ *pval = NULL;
+ return NULL;
+}
+
+static int
+dict_compare(PyDictObject *a, PyDictObject *b)
+{
+ PyObject *adiff, *bdiff, *aval, *bval;
+ int res;
+
+ /* Compare lengths first */
+ if (a->ma_used < b->ma_used)
+ return -1; /* a is shorter */
+ else if (a->ma_used > b->ma_used)
+ return 1; /* b is shorter */
+
+ /* Same length -- check all keys */
+ bdiff = bval = NULL;
+ adiff = characterize(a, b, &aval);
+ if (adiff == NULL) {
+ assert(!aval);
+ /* Either an error, or a is a subset with the same length so
+ * must be equal.
+ */
+ res = PyErr_Occurred() ? -1 : 0;
+ goto Finished;
+ }
+ bdiff = characterize(b, a, &bval);
+ if (bdiff == NULL && PyErr_Occurred()) {
+ assert(!bval);
+ res = -1;
+ goto Finished;
+ }
+ res = 0;
+ if (bdiff) {
+ /* bdiff == NULL "should be" impossible now, but perhaps
+ * the last comparison done by the characterize() on a had
+ * the side effect of making the dicts equal!
+ */
+ res = PyObject_Compare(adiff, bdiff);
+ }
+ if (res == 0 && bval != NULL)
+ res = PyObject_Compare(aval, bval);
+
+Finished:
+ Py_XDECREF(adiff);
+ Py_XDECREF(bdiff);
+ Py_XDECREF(aval);
+ Py_XDECREF(bval);
+ return res;
+}
+
+/* Return 1 if dicts equal, 0 if not, -1 if error.
+ * Gets out as soon as any difference is detected.
+ * Uses only Py_EQ comparison.
+ */
+static int
+dict_equal(PyDictObject *a, PyDictObject *b)
+{
+ Py_ssize_t i;
+
+ if (a->ma_used != b->ma_used)
+ /* can't be equal if # of entries differ */
+ return 0;
+
+ /* Same # of entries -- check all of 'em. Exit early on any diff. */
+ for (i = 0; i <= a->ma_mask; i++) {
+ PyObject *aval = a->ma_table[i].me_value;
+ if (aval != NULL) {
+ int cmp;
+ PyObject *bval;
+ PyObject *key = a->ma_table[i].me_key;
+ /* temporarily bump aval's refcount to ensure it stays
+ alive until we're done with it */
+ Py_INCREF(aval);
+ /* ditto for key */
+ Py_INCREF(key);
+ bval = PyDict_GetItem((PyObject *)b, key);
+ Py_DECREF(key);
+ if (bval == NULL) {
+ Py_DECREF(aval);
+ return 0;
+ }
+ cmp = PyObject_RichCompareBool(aval, bval, Py_EQ);
+ Py_DECREF(aval);
+ if (cmp <= 0) /* error or not equal */
+ return cmp;
+ }
+ }
+ return 1;
+ }
+
+static PyObject *
+dict_richcompare(PyObject *v, PyObject *w, int op)
+{
+ int cmp;
+ PyObject *res;
+
+ if (!PyDict_Check(v) || !PyDict_Check(w)) {
+ res = Py_NotImplemented;
+ }
+ else if (op == Py_EQ || op == Py_NE) {
+ cmp = dict_equal((PyDictObject *)v, (PyDictObject *)w);
+ if (cmp < 0)
+ return NULL;
+ res = (cmp == (op == Py_EQ)) ? Py_True : Py_False;
+ }
+ else {
+ /* Py3K warning if comparison isn't == or != */
+ if (PyErr_WarnPy3k("dict inequality comparisons not supported "
+ "in 3.x", 1) < 0) {
+ return NULL;
+ }
+ res = Py_NotImplemented;
+ }
+ Py_INCREF(res);
+ return res;
+ }
+
+static PyObject *
+dict_contains(register PyDictObject *mp, PyObject *key)
+{
+ long hash;
+ PyDictEntry *ep;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return NULL;
+ return PyBool_FromLong(ep->me_value != NULL);
+}
+
+static PyObject *
+dict_has_key(register PyDictObject *mp, PyObject *key)
+{
+ if (PyErr_WarnPy3k("dict.has_key() not supported in 3.x; "
+ "use the in operator", 1) < 0)
+ return NULL;
+ return dict_contains(mp, key);
+}
+
+static PyObject *
+dict_get(register PyDictObject *mp, PyObject *args)
+{
+ PyObject *key;
+ PyObject *failobj = Py_None;
+ PyObject *val = NULL;
+ long hash;
+ PyDictEntry *ep;
+
+ if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
+ return NULL;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return NULL;
+ val = ep->me_value;
+ if (val == NULL)
+ val = failobj;
+ Py_INCREF(val);
+ return val;
+}
+
+
+static PyObject *
+dict_setdefault(register PyDictObject *mp, PyObject *args)
+{
+ PyObject *key;
+ PyObject *failobj = Py_None;
+ PyObject *val = NULL;
+ long hash;
+ PyDictEntry *ep;
+
+ if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
+ return NULL;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return NULL;
+ val = ep->me_value;
+ if (val == NULL) {
+ if (dict_set_item_by_hash_or_entry((PyObject*)mp, key, hash, ep,
+ failobj) == 0)
+ val = failobj;
+ }
+ Py_XINCREF(val);
+ return val;
+}
+
+
+static PyObject *
+dict_clear(register PyDictObject *mp)
+{
+ PyDict_Clear((PyObject *)mp);
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+dict_pop(PyDictObject *mp, PyObject *args)
+{
+ long hash;
+ PyDictEntry *ep;
+ PyObject *old_value, *old_key;
+ PyObject *key, *deflt = NULL;
+
+ if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt))
+ return NULL;
+ if (mp->ma_used == 0) {
+ if (deflt) {
+ Py_INCREF(deflt);
+ return deflt;
+ }
+ set_key_error(key);
+ return NULL;
+ }
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return NULL;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ if (ep == NULL)
+ return NULL;
+ if (ep->me_value == NULL) {
+ if (deflt) {
+ Py_INCREF(deflt);
+ return deflt;
+ }
+ set_key_error(key);
+ return NULL;
+ }
+ old_key = ep->me_key;
+ Py_INCREF(dummy);
+ ep->me_key = dummy;
+ old_value = ep->me_value;
+ ep->me_value = NULL;
+ mp->ma_used--;
+ Py_DECREF(old_key);
+ return old_value;
+}
+
+static PyObject *
+dict_popitem(PyDictObject *mp)
+{
+ Py_ssize_t i = 0;
+ PyDictEntry *ep;
+ PyObject *res;
+
+ /* Allocate the result tuple before checking the size. Believe it
+ * or not, this allocation could trigger a garbage collection which
+ * could empty the dict, so if we checked the size first and that
+ * happened, the result would be an infinite loop (searching for an
+ * entry that no longer exists). Note that the usual popitem()
+ * idiom is "while d: k, v = d.popitem()". so needing to throw the
+ * tuple away if the dict *is* empty isn't a significant
+ * inefficiency -- possible, but unlikely in practice.
+ */
+ res = PyTuple_New(2);
+ if (res == NULL)
+ return NULL;
+ if (mp->ma_used == 0) {
+ Py_DECREF(res);
+ PyErr_SetString(PyExc_KeyError,
+ "popitem(): dictionary is empty");
+ return NULL;
+ }
+ /* Set ep to "the first" dict entry with a value. We abuse the hash
+ * field of slot 0 to hold a search finger:
+ * If slot 0 has a value, use slot 0.
+ * Else slot 0 is being used to hold a search finger,
+ * and we use its hash value as the first index to look.
+ */
+ ep = &mp->ma_table[0];
+ if (ep->me_value == NULL) {
+ i = ep->me_hash;
+ /* The hash field may be a real hash value, or it may be a
+ * legit search finger, or it may be a once-legit search
+ * finger that's out of bounds now because it wrapped around
+ * or the table shrunk -- simply make sure it's in bounds now.
+ */
+ if (i > mp->ma_mask || i < 1)
+ i = 1; /* skip slot 0 */
+ while ((ep = &mp->ma_table[i])->me_value == NULL) {
+ i++;
+ if (i > mp->ma_mask)
+ i = 1;
+ }
+ }
+ PyTuple_SET_ITEM(res, 0, ep->me_key);
+ PyTuple_SET_ITEM(res, 1, ep->me_value);
+ Py_INCREF(dummy);
+ ep->me_key = dummy;
+ ep->me_value = NULL;
+ mp->ma_used--;
+ assert(mp->ma_table[0].me_value == NULL);
+ mp->ma_table[0].me_hash = i + 1; /* next place to start */
+ return res;
+}
+
+static int
+dict_traverse(PyObject *op, visitproc visit, void *arg)
+{
+ Py_ssize_t i = 0;
+ PyObject *pk;
+ PyObject *pv;
+
+ while (PyDict_Next(op, &i, &pk, &pv)) {
+ Py_VISIT(pk);
+ Py_VISIT(pv);
+ }
+ return 0;
+}
+
+static int
+dict_tp_clear(PyObject *op)
+{
+ PyDict_Clear(op);
+ return 0;
+}
+
+
+extern PyTypeObject PyDictIterKey_Type; /* Forward */
+extern PyTypeObject PyDictIterValue_Type; /* Forward */
+extern PyTypeObject PyDictIterItem_Type; /* Forward */
+static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
+
+static PyObject *
+dict_iterkeys(PyDictObject *dict)
+{
+ return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+static PyObject *
+dict_itervalues(PyDictObject *dict)
+{
+ return dictiter_new(dict, &PyDictIterValue_Type);
+}
+
+static PyObject *
+dict_iteritems(PyDictObject *dict)
+{
+ return dictiter_new(dict, &PyDictIterItem_Type);
+}
+
+static PyObject *
+dict_sizeof(PyDictObject *mp)
+{
+ Py_ssize_t res;
+
+ res = sizeof(PyDictObject);
+ if (mp->ma_table != mp->ma_smalltable)
+ res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry);
+ return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(has_key__doc__,
+"D.has_key(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(contains__doc__,
+"D.__contains__(k) -> True if D has a key k, else False");
+
+PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
+
+PyDoc_STRVAR(sizeof__doc__,
+"D.__sizeof__() -> size of D in memory, in bytes");
+
+PyDoc_STRVAR(get__doc__,
+"D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.");
+
+PyDoc_STRVAR(setdefault_doc__,
+"D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D");
+
+PyDoc_STRVAR(pop__doc__,
+"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n\
+If key is not found, d is returned if given, otherwise KeyError is raised");
+
+PyDoc_STRVAR(popitem__doc__,
+"D.popitem() -> (k, v), remove and return some (key, value) pair as a\n\
+2-tuple; but raise KeyError if D is empty.");
+
+PyDoc_STRVAR(keys__doc__,
+"D.keys() -> list of D's keys");
+
+PyDoc_STRVAR(items__doc__,
+"D.items() -> list of D's (key, value) pairs, as 2-tuples");
+
+PyDoc_STRVAR(values__doc__,
+"D.values() -> list of D's values");
+
+PyDoc_STRVAR(update__doc__,
+"D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n"
+"If E present and has a .keys() method, does: for k in E: D[k] = E[k]\n\
+If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v\n\
+In either case, this is followed by: for k in F: D[k] = F[k]");
+
+PyDoc_STRVAR(fromkeys__doc__,
+"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\
+v defaults to None.");
+
+PyDoc_STRVAR(clear__doc__,
+"D.clear() -> None. Remove all items from D.");
+
+PyDoc_STRVAR(copy__doc__,
+"D.copy() -> a shallow copy of D");
+
+PyDoc_STRVAR(iterkeys__doc__,
+"D.iterkeys() -> an iterator over the keys of D");
+
+PyDoc_STRVAR(itervalues__doc__,
+"D.itervalues() -> an iterator over the values of D");
+
+PyDoc_STRVAR(iteritems__doc__,
+"D.iteritems() -> an iterator over the (key, value) items of D");
+
+/* Forward */
+static PyObject *dictkeys_new(PyObject *);
+static PyObject *dictitems_new(PyObject *);
+static PyObject *dictvalues_new(PyObject *);
+
+PyDoc_STRVAR(viewkeys__doc__,
+ "D.viewkeys() -> a set-like object providing a view on D's keys");
+PyDoc_STRVAR(viewitems__doc__,
+ "D.viewitems() -> a set-like object providing a view on D's items");
+PyDoc_STRVAR(viewvalues__doc__,
+ "D.viewvalues() -> an object providing a view on D's values");
+
+static PyMethodDef mapp_methods[] = {
+ {"__contains__",(PyCFunction)dict_contains, METH_O | METH_COEXIST,
+ contains__doc__},
+ {"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST,
+ getitem__doc__},
+ {"__sizeof__", (PyCFunction)dict_sizeof, METH_NOARGS,
+ sizeof__doc__},
+ {"has_key", (PyCFunction)dict_has_key, METH_O,
+ has_key__doc__},
+ {"get", (PyCFunction)dict_get, METH_VARARGS,
+ get__doc__},
+ {"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS,
+ setdefault_doc__},
+ {"pop", (PyCFunction)dict_pop, METH_VARARGS,
+ pop__doc__},
+ {"popitem", (PyCFunction)dict_popitem, METH_NOARGS,
+ popitem__doc__},
+ {"keys", (PyCFunction)dict_keys, METH_NOARGS,
+ keys__doc__},
+ {"items", (PyCFunction)dict_items, METH_NOARGS,
+ items__doc__},
+ {"values", (PyCFunction)dict_values, METH_NOARGS,
+ values__doc__},
+ {"viewkeys", (PyCFunction)dictkeys_new, METH_NOARGS,
+ viewkeys__doc__},
+ {"viewitems", (PyCFunction)dictitems_new, METH_NOARGS,
+ viewitems__doc__},
+ {"viewvalues", (PyCFunction)dictvalues_new, METH_NOARGS,
+ viewvalues__doc__},
+ {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS,
+ update__doc__},
+ {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS,
+ fromkeys__doc__},
+ {"clear", (PyCFunction)dict_clear, METH_NOARGS,
+ clear__doc__},
+ {"copy", (PyCFunction)dict_copy, METH_NOARGS,
+ copy__doc__},
+ {"iterkeys", (PyCFunction)dict_iterkeys, METH_NOARGS,
+ iterkeys__doc__},
+ {"itervalues", (PyCFunction)dict_itervalues, METH_NOARGS,
+ itervalues__doc__},
+ {"iteritems", (PyCFunction)dict_iteritems, METH_NOARGS,
+ iteritems__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+/* Return 1 if `key` is in dict `op`, 0 if not, and -1 on error. */
+int
+PyDict_Contains(PyObject *op, PyObject *key)
+{
+ long hash;
+ PyDictObject *mp = (PyDictObject *)op;
+ PyDictEntry *ep;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ ep = (mp->ma_lookup)(mp, key, hash);
+ return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Internal version of PyDict_Contains used when the hash value is already known */
+int
+_PyDict_Contains(PyObject *op, PyObject *key, long hash)
+{
+ PyDictObject *mp = (PyDictObject *)op;
+ PyDictEntry *ep;
+
+ ep = (mp->ma_lookup)(mp, key, hash);
+ return ep == NULL ? -1 : (ep->me_value != NULL);
+}
+
+/* Hack to implement "key in dict" */
+static PySequenceMethods dict_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ PyDict_Contains, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+};
+
+static PyObject *
+dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = type->tp_alloc(type, 0);
+ if (self != NULL) {
+ PyDictObject *d = (PyDictObject *)self;
+ /* It's guaranteed that tp->alloc zeroed out the struct. */
+ assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
+ INIT_NONZERO_DICT_SLOTS(d);
+ d->ma_lookup = lookdict_string;
+ /* The object has been implicitly tracked by tp_alloc */
+ if (type == &PyDict_Type)
+ _PyObject_GC_UNTRACK(d);
+#ifdef SHOW_CONVERSION_COUNTS
+ ++created;
+#endif
+#ifdef SHOW_TRACK_COUNT
+ if (_PyObject_GC_IS_TRACKED(d))
+ count_tracked++;
+ else
+ count_untracked++;
+#endif
+ }
+ return self;
+}
+
+static int
+dict_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ return dict_update_common(self, args, kwds, "dict");
+}
+
+static PyObject *
+dict_iter(PyDictObject *dict)
+{
+ return dictiter_new(dict, &PyDictIterKey_Type);
+}
+
+PyDoc_STRVAR(dictionary_doc,
+"dict() -> new empty dictionary\n"
+"dict(mapping) -> new dictionary initialized from a mapping object's\n"
+" (key, value) pairs\n"
+"dict(iterable) -> new dictionary initialized as if via:\n"
+" d = {}\n"
+" for k, v in iterable:\n"
+" d[k] = v\n"
+"dict(**kwargs) -> new dictionary initialized with the name=value pairs\n"
+" in the keyword argument list. For example: dict(one=1, two=2)");
+
+PyTypeObject PyDict_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict",
+ sizeof(PyDictObject),
+ 0,
+ (destructor)dict_dealloc, /* tp_dealloc */
+ (printfunc)dict_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)dict_compare, /* tp_compare */
+ (reprfunc)dict_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &dict_as_sequence, /* tp_as_sequence */
+ &dict_as_mapping, /* tp_as_mapping */
+ (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */
+ dictionary_doc, /* tp_doc */
+ dict_traverse, /* tp_traverse */
+ dict_tp_clear, /* tp_clear */
+ dict_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dict_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ mapp_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ dict_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ dict_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/* For backward compatibility with old dictionary interface */
+
+PyObject *
+PyDict_GetItemString(PyObject *v, const char *key)
+{
+ PyObject *kv, *rv;
+ kv = PyString_FromString(key);
+ if (kv == NULL)
+ return NULL;
+ rv = PyDict_GetItem(v, kv);
+ Py_DECREF(kv);
+ return rv;
+}
+
+int
+PyDict_SetItemString(PyObject *v, const char *key, PyObject *item)
+{
+ PyObject *kv;
+ int err;
+ kv = PyString_FromString(key);
+ if (kv == NULL)
+ return -1;
+ PyString_InternInPlace(&kv); /* XXX Should we really? */
+ err = PyDict_SetItem(v, kv, item);
+ Py_DECREF(kv);
+ return err;
+}
+
+int
+PyDict_DelItemString(PyObject *v, const char *key)
+{
+ PyObject *kv;
+ int err;
+ kv = PyString_FromString(key);
+ if (kv == NULL)
+ return -1;
+ err = PyDict_DelItem(v, kv);
+ Py_DECREF(kv);
+ return err;
+}
+
+/* Dictionary iterator types */
+
+typedef struct {
+ PyObject_HEAD
+ PyDictObject *di_dict; /* Set to NULL when iterator is exhausted */
+ Py_ssize_t di_used;
+ Py_ssize_t di_pos;
+ PyObject* di_result; /* reusable result tuple for iteritems */
+ Py_ssize_t len;
+} dictiterobject;
+
+static PyObject *
+dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
+{
+ dictiterobject *di;
+ di = PyObject_GC_New(dictiterobject, itertype);
+ if (di == NULL)
+ return NULL;
+ Py_INCREF(dict);
+ di->di_dict = dict;
+ di->di_used = dict->ma_used;
+ di->di_pos = 0;
+ di->len = dict->ma_used;
+ if (itertype == &PyDictIterItem_Type) {
+ di->di_result = PyTuple_Pack(2, Py_None, Py_None);
+ if (di->di_result == NULL) {
+ Py_DECREF(di);
+ return NULL;
+ }
+ }
+ else
+ di->di_result = NULL;
+ _PyObject_GC_TRACK(di);
+ return (PyObject *)di;
+}
+
+static void
+dictiter_dealloc(dictiterobject *di)
+{
+ Py_XDECREF(di->di_dict);
+ Py_XDECREF(di->di_result);
+ PyObject_GC_Del(di);
+}
+
+static int
+dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
+{
+ Py_VISIT(di->di_dict);
+ Py_VISIT(di->di_result);
+ return 0;
+}
+
+static PyObject *
+dictiter_len(dictiterobject *di)
+{
+ Py_ssize_t len = 0;
+ if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
+ len = di->len;
+ return PyInt_FromSize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dictiter_methods[] = {
+ {"__length_hint__", (PyCFunction)dictiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *dictiter_iternextkey(dictiterobject *di)
+{
+ PyObject *key;
+ register Py_ssize_t i, mask;
+ register PyDictEntry *ep;
+ PyDictObject *d = di->di_dict;
+
+ if (d == NULL)
+ return NULL;
+ assert (PyDict_Check(d));
+
+ if (di->di_used != d->ma_used) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "dictionary changed size during iteration");
+ di->di_used = -1; /* Make this state sticky */
+ return NULL;
+ }
+
+ i = di->di_pos;
+ if (i < 0)
+ goto fail;
+ ep = d->ma_table;
+ mask = d->ma_mask;
+ while (i <= mask && ep[i].me_value == NULL)
+ i++;
+ di->di_pos = i+1;
+ if (i > mask)
+ goto fail;
+ di->len--;
+ key = ep[i].me_key;
+ Py_INCREF(key);
+ return key;
+
+fail:
+ Py_DECREF(d);
+ di->di_dict = NULL;
+ return NULL;
+}
+
+PyTypeObject PyDictIterKey_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dictionary-keyiterator", /* tp_name */
+ sizeof(dictiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dictiter_iternextkey, /* tp_iternext */
+ dictiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *dictiter_iternextvalue(dictiterobject *di)
+{
+ PyObject *value;
+ register Py_ssize_t i, mask;
+ register PyDictEntry *ep;
+ PyDictObject *d = di->di_dict;
+
+ if (d == NULL)
+ return NULL;
+ assert (PyDict_Check(d));
+
+ if (di->di_used != d->ma_used) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "dictionary changed size during iteration");
+ di->di_used = -1; /* Make this state sticky */
+ return NULL;
+ }
+
+ i = di->di_pos;
+ mask = d->ma_mask;
+ if (i < 0 || i > mask)
+ goto fail;
+ ep = d->ma_table;
+ while ((value=ep[i].me_value) == NULL) {
+ i++;
+ if (i > mask)
+ goto fail;
+ }
+ di->di_pos = i+1;
+ di->len--;
+ Py_INCREF(value);
+ return value;
+
+fail:
+ Py_DECREF(d);
+ di->di_dict = NULL;
+ return NULL;
+}
+
+PyTypeObject PyDictIterValue_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dictionary-valueiterator", /* tp_name */
+ sizeof(dictiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dictiter_iternextvalue, /* tp_iternext */
+ dictiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *dictiter_iternextitem(dictiterobject *di)
+{
+ PyObject *key, *value, *result = di->di_result;
+ register Py_ssize_t i, mask;
+ register PyDictEntry *ep;
+ PyDictObject *d = di->di_dict;
+
+ if (d == NULL)
+ return NULL;
+ assert (PyDict_Check(d));
+
+ if (di->di_used != d->ma_used) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "dictionary changed size during iteration");
+ di->di_used = -1; /* Make this state sticky */
+ return NULL;
+ }
+
+ i = di->di_pos;
+ if (i < 0)
+ goto fail;
+ ep = d->ma_table;
+ mask = d->ma_mask;
+ while (i <= mask && ep[i].me_value == NULL)
+ i++;
+ di->di_pos = i+1;
+ if (i > mask)
+ goto fail;
+
+ if (result->ob_refcnt == 1) {
+ Py_INCREF(result);
+ Py_DECREF(PyTuple_GET_ITEM(result, 0));
+ Py_DECREF(PyTuple_GET_ITEM(result, 1));
+ } else {
+ result = PyTuple_New(2);
+ if (result == NULL)
+ return NULL;
+ }
+ di->len--;
+ key = ep[i].me_key;
+ value = ep[i].me_value;
+ Py_INCREF(key);
+ Py_INCREF(value);
+ PyTuple_SET_ITEM(result, 0, key);
+ PyTuple_SET_ITEM(result, 1, value);
+ return result;
+
+fail:
+ Py_DECREF(d);
+ di->di_dict = NULL;
+ return NULL;
+}
+
+PyTypeObject PyDictIterItem_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dictionary-itemiterator", /* tp_name */
+ sizeof(dictiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)dictiter_iternextitem, /* tp_iternext */
+ dictiter_methods, /* tp_methods */
+ 0,
+};
+
+/***********************************************/
+/* View objects for keys(), items(), values(). */
+/***********************************************/
+
+/* The instance lay-out is the same for all three; but the type differs. */
+
+typedef struct {
+ PyObject_HEAD
+ PyDictObject *dv_dict;
+} dictviewobject;
+
+
+static void
+dictview_dealloc(dictviewobject *dv)
+{
+ Py_XDECREF(dv->dv_dict);
+ PyObject_GC_Del(dv);
+}
+
+static int
+dictview_traverse(dictviewobject *dv, visitproc visit, void *arg)
+{
+ Py_VISIT(dv->dv_dict);
+ return 0;
+}
+
+static Py_ssize_t
+dictview_len(dictviewobject *dv)
+{
+ Py_ssize_t len = 0;
+ if (dv->dv_dict != NULL)
+ len = dv->dv_dict->ma_used;
+ return len;
+}
+
+static PyObject *
+dictview_new(PyObject *dict, PyTypeObject *type)
+{
+ dictviewobject *dv;
+ if (dict == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (!PyDict_Check(dict)) {
+ /* XXX Get rid of this restriction later */
+ PyErr_Format(PyExc_TypeError,
+ "%s() requires a dict argument, not '%s'",
+ type->tp_name, dict->ob_type->tp_name);
+ return NULL;
+ }
+ dv = PyObject_GC_New(dictviewobject, type);
+ if (dv == NULL)
+ return NULL;
+ Py_INCREF(dict);
+ dv->dv_dict = (PyDictObject *)dict;
+ _PyObject_GC_TRACK(dv);
+ return (PyObject *)dv;
+}
+
+/* TODO(guido): The views objects are not complete:
+
+ * support more set operations
+ * support arbitrary mappings?
+ - either these should be static or exported in dictobject.h
+ - if public then they should probably be in builtins
+*/
+
+/* Return 1 if self is a subset of other, iterating over self;
+ 0 if not; -1 if an error occurred. */
+static int
+all_contained_in(PyObject *self, PyObject *other)
+{
+ PyObject *iter = PyObject_GetIter(self);
+ int ok = 1;
+
+ if (iter == NULL)
+ return -1;
+ for (;;) {
+ PyObject *next = PyIter_Next(iter);
+ if (next == NULL) {
+ if (PyErr_Occurred())
+ ok = -1;
+ break;
+ }
+ ok = PySequence_Contains(other, next);
+ Py_DECREF(next);
+ if (ok <= 0)
+ break;
+ }
+ Py_DECREF(iter);
+ return ok;
+}
+
+static PyObject *
+dictview_richcompare(PyObject *self, PyObject *other, int op)
+{
+ Py_ssize_t len_self, len_other;
+ int ok;
+ PyObject *result;
+
+ assert(self != NULL);
+ assert(PyDictViewSet_Check(self));
+ assert(other != NULL);
+
+ if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ len_self = PyObject_Size(self);
+ if (len_self < 0)
+ return NULL;
+ len_other = PyObject_Size(other);
+ if (len_other < 0)
+ return NULL;
+
+ ok = 0;
+ switch(op) {
+
+ case Py_NE:
+ case Py_EQ:
+ if (len_self == len_other)
+ ok = all_contained_in(self, other);
+ if (op == Py_NE && ok >= 0)
+ ok = !ok;
+ break;
+
+ case Py_LT:
+ if (len_self < len_other)
+ ok = all_contained_in(self, other);
+ break;
+
+ case Py_LE:
+ if (len_self <= len_other)
+ ok = all_contained_in(self, other);
+ break;
+
+ case Py_GT:
+ if (len_self > len_other)
+ ok = all_contained_in(other, self);
+ break;
+
+ case Py_GE:
+ if (len_self >= len_other)
+ ok = all_contained_in(other, self);
+ break;
+
+ }
+ if (ok < 0)
+ return NULL;
+ result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+dictview_repr(dictviewobject *dv)
+{
+ PyObject *seq;
+ PyObject *seq_str;
+ PyObject *result;
+
+ seq = PySequence_List((PyObject *)dv);
+ if (seq == NULL)
+ return NULL;
+
+ seq_str = PyObject_Repr(seq);
+ if (seq_str == NULL) {
+ Py_DECREF(seq);
+ return NULL;
+ }
+ result = PyString_FromFormat("%s(%s)", Py_TYPE(dv)->tp_name,
+ PyString_AS_STRING(seq_str));
+ Py_DECREF(seq_str);
+ Py_DECREF(seq);
+ return result;
+}
+
+/*** dict_keys ***/
+
+static PyObject *
+dictkeys_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
+}
+
+static int
+dictkeys_contains(dictviewobject *dv, PyObject *obj)
+{
+ if (dv->dv_dict == NULL)
+ return 0;
+ return PyDict_Contains((PyObject *)dv->dv_dict, obj);
+}
+
+static PySequenceMethods dictkeys_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)dictkeys_contains, /* sq_contains */
+};
+
+static PyObject*
+dictviews_sub(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "difference_update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_and(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "intersection_update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_or(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_xor(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O",
+ other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyNumberMethods dictviews_as_number = {
+ 0, /*nb_add*/
+ (binaryfunc)dictviews_sub, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ 0, /*nb_remainder*/
+ 0, /*nb_divmod*/
+ 0, /*nb_power*/
+ 0, /*nb_negative*/
+ 0, /*nb_positive*/
+ 0, /*nb_absolute*/
+ 0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ (binaryfunc)dictviews_and, /*nb_and*/
+ (binaryfunc)dictviews_xor, /*nb_xor*/
+ (binaryfunc)dictviews_or, /*nb_or*/
+};
+
+static PyMethodDef dictkeys_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictKeys_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_keys", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ &dictviews_as_number, /* tp_as_number */
+ &dictkeys_as_sequence, /* 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 | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ dictview_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictkeys_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictkeys_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictkeys_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictKeys_Type);
+}
+
+/*** dict_items ***/
+
+static PyObject *
+dictitems_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
+}
+
+static int
+dictitems_contains(dictviewobject *dv, PyObject *obj)
+{
+ PyObject *key, *value, *found;
+ if (dv->dv_dict == NULL)
+ return 0;
+ if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
+ return 0;
+ key = PyTuple_GET_ITEM(obj, 0);
+ value = PyTuple_GET_ITEM(obj, 1);
+ found = PyDict_GetItem((PyObject *)dv->dv_dict, key);
+ if (found == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+ }
+ return PyObject_RichCompareBool(value, found, Py_EQ);
+}
+
+static PySequenceMethods dictitems_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)dictitems_contains, /* sq_contains */
+};
+
+static PyMethodDef dictitems_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictItems_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_items", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ &dictviews_as_number, /* tp_as_number */
+ &dictitems_as_sequence, /* 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 | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ dictview_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictitems_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictitems_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictitems_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictItems_Type);
+}
+
+/*** dict_values ***/
+
+static PyObject *
+dictvalues_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
+}
+
+static PySequenceMethods dictvalues_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)0, /* sq_contains */
+};
+
+static PyMethodDef dictvalues_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictValues_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_values", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &dictvalues_as_sequence, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictvalues_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictvalues_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictvalues_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictValues_Type);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/enumobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/enumobject.c
new file mode 100644
index 0000000000..9b6de23ab1
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/enumobject.c
@@ -0,0 +1,381 @@
+/* enumerate object */
+
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t en_index; /* current index of enumeration */
+ PyObject* en_sit; /* secondary iterator of enumeration */
+ PyObject* en_result; /* result tuple */
+ PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */
+} enumobject;
+
+static PyObject *
+enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ enumobject *en;
+ PyObject *seq = NULL;
+ PyObject *start = NULL;
+ static char *kwlist[] = {"sequence", "start", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
+ &seq, &start))
+ return NULL;
+
+ en = (enumobject *)type->tp_alloc(type, 0);
+ if (en == NULL)
+ return NULL;
+ if (start != NULL) {
+ start = PyNumber_Index(start);
+ if (start == NULL) {
+ Py_DECREF(en);
+ return NULL;
+ }
+ assert(PyInt_Check(start) || PyLong_Check(start));
+ en->en_index = PyInt_AsSsize_t(start);
+ if (en->en_index == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ en->en_index = PY_SSIZE_T_MAX;
+ en->en_longindex = start;
+ } else {
+ en->en_longindex = NULL;
+ Py_DECREF(start);
+ }
+ } else {
+ en->en_index = 0;
+ en->en_longindex = NULL;
+ }
+ en->en_sit = PyObject_GetIter(seq);
+ if (en->en_sit == NULL) {
+ Py_DECREF(en);
+ return NULL;
+ }
+ en->en_result = PyTuple_Pack(2, Py_None, Py_None);
+ if (en->en_result == NULL) {
+ Py_DECREF(en);
+ return NULL;
+ }
+ return (PyObject *)en;
+}
+
+static void
+enum_dealloc(enumobject *en)
+{
+ PyObject_GC_UnTrack(en);
+ Py_XDECREF(en->en_sit);
+ Py_XDECREF(en->en_result);
+ Py_XDECREF(en->en_longindex);
+ Py_TYPE(en)->tp_free(en);
+}
+
+static int
+enum_traverse(enumobject *en, visitproc visit, void *arg)
+{
+ Py_VISIT(en->en_sit);
+ Py_VISIT(en->en_result);
+ Py_VISIT(en->en_longindex);
+ return 0;
+}
+
+static PyObject *
+enum_next_long(enumobject *en, PyObject* next_item)
+{
+ static PyObject *one = NULL;
+ PyObject *result = en->en_result;
+ PyObject *next_index;
+ PyObject *stepped_up;
+
+ if (en->en_longindex == NULL) {
+ en->en_longindex = PyInt_FromSsize_t(PY_SSIZE_T_MAX);
+ if (en->en_longindex == NULL)
+ return NULL;
+ }
+ if (one == NULL) {
+ one = PyInt_FromLong(1);
+ if (one == NULL)
+ return NULL;
+ }
+ next_index = en->en_longindex;
+ assert(next_index != NULL);
+ stepped_up = PyNumber_Add(next_index, one);
+ if (stepped_up == NULL)
+ return NULL;
+ en->en_longindex = stepped_up;
+
+ if (result->ob_refcnt == 1) {
+ Py_INCREF(result);
+ Py_DECREF(PyTuple_GET_ITEM(result, 0));
+ Py_DECREF(PyTuple_GET_ITEM(result, 1));
+ } else {
+ result = PyTuple_New(2);
+ if (result == NULL) {
+ Py_DECREF(next_index);
+ Py_DECREF(next_item);
+ return NULL;
+ }
+ }
+ PyTuple_SET_ITEM(result, 0, next_index);
+ PyTuple_SET_ITEM(result, 1, next_item);
+ return result;
+}
+
+static PyObject *
+enum_next(enumobject *en)
+{
+ PyObject *next_index;
+ PyObject *next_item;
+ PyObject *result = en->en_result;
+ PyObject *it = en->en_sit;
+
+ next_item = (*Py_TYPE(it)->tp_iternext)(it);
+ if (next_item == NULL)
+ return NULL;
+
+ if (en->en_index == PY_SSIZE_T_MAX)
+ return enum_next_long(en, next_item);
+
+ next_index = PyInt_FromSsize_t(en->en_index);
+ if (next_index == NULL) {
+ Py_DECREF(next_item);
+ return NULL;
+ }
+ en->en_index++;
+
+ if (result->ob_refcnt == 1) {
+ Py_INCREF(result);
+ Py_DECREF(PyTuple_GET_ITEM(result, 0));
+ Py_DECREF(PyTuple_GET_ITEM(result, 1));
+ } else {
+ result = PyTuple_New(2);
+ if (result == NULL) {
+ Py_DECREF(next_index);
+ Py_DECREF(next_item);
+ return NULL;
+ }
+ }
+ PyTuple_SET_ITEM(result, 0, next_index);
+ PyTuple_SET_ITEM(result, 1, next_item);
+ return result;
+}
+
+PyDoc_STRVAR(enum_doc,
+"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
+"\n"
+"Return an enumerate object. iterable must be another object that supports\n"
+"iteration. The enumerate object yields pairs containing a count (from\n"
+"start, which defaults to zero) and a value yielded by the iterable argument.\n"
+"enumerate is useful for obtaining an indexed list:\n"
+" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
+
+PyTypeObject PyEnum_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "enumerate", /* tp_name */
+ sizeof(enumobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)enum_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ enum_doc, /* tp_doc */
+ (traverseproc)enum_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)enum_next, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* 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 */
+ PyType_GenericAlloc, /* tp_alloc */
+ enum_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/* Reversed Object ***************************************************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t index;
+ PyObject* seq;
+} reversedobject;
+
+static PyObject *
+reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t n;
+ PyObject *seq, *reversed_meth;
+ static PyObject *reversed_cache = NULL;
+ reversedobject *ro;
+
+ if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
+ return NULL;
+
+ if (PyInstance_Check(seq)) {
+ reversed_meth = PyObject_GetAttrString(seq, "__reversed__");
+ if (reversed_meth == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__",
+ &reversed_cache);
+ if (reversed_meth == NULL && PyErr_Occurred())
+ return NULL;
+ }
+ if (reversed_meth != NULL) {
+ PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
+ Py_DECREF(reversed_meth);
+ return res;
+ }
+
+ if (!PySequence_Check(seq)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument to reversed() must be a sequence");
+ return NULL;
+ }
+
+ n = PySequence_Size(seq);
+ if (n == -1)
+ return NULL;
+
+ ro = (reversedobject *)type->tp_alloc(type, 0);
+ if (ro == NULL)
+ return NULL;
+
+ ro->index = n-1;
+ Py_INCREF(seq);
+ ro->seq = seq;
+ return (PyObject *)ro;
+}
+
+static void
+reversed_dealloc(reversedobject *ro)
+{
+ PyObject_GC_UnTrack(ro);
+ Py_XDECREF(ro->seq);
+ Py_TYPE(ro)->tp_free(ro);
+}
+
+static int
+reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
+{
+ Py_VISIT(ro->seq);
+ return 0;
+}
+
+static PyObject *
+reversed_next(reversedobject *ro)
+{
+ PyObject *item;
+ Py_ssize_t index = ro->index;
+
+ if (index >= 0) {
+ item = PySequence_GetItem(ro->seq, index);
+ if (item != NULL) {
+ ro->index--;
+ return item;
+ }
+ if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+ PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ }
+ ro->index = -1;
+ Py_CLEAR(ro->seq);
+ return NULL;
+}
+
+PyDoc_STRVAR(reversed_doc,
+"reversed(sequence) -> reverse iterator over values of the sequence\n"
+"\n"
+"Return a reverse iterator");
+
+static PyObject *
+reversed_len(reversedobject *ro)
+{
+ Py_ssize_t position, seqsize;
+
+ if (ro->seq == NULL)
+ return PyInt_FromLong(0);
+ seqsize = PySequence_Size(ro->seq);
+ if (seqsize == -1)
+ return NULL;
+ position = ro->index + 1;
+ return PyInt_FromSsize_t((seqsize < position) ? 0 : position);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef reversediter_methods[] = {
+ {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyReversed_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "reversed", /* tp_name */
+ sizeof(reversedobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)reversed_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ reversed_doc, /* tp_doc */
+ (traverseproc)reversed_traverse,/* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)reversed_next, /* tp_iternext */
+ reversediter_methods, /* tp_methods */
+ 0, /* 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 */
+ PyType_GenericAlloc, /* tp_alloc */
+ reversed_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/exceptions.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/exceptions.c
new file mode 100644
index 0000000000..d637fe3a37
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/exceptions.c
@@ -0,0 +1,2231 @@
+/*
+ * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
+ *
+ * Thanks go to Tim Peters and Michael Hudson for debugging.
+ */
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include "structmember.h"
+#include "osdefs.h"
+
+#define EXC_MODULE_NAME "exceptions."
+
+/* NOTE: If the exception class hierarchy changes, don't forget to update
+ * Lib/test/exception_hierarchy.txt
+ */
+
+PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
+\n\
+Exceptions found here are defined both in the exceptions module and the\n\
+built-in namespace. It is recommended that user-defined exceptions\n\
+inherit from Exception. See the documentation for the exception\n\
+inheritance hierarchy.\n\
+");
+
+/*
+ * BaseException
+ */
+static PyObject *
+BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyBaseExceptionObject *self;
+
+ self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
+ if (!self)
+ return NULL;
+ /* the dict is created on the fly in PyObject_GenericSetAttr */
+ self->message = self->dict = NULL;
+
+ self->args = PyTuple_New(0);
+ if (!self->args) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ self->message = PyString_FromString("");
+ if (!self->message) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ return (PyObject *)self;
+}
+
+static int
+BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
+{
+ if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
+ return -1;
+
+ Py_DECREF(self->args);
+ self->args = args;
+ Py_INCREF(self->args);
+
+ if (PyTuple_GET_SIZE(self->args) == 1) {
+ Py_CLEAR(self->message);
+ self->message = PyTuple_GET_ITEM(self->args, 0);
+ Py_INCREF(self->message);
+ }
+ return 0;
+}
+
+static int
+BaseException_clear(PyBaseExceptionObject *self)
+{
+ Py_CLEAR(self->dict);
+ Py_CLEAR(self->args);
+ Py_CLEAR(self->message);
+ return 0;
+}
+
+static void
+BaseException_dealloc(PyBaseExceptionObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ BaseException_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->dict);
+ Py_VISIT(self->args);
+ Py_VISIT(self->message);
+ return 0;
+}
+
+static PyObject *
+BaseException_str(PyBaseExceptionObject *self)
+{
+ PyObject *out;
+
+ switch (PyTuple_GET_SIZE(self->args)) {
+ case 0:
+ out = PyString_FromString("");
+ break;
+ case 1:
+ out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
+ break;
+ default:
+ out = PyObject_Str(self->args);
+ break;
+ }
+
+ return out;
+}
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+BaseException_unicode(PyBaseExceptionObject *self)
+{
+ PyObject *out;
+
+ /* issue6108: if __str__ has been overridden in the subclass, unicode()
+ should return the message returned by __str__ as used to happen
+ before this method was implemented. */
+ if (Py_TYPE(self)->tp_str != (reprfunc)BaseException_str) {
+ PyObject *str;
+ /* Unlike PyObject_Str, tp_str can return unicode (i.e. return the
+ equivalent of unicode(e.__str__()) instead of unicode(str(e))). */
+ str = Py_TYPE(self)->tp_str((PyObject*)self);
+ if (str == NULL)
+ return NULL;
+ out = PyObject_Unicode(str);
+ Py_DECREF(str);
+ return out;
+ }
+
+ switch (PyTuple_GET_SIZE(self->args)) {
+ case 0:
+ out = PyUnicode_FromString("");
+ break;
+ case 1:
+ out = PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
+ break;
+ default:
+ out = PyObject_Unicode(self->args);
+ break;
+ }
+
+ return out;
+}
+#endif
+
+static PyObject *
+BaseException_repr(PyBaseExceptionObject *self)
+{
+ PyObject *repr_suffix;
+ PyObject *repr;
+ char *name;
+ char *dot;
+
+ repr_suffix = PyObject_Repr(self->args);
+ if (!repr_suffix)
+ return NULL;
+
+ name = (char *)Py_TYPE(self)->tp_name;
+ dot = strrchr(name, '.');
+ if (dot != NULL) name = dot+1;
+
+ repr = PyString_FromString(name);
+ if (!repr) {
+ Py_DECREF(repr_suffix);
+ return NULL;
+ }
+
+ PyString_ConcatAndDel(&repr, repr_suffix);
+ return repr;
+}
+
+/* Pickling support */
+static PyObject *
+BaseException_reduce(PyBaseExceptionObject *self)
+{
+ if (self->args && self->dict)
+ return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
+ else
+ return PyTuple_Pack(2, Py_TYPE(self), self->args);
+}
+
+/*
+ * Needed for backward compatibility, since exceptions used to store
+ * all their attributes in the __dict__. Code is taken from cPickle's
+ * load_build function.
+ */
+static PyObject *
+BaseException_setstate(PyObject *self, PyObject *state)
+{
+ PyObject *d_key, *d_value;
+ Py_ssize_t i = 0;
+
+ if (state != Py_None) {
+ if (!PyDict_Check(state)) {
+ PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
+ return NULL;
+ }
+ while (PyDict_Next(state, &i, &d_key, &d_value)) {
+ if (PyObject_SetAttr(self, d_key, d_value) < 0)
+ return NULL;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+
+static PyMethodDef BaseException_methods[] = {
+ {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
+ {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
+#ifdef Py_USING_UNICODE
+ {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
+#endif
+ {NULL, NULL, 0, NULL},
+};
+
+
+
+static PyObject *
+BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
+{
+ if (PyErr_WarnPy3k("__getitem__ not supported for exception "
+ "classes in 3.x; use args attribute", 1) < 0)
+ return NULL;
+ return PySequence_GetItem(self->args, index);
+}
+
+static PyObject *
+BaseException_getslice(PyBaseExceptionObject *self,
+ Py_ssize_t start, Py_ssize_t stop)
+{
+ if (PyErr_WarnPy3k("__getslice__ not supported for exception "
+ "classes in 3.x; use args attribute", 1) < 0)
+ return NULL;
+ return PySequence_GetSlice(self->args, start, stop);
+}
+
+static PySequenceMethods BaseException_as_sequence = {
+ 0, /* sq_length; */
+ 0, /* sq_concat; */
+ 0, /* sq_repeat; */
+ (ssizeargfunc)BaseException_getitem, /* sq_item; */
+ (ssizessizeargfunc)BaseException_getslice, /* sq_slice; */
+ 0, /* sq_ass_item; */
+ 0, /* sq_ass_slice; */
+ 0, /* sq_contains; */
+ 0, /* sq_inplace_concat; */
+ 0 /* sq_inplace_repeat; */
+};
+
+static PyObject *
+BaseException_get_dict(PyBaseExceptionObject *self)
+{
+ if (self->dict == NULL) {
+ self->dict = PyDict_New();
+ if (!self->dict)
+ return NULL;
+ }
+ Py_INCREF(self->dict);
+ return self->dict;
+}
+
+static int
+BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
+{
+ if (val == NULL) {
+ PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
+ return -1;
+ }
+ if (!PyDict_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
+ return -1;
+ }
+ Py_CLEAR(self->dict);
+ Py_INCREF(val);
+ self->dict = val;
+ return 0;
+}
+
+static PyObject *
+BaseException_get_args(PyBaseExceptionObject *self)
+{
+ if (self->args == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_INCREF(self->args);
+ return self->args;
+}
+
+static int
+BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
+{
+ PyObject *seq;
+ if (val == NULL) {
+ PyErr_SetString(PyExc_TypeError, "args may not be deleted");
+ return -1;
+ }
+ seq = PySequence_Tuple(val);
+ if (!seq)
+ return -1;
+ Py_CLEAR(self->args);
+ self->args = seq;
+ return 0;
+}
+
+static PyObject *
+BaseException_get_message(PyBaseExceptionObject *self)
+{
+ PyObject *msg;
+
+ /* if "message" is in self->dict, accessing a user-set message attribute */
+ if (self->dict &&
+ (msg = PyDict_GetItemString(self->dict, "message"))) {
+ Py_INCREF(msg);
+ return msg;
+ }
+
+ if (self->message == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "message attribute was deleted");
+ return NULL;
+ }
+
+ /* accessing the deprecated "builtin" message attribute of Exception */
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "BaseException.message has been deprecated as "
+ "of Python 2.6", 1) < 0)
+ return NULL;
+
+ Py_INCREF(self->message);
+ return self->message;
+}
+
+static int
+BaseException_set_message(PyBaseExceptionObject *self, PyObject *val)
+{
+ /* if val is NULL, delete the message attribute */
+ if (val == NULL) {
+ if (self->dict && PyDict_GetItemString(self->dict, "message")) {
+ if (PyDict_DelItemString(self->dict, "message") < 0)
+ return -1;
+ }
+ Py_CLEAR(self->message);
+ return 0;
+ }
+
+ /* else set it in __dict__, but may need to create the dict first */
+ if (self->dict == NULL) {
+ self->dict = PyDict_New();
+ if (!self->dict)
+ return -1;
+ }
+ return PyDict_SetItemString(self->dict, "message", val);
+}
+
+static PyGetSetDef BaseException_getset[] = {
+ {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
+ {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
+ {"message", (getter)BaseException_get_message,
+ (setter)BaseException_set_message},
+ {NULL},
+};
+
+
+static PyTypeObject _PyExc_BaseException = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ EXC_MODULE_NAME "BaseException", /*tp_name*/
+ sizeof(PyBaseExceptionObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)BaseException_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /* tp_compare; */
+ (reprfunc)BaseException_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &BaseException_as_sequence, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ (reprfunc)BaseException_str, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
+ PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
+ (traverseproc)BaseException_traverse, /* tp_traverse */
+ (inquiry)BaseException_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ BaseException_methods, /* tp_methods */
+ 0, /* tp_members */
+ BaseException_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
+ (initproc)BaseException_init, /* tp_init */
+ 0, /* tp_alloc */
+ BaseException_new, /* tp_new */
+};
+/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
+from the previous implmentation and also allowing Python objects to be used
+in the API */
+PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
+
+/* note these macros omit the last semicolon so the macro invocation may
+ * include it and not look strange.
+ */
+#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ EXC_MODULE_NAME # EXCNAME, \
+ sizeof(PyBaseExceptionObject), \
+ 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+ PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
+ (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+ 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
+ (initproc)BaseException_init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ EXC_MODULE_NAME # EXCNAME, \
+ sizeof(Py ## EXCSTORE ## Object), \
+ 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
+ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+ (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
+static PyTypeObject _PyExc_ ## EXCNAME = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ EXC_MODULE_NAME # EXCNAME, \
+ sizeof(Py ## EXCSTORE ## Object), 0, \
+ (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ (reprfunc)EXCSTR, 0, 0, 0, \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
+ PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
+ (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
+ EXCMEMBERS, 0, &_ ## EXCBASE, \
+ 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
+ (initproc)EXCSTORE ## _init, 0, BaseException_new,\
+}; \
+PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
+
+
+/*
+ * Exception extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, Exception,
+ "Common base class for all non-exit exceptions.");
+
+
+/*
+ * StandardError extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StandardError,
+ "Base class for all standard Python exceptions that do not represent\n"
+ "interpreter exiting.");
+
+
+/*
+ * TypeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, TypeError,
+ "Inappropriate argument type.");
+
+
+/*
+ * StopIteration extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, StopIteration,
+ "Signal the end from iterator.next().");
+
+
+/*
+ * GeneratorExit extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, GeneratorExit,
+ "Request that a generator exit.");
+
+
+/*
+ * SystemExit extends BaseException
+ */
+
+static int
+SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t size = PyTuple_GET_SIZE(args);
+
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+
+ if (size == 0)
+ return 0;
+ Py_CLEAR(self->code);
+ if (size == 1)
+ self->code = PyTuple_GET_ITEM(args, 0);
+ else if (size > 1)
+ self->code = args;
+ Py_INCREF(self->code);
+ return 0;
+}
+
+static int
+SystemExit_clear(PySystemExitObject *self)
+{
+ Py_CLEAR(self->code);
+ return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SystemExit_dealloc(PySystemExitObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ SystemExit_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->code);
+ return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef SystemExit_members[] = {
+ {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
+ PyDoc_STR("exception code")},
+ {NULL} /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
+ SystemExit_dealloc, 0, SystemExit_members, 0,
+ "Request to exit from the interpreter.");
+
+/*
+ * KeyboardInterrupt extends BaseException
+ */
+SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
+ "Program interrupted by user.");
+
+
+/*
+ * ImportError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ImportError,
+ "Import can't find module, or can't find name in module.");
+
+
+/*
+ * EnvironmentError extends StandardError
+ */
+
+/* Where a function has a single filename, such as open() or some
+ * of the os module functions, PyErr_SetFromErrnoWithFilename() is
+ * called, giving a third argument which is the filename. But, so
+ * that old code using in-place unpacking doesn't break, e.g.:
+ *
+ * except IOError, (errno, strerror):
+ *
+ * we hack args so that it only contains two items. This also
+ * means we need our own __str__() which prints out the filename
+ * when it was supplied.
+ */
+static int
+EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
+ PyObject *kwds)
+{
+ PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
+ PyObject *subslice = NULL;
+
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+
+ if (PyTuple_GET_SIZE(args) <= 1 || PyTuple_GET_SIZE(args) > 3) {
+ return 0;
+ }
+
+ if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
+ &myerrno, &strerror, &filename)) {
+ return -1;
+ }
+ Py_CLEAR(self->myerrno); /* replacing */
+ self->myerrno = myerrno;
+ Py_INCREF(self->myerrno);
+
+ Py_CLEAR(self->strerror); /* replacing */
+ self->strerror = strerror;
+ Py_INCREF(self->strerror);
+
+ /* self->filename will remain Py_None otherwise */
+ if (filename != NULL) {
+ Py_CLEAR(self->filename); /* replacing */
+ self->filename = filename;
+ Py_INCREF(self->filename);
+
+ subslice = PyTuple_GetSlice(args, 0, 2);
+ if (!subslice)
+ return -1;
+
+ Py_DECREF(self->args); /* replacing args */
+ self->args = subslice;
+ }
+ return 0;
+}
+
+static int
+EnvironmentError_clear(PyEnvironmentErrorObject *self)
+{
+ Py_CLEAR(self->myerrno);
+ Py_CLEAR(self->strerror);
+ Py_CLEAR(self->filename);
+ return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ EnvironmentError_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
+ void *arg)
+{
+ Py_VISIT(self->myerrno);
+ Py_VISIT(self->strerror);
+ Py_VISIT(self->filename);
+ return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyObject *
+EnvironmentError_str(PyEnvironmentErrorObject *self)
+{
+ PyObject *rtnval = NULL;
+
+ if (self->filename) {
+ PyObject *fmt;
+ PyObject *repr;
+ PyObject *tuple;
+
+ fmt = PyString_FromString("[Errno %s] %s: %s");
+ if (!fmt)
+ return NULL;
+
+ repr = PyObject_Repr(self->filename);
+ if (!repr) {
+ Py_DECREF(fmt);
+ return NULL;
+ }
+ tuple = PyTuple_New(3);
+ if (!tuple) {
+ Py_DECREF(repr);
+ Py_DECREF(fmt);
+ return NULL;
+ }
+
+ if (self->myerrno) {
+ Py_INCREF(self->myerrno);
+ PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 0, Py_None);
+ }
+ if (self->strerror) {
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(tuple, 1, self->strerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 1, Py_None);
+ }
+
+ PyTuple_SET_ITEM(tuple, 2, repr);
+
+ rtnval = PyString_Format(fmt, tuple);
+
+ Py_DECREF(fmt);
+ Py_DECREF(tuple);
+ }
+ else if (self->myerrno && self->strerror) {
+ PyObject *fmt;
+ PyObject *tuple;
+
+ fmt = PyString_FromString("[Errno %s] %s");
+ if (!fmt)
+ return NULL;
+
+ tuple = PyTuple_New(2);
+ if (!tuple) {
+ Py_DECREF(fmt);
+ return NULL;
+ }
+
+ if (self->myerrno) {
+ Py_INCREF(self->myerrno);
+ PyTuple_SET_ITEM(tuple, 0, self->myerrno);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 0, Py_None);
+ }
+ if (self->strerror) {
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(tuple, 1, self->strerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 1, Py_None);
+ }
+
+ rtnval = PyString_Format(fmt, tuple);
+
+ Py_DECREF(fmt);
+ Py_DECREF(tuple);
+ }
+ else
+ rtnval = BaseException_str((PyBaseExceptionObject *)self);
+
+ return rtnval;
+}
+
+static PyMemberDef EnvironmentError_members[] = {
+ {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
+ PyDoc_STR("exception errno")},
+ {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
+ PyDoc_STR("exception strerror")},
+ {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
+ PyDoc_STR("exception filename")},
+ {NULL} /* Sentinel */
+};
+
+
+static PyObject *
+EnvironmentError_reduce(PyEnvironmentErrorObject *self)
+{
+ PyObject *args = self->args;
+ PyObject *res = NULL, *tmp;
+
+ /* self->args is only the first two real arguments if there was a
+ * file name given to EnvironmentError. */
+ if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
+ args = PyTuple_New(3);
+ if (!args)
+ return NULL;
+
+ tmp = PyTuple_GET_ITEM(self->args, 0);
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(args, 0, tmp);
+
+ tmp = PyTuple_GET_ITEM(self->args, 1);
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(args, 1, tmp);
+
+ Py_INCREF(self->filename);
+ PyTuple_SET_ITEM(args, 2, self->filename);
+ } else
+ Py_INCREF(args);
+
+ if (self->dict)
+ res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
+ else
+ res = PyTuple_Pack(2, Py_TYPE(self), args);
+ Py_DECREF(args);
+ return res;
+}
+
+
+static PyMethodDef EnvironmentError_methods[] = {
+ {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
+ {NULL}
+};
+
+ComplexExtendsException(PyExc_StandardError, EnvironmentError,
+ EnvironmentError, EnvironmentError_dealloc,
+ EnvironmentError_methods, EnvironmentError_members,
+ EnvironmentError_str,
+ "Base class for I/O related errors.");
+
+
+/*
+ * IOError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, IOError,
+ EnvironmentError, "I/O operation failed.");
+
+
+/*
+ * OSError extends EnvironmentError
+ */
+MiddlingExtendsException(PyExc_EnvironmentError, OSError,
+ EnvironmentError, "OS system call failed.");
+
+
+/*
+ * WindowsError extends OSError
+ */
+#ifdef MS_WINDOWS
+#include "errmap.h"
+
+static int
+WindowsError_clear(PyWindowsErrorObject *self)
+{
+ Py_CLEAR(self->myerrno);
+ Py_CLEAR(self->strerror);
+ Py_CLEAR(self->filename);
+ Py_CLEAR(self->winerror);
+ return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+WindowsError_dealloc(PyWindowsErrorObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ WindowsError_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->myerrno);
+ Py_VISIT(self->strerror);
+ Py_VISIT(self->filename);
+ Py_VISIT(self->winerror);
+ return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static int
+WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *o_errcode = NULL;
+ long errcode;
+ long posix_errno;
+
+ if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
+ == -1)
+ return -1;
+
+ if (self->myerrno == NULL)
+ return 0;
+
+ /* Set errno to the POSIX errno, and winerror to the Win32
+ error code. */
+ errcode = PyInt_AsLong(self->myerrno);
+ if (errcode == -1 && PyErr_Occurred())
+ return -1;
+ posix_errno = winerror_to_errno(errcode);
+
+ Py_CLEAR(self->winerror);
+ self->winerror = self->myerrno;
+
+ o_errcode = PyInt_FromLong(posix_errno);
+ if (!o_errcode)
+ return -1;
+
+ self->myerrno = o_errcode;
+
+ return 0;
+}
+
+
+static PyObject *
+WindowsError_str(PyWindowsErrorObject *self)
+{
+ PyObject *rtnval = NULL;
+
+ if (self->filename) {
+ PyObject *fmt;
+ PyObject *repr;
+ PyObject *tuple;
+
+ fmt = PyString_FromString("[Error %s] %s: %s");
+ if (!fmt)
+ return NULL;
+
+ repr = PyObject_Repr(self->filename);
+ if (!repr) {
+ Py_DECREF(fmt);
+ return NULL;
+ }
+ tuple = PyTuple_New(3);
+ if (!tuple) {
+ Py_DECREF(repr);
+ Py_DECREF(fmt);
+ return NULL;
+ }
+
+ if (self->winerror) {
+ Py_INCREF(self->winerror);
+ PyTuple_SET_ITEM(tuple, 0, self->winerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 0, Py_None);
+ }
+ if (self->strerror) {
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(tuple, 1, self->strerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 1, Py_None);
+ }
+
+ PyTuple_SET_ITEM(tuple, 2, repr);
+
+ rtnval = PyString_Format(fmt, tuple);
+
+ Py_DECREF(fmt);
+ Py_DECREF(tuple);
+ }
+ else if (self->winerror && self->strerror) {
+ PyObject *fmt;
+ PyObject *tuple;
+
+ fmt = PyString_FromString("[Error %s] %s");
+ if (!fmt)
+ return NULL;
+
+ tuple = PyTuple_New(2);
+ if (!tuple) {
+ Py_DECREF(fmt);
+ return NULL;
+ }
+
+ if (self->winerror) {
+ Py_INCREF(self->winerror);
+ PyTuple_SET_ITEM(tuple, 0, self->winerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 0, Py_None);
+ }
+ if (self->strerror) {
+ Py_INCREF(self->strerror);
+ PyTuple_SET_ITEM(tuple, 1, self->strerror);
+ }
+ else {
+ Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(tuple, 1, Py_None);
+ }
+
+ rtnval = PyString_Format(fmt, tuple);
+
+ Py_DECREF(fmt);
+ Py_DECREF(tuple);
+ }
+ else
+ rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
+
+ return rtnval;
+}
+
+static PyMemberDef WindowsError_members[] = {
+ {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
+ PyDoc_STR("POSIX exception code")},
+ {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
+ PyDoc_STR("exception strerror")},
+ {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
+ PyDoc_STR("exception filename")},
+ {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
+ PyDoc_STR("Win32 exception code")},
+ {NULL} /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
+ WindowsError_dealloc, 0, WindowsError_members,
+ WindowsError_str, "MS-Windows OS system call failed.");
+
+#endif /* MS_WINDOWS */
+
+
+/*
+ * VMSError extends OSError (I think)
+ */
+#ifdef __VMS
+MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
+ "OpenVMS OS system call failed.");
+#endif
+
+
+/*
+ * EOFError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, EOFError,
+ "Read beyond end of file.");
+
+
+/*
+ * RuntimeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, RuntimeError,
+ "Unspecified run-time error.");
+
+
+/*
+ * NotImplementedError extends RuntimeError
+ */
+SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
+ "Method or function hasn't been implemented yet.");
+
+/*
+ * NameError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, NameError,
+ "Name not found globally.");
+
+/*
+ * UnboundLocalError extends NameError
+ */
+SimpleExtendsException(PyExc_NameError, UnboundLocalError,
+ "Local name referenced but not bound to a value.");
+
+/*
+ * AttributeError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AttributeError,
+ "Attribute not found.");
+
+
+/*
+ * SyntaxError extends StandardError
+ */
+
+static int
+SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *info = NULL;
+ Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
+
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+
+ if (lenargs >= 1) {
+ Py_CLEAR(self->msg);
+ self->msg = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(self->msg);
+ }
+ if (lenargs == 2) {
+ info = PyTuple_GET_ITEM(args, 1);
+ info = PySequence_Tuple(info);
+ if (!info)
+ return -1;
+
+ if (PyTuple_GET_SIZE(info) != 4) {
+ /* not a very good error message, but it's what Python 2.4 gives */
+ PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+ Py_DECREF(info);
+ return -1;
+ }
+
+ Py_CLEAR(self->filename);
+ self->filename = PyTuple_GET_ITEM(info, 0);
+ Py_INCREF(self->filename);
+
+ Py_CLEAR(self->lineno);
+ self->lineno = PyTuple_GET_ITEM(info, 1);
+ Py_INCREF(self->lineno);
+
+ Py_CLEAR(self->offset);
+ self->offset = PyTuple_GET_ITEM(info, 2);
+ Py_INCREF(self->offset);
+
+ Py_CLEAR(self->text);
+ self->text = PyTuple_GET_ITEM(info, 3);
+ Py_INCREF(self->text);
+
+ Py_DECREF(info);
+ }
+ return 0;
+}
+
+static int
+SyntaxError_clear(PySyntaxErrorObject *self)
+{
+ Py_CLEAR(self->msg);
+ Py_CLEAR(self->filename);
+ Py_CLEAR(self->lineno);
+ Py_CLEAR(self->offset);
+ Py_CLEAR(self->text);
+ Py_CLEAR(self->print_file_and_line);
+ return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+SyntaxError_dealloc(PySyntaxErrorObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ SyntaxError_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->msg);
+ Py_VISIT(self->filename);
+ Py_VISIT(self->lineno);
+ Py_VISIT(self->offset);
+ Py_VISIT(self->text);
+ Py_VISIT(self->print_file_and_line);
+ return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+/* This is called "my_basename" instead of just "basename" to avoid name
+ conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
+ defined, and Python does define that. */
+static char *
+my_basename(char *name)
+{
+ char *cp = name;
+ char *result = name;
+
+ if (name == NULL)
+ return "???";
+ while (*cp != '\0') {
+ if (*cp == SEP)
+ result = cp + 1;
+ ++cp;
+ }
+ return result;
+}
+
+
+static PyObject *
+SyntaxError_str(PySyntaxErrorObject *self)
+{
+ PyObject *str;
+ PyObject *result;
+ int have_filename = 0;
+ int have_lineno = 0;
+ char *buffer = NULL;
+ Py_ssize_t bufsize;
+
+ if (self->msg)
+ str = PyObject_Str(self->msg);
+ else
+ str = PyObject_Str(Py_None);
+ if (!str)
+ return NULL;
+ /* Don't fiddle with non-string return (shouldn't happen anyway) */
+ if (!PyString_Check(str))
+ return str;
+
+ /* XXX -- do all the additional formatting with filename and
+ lineno here */
+
+ have_filename = (self->filename != NULL) &&
+ PyString_Check(self->filename);
+ have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
+
+ if (!have_filename && !have_lineno)
+ return str;
+
+ bufsize = PyString_GET_SIZE(str) + 64;
+ if (have_filename)
+ bufsize += PyString_GET_SIZE(self->filename);
+
+ buffer = PyMem_MALLOC(bufsize);
+ if (buffer == NULL)
+ return str;
+
+ if (have_filename && have_lineno)
+ PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
+ PyString_AS_STRING(str),
+ my_basename(PyString_AS_STRING(self->filename)),
+ PyInt_AsLong(self->lineno));
+ else if (have_filename)
+ PyOS_snprintf(buffer, bufsize, "%s (%s)",
+ PyString_AS_STRING(str),
+ my_basename(PyString_AS_STRING(self->filename)));
+ else /* only have_lineno */
+ PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
+ PyString_AS_STRING(str),
+ PyInt_AsLong(self->lineno));
+
+ result = PyString_FromString(buffer);
+ PyMem_FREE(buffer);
+
+ if (result == NULL)
+ result = str;
+ else
+ Py_DECREF(str);
+ return result;
+}
+
+static PyMemberDef SyntaxError_members[] = {
+ {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
+ PyDoc_STR("exception msg")},
+ {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
+ PyDoc_STR("exception filename")},
+ {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
+ PyDoc_STR("exception lineno")},
+ {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
+ PyDoc_STR("exception offset")},
+ {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
+ PyDoc_STR("exception text")},
+ {"print_file_and_line", T_OBJECT,
+ offsetof(PySyntaxErrorObject, print_file_and_line), 0,
+ PyDoc_STR("exception print_file_and_line")},
+ {NULL} /* Sentinel */
+};
+
+ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
+ SyntaxError_dealloc, 0, SyntaxError_members,
+ SyntaxError_str, "Invalid syntax.");
+
+
+/*
+ * IndentationError extends SyntaxError
+ */
+MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
+ "Improper indentation.");
+
+
+/*
+ * TabError extends IndentationError
+ */
+MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
+ "Improper mixture of spaces and tabs.");
+
+
+/*
+ * LookupError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, LookupError,
+ "Base class for lookup errors.");
+
+
+/*
+ * IndexError extends LookupError
+ */
+SimpleExtendsException(PyExc_LookupError, IndexError,
+ "Sequence index out of range.");
+
+
+/*
+ * KeyError extends LookupError
+ */
+static PyObject *
+KeyError_str(PyBaseExceptionObject *self)
+{
+ /* If args is a tuple of exactly one item, apply repr to args[0].
+ This is done so that e.g. the exception raised by {}[''] prints
+ KeyError: ''
+ rather than the confusing
+ KeyError
+ alone. The downside is that if KeyError is raised with an explanatory
+ string, that string will be displayed in quotes. Too bad.
+ If args is anything else, use the default BaseException__str__().
+ */
+ if (PyTuple_GET_SIZE(self->args) == 1) {
+ return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
+ }
+ return BaseException_str(self);
+}
+
+ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
+ 0, 0, 0, KeyError_str, "Mapping key not found.");
+
+
+/*
+ * ValueError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ValueError,
+ "Inappropriate argument value (of correct type).");
+
+/*
+ * UnicodeError extends ValueError
+ */
+
+SimpleExtendsException(PyExc_ValueError, UnicodeError,
+ "Unicode related error.");
+
+#ifdef Py_USING_UNICODE
+static PyObject *
+get_string(PyObject *attr, const char *name)
+{
+ if (!attr) {
+ PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+ return NULL;
+ }
+
+ if (!PyString_Check(attr)) {
+ PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
+ return NULL;
+ }
+ Py_INCREF(attr);
+ return attr;
+}
+
+
+static int
+set_string(PyObject **attr, const char *value)
+{
+ PyObject *obj = PyString_FromString(value);
+ if (!obj)
+ return -1;
+ Py_CLEAR(*attr);
+ *attr = obj;
+ return 0;
+}
+
+
+static PyObject *
+get_unicode(PyObject *attr, const char *name)
+{
+ if (!attr) {
+ PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
+ return NULL;
+ }
+
+ if (!PyUnicode_Check(attr)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s attribute must be unicode", name);
+ return NULL;
+ }
+ Py_INCREF(attr);
+ return attr;
+}
+
+PyObject *
+PyUnicodeEncodeError_GetEncoding(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetEncoding(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
+}
+
+PyObject *
+PyUnicodeEncodeError_GetObject(PyObject *exc)
+{
+ return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeDecodeError_GetObject(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+PyObject *
+PyUnicodeTranslateError_GetObject(PyObject *exc)
+{
+ return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
+}
+
+int
+PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+ Py_ssize_t size;
+ PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+ "object");
+ if (!obj)
+ return -1;
+ *start = ((PyUnicodeErrorObject *)exc)->start;
+ size = PyUnicode_GET_SIZE(obj);
+ if (*start<0)
+ *start = 0; /*XXX check for values <0*/
+ if (*start>=size)
+ *start = size-1;
+ Py_DECREF(obj);
+ return 0;
+}
+
+
+int
+PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+ Py_ssize_t size;
+ PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+ "object");
+ if (!obj)
+ return -1;
+ size = PyString_GET_SIZE(obj);
+ *start = ((PyUnicodeErrorObject *)exc)->start;
+ if (*start<0)
+ *start = 0;
+ if (*start>=size)
+ *start = size-1;
+ Py_DECREF(obj);
+ return 0;
+}
+
+
+int
+PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
+{
+ return PyUnicodeEncodeError_GetStart(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+ ((PyUnicodeErrorObject *)exc)->start = start;
+ return 0;
+}
+
+
+int
+PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+ ((PyUnicodeErrorObject *)exc)->start = start;
+ return 0;
+}
+
+
+int
+PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
+{
+ ((PyUnicodeErrorObject *)exc)->start = start;
+ return 0;
+}
+
+
+int
+PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+ Py_ssize_t size;
+ PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
+ "object");
+ if (!obj)
+ return -1;
+ *end = ((PyUnicodeErrorObject *)exc)->end;
+ size = PyUnicode_GET_SIZE(obj);
+ if (*end<1)
+ *end = 1;
+ if (*end>size)
+ *end = size;
+ Py_DECREF(obj);
+ return 0;
+}
+
+
+int
+PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
+{
+ Py_ssize_t size;
+ PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
+ "object");
+ if (!obj)
+ return -1;
+ *end = ((PyUnicodeErrorObject *)exc)->end;
+ size = PyString_GET_SIZE(obj);
+ if (*end<1)
+ *end = 1;
+ if (*end>size)
+ *end = size;
+ Py_DECREF(obj);
+ return 0;
+}
+
+
+int
+PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
+{
+ return PyUnicodeEncodeError_GetEnd(exc, start);
+}
+
+
+int
+PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+ ((PyUnicodeErrorObject *)exc)->end = end;
+ return 0;
+}
+
+
+int
+PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+ ((PyUnicodeErrorObject *)exc)->end = end;
+ return 0;
+}
+
+
+int
+PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
+{
+ ((PyUnicodeErrorObject *)exc)->end = end;
+ return 0;
+}
+
+PyObject *
+PyUnicodeEncodeError_GetReason(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeDecodeError_GetReason(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+PyObject *
+PyUnicodeTranslateError_GetReason(PyObject *exc)
+{
+ return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
+}
+
+
+int
+PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+int
+PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
+{
+ return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
+}
+
+
+static int
+UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
+ PyTypeObject *objecttype)
+{
+ Py_CLEAR(self->encoding);
+ Py_CLEAR(self->object);
+ Py_CLEAR(self->reason);
+
+ if (!PyArg_ParseTuple(args, "O!O!nnO!",
+ &PyString_Type, &self->encoding,
+ objecttype, &self->object,
+ &self->start,
+ &self->end,
+ &PyString_Type, &self->reason)) {
+ self->encoding = self->object = self->reason = NULL;
+ return -1;
+ }
+
+ Py_INCREF(self->encoding);
+ Py_INCREF(self->object);
+ Py_INCREF(self->reason);
+
+ return 0;
+}
+
+static int
+UnicodeError_clear(PyUnicodeErrorObject *self)
+{
+ Py_CLEAR(self->encoding);
+ Py_CLEAR(self->object);
+ Py_CLEAR(self->reason);
+ return BaseException_clear((PyBaseExceptionObject *)self);
+}
+
+static void
+UnicodeError_dealloc(PyUnicodeErrorObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ UnicodeError_clear(self);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->encoding);
+ Py_VISIT(self->object);
+ Py_VISIT(self->reason);
+ return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
+}
+
+static PyMemberDef UnicodeError_members[] = {
+ {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
+ PyDoc_STR("exception encoding")},
+ {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
+ PyDoc_STR("exception object")},
+ {"start", T_PYSSIZET, offsetof(PyUnicodeErrorObject, start), 0,
+ PyDoc_STR("exception start")},
+ {"end", T_PYSSIZET, offsetof(PyUnicodeErrorObject, end), 0,
+ PyDoc_STR("exception end")},
+ {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
+ PyDoc_STR("exception reason")},
+ {NULL} /* Sentinel */
+};
+
+
+/*
+ * UnicodeEncodeError extends UnicodeError
+ */
+
+static int
+UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+ return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+ kwds, &PyUnicode_Type);
+}
+
+static PyObject *
+UnicodeEncodeError_str(PyObject *self)
+{
+ PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+ PyObject *result = NULL;
+ PyObject *reason_str = NULL;
+ PyObject *encoding_str = NULL;
+
+ if (!uself->object)
+ /* Not properly initialized. */
+ return PyUnicode_FromString("");
+
+ /* Get reason and encoding as strings, which they might not be if
+ they've been modified after we were contructed. */
+ reason_str = PyObject_Str(uself->reason);
+ if (reason_str == NULL)
+ goto done;
+ encoding_str = PyObject_Str(uself->encoding);
+ if (encoding_str == NULL)
+ goto done;
+
+ if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+ int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
+ char badchar_str[20];
+ if (badchar <= 0xff)
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+ else if (badchar <= 0xffff)
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+ else
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+ result = PyString_FromFormat(
+ "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
+ PyString_AS_STRING(encoding_str),
+ badchar_str,
+ uself->start,
+ PyString_AS_STRING(reason_str));
+ }
+ else {
+ result = PyString_FromFormat(
+ "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
+ PyString_AS_STRING(encoding_str),
+ uself->start,
+ uself->end-1,
+ PyString_AS_STRING(reason_str));
+ }
+done:
+ Py_XDECREF(reason_str);
+ Py_XDECREF(encoding_str);
+ return result;
+}
+
+static PyTypeObject _PyExc_UnicodeEncodeError = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ EXC_MODULE_NAME "UnicodeEncodeError",
+ sizeof(PyUnicodeErrorObject), 0,
+ (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
+ (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+ 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+ (initproc)UnicodeEncodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
+
+PyObject *
+PyUnicodeEncodeError_Create(
+ const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
+ Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
+ encoding, object, length, start, end, reason);
+}
+
+
+/*
+ * UnicodeDecodeError extends UnicodeError
+ */
+
+static int
+UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+ return UnicodeError_init((PyUnicodeErrorObject *)self, args,
+ kwds, &PyString_Type);
+}
+
+static PyObject *
+UnicodeDecodeError_str(PyObject *self)
+{
+ PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+ PyObject *result = NULL;
+ PyObject *reason_str = NULL;
+ PyObject *encoding_str = NULL;
+
+ if (!uself->object)
+ /* Not properly initialized. */
+ return PyUnicode_FromString("");
+
+ /* Get reason and encoding as strings, which they might not be if
+ they've been modified after we were contructed. */
+ reason_str = PyObject_Str(uself->reason);
+ if (reason_str == NULL)
+ goto done;
+ encoding_str = PyObject_Str(uself->encoding);
+ if (encoding_str == NULL)
+ goto done;
+
+ if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+ /* FromFormat does not support %02x, so format that separately */
+ char byte[4];
+ PyOS_snprintf(byte, sizeof(byte), "%02x",
+ ((int)PyString_AS_STRING(uself->object)[uself->start])&0xff);
+ result = PyString_FromFormat(
+ "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
+ PyString_AS_STRING(encoding_str),
+ byte,
+ uself->start,
+ PyString_AS_STRING(reason_str));
+ }
+ else {
+ result = PyString_FromFormat(
+ "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
+ PyString_AS_STRING(encoding_str),
+ uself->start,
+ uself->end-1,
+ PyString_AS_STRING(reason_str));
+ }
+done:
+ Py_XDECREF(reason_str);
+ Py_XDECREF(encoding_str);
+ return result;
+}
+
+static PyTypeObject _PyExc_UnicodeDecodeError = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ EXC_MODULE_NAME "UnicodeDecodeError",
+ sizeof(PyUnicodeErrorObject), 0,
+ (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
+ (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+ 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+ (initproc)UnicodeDecodeError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
+
+PyObject *
+PyUnicodeDecodeError_Create(
+ const char *encoding, const char *object, Py_ssize_t length,
+ Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
+ encoding, object, length, start, end, reason);
+}
+
+
+/*
+ * UnicodeTranslateError extends UnicodeError
+ */
+
+static int
+UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
+ PyObject *kwds)
+{
+ if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
+ return -1;
+
+ Py_CLEAR(self->object);
+ Py_CLEAR(self->reason);
+
+ if (!PyArg_ParseTuple(args, "O!nnO!",
+ &PyUnicode_Type, &self->object,
+ &self->start,
+ &self->end,
+ &PyString_Type, &self->reason)) {
+ self->object = self->reason = NULL;
+ return -1;
+ }
+
+ Py_INCREF(self->object);
+ Py_INCREF(self->reason);
+
+ return 0;
+}
+
+
+static PyObject *
+UnicodeTranslateError_str(PyObject *self)
+{
+ PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self;
+ PyObject *result = NULL;
+ PyObject *reason_str = NULL;
+
+ if (!uself->object)
+ /* Not properly initialized. */
+ return PyUnicode_FromString("");
+
+ /* Get reason as a string, which it might not be if it's been
+ modified after we were contructed. */
+ reason_str = PyObject_Str(uself->reason);
+ if (reason_str == NULL)
+ goto done;
+
+ if (uself->start < PyUnicode_GET_SIZE(uself->object) && uself->end == uself->start+1) {
+ int badchar = (int)PyUnicode_AS_UNICODE(uself->object)[uself->start];
+ char badchar_str[20];
+ if (badchar <= 0xff)
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
+ else if (badchar <= 0xffff)
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
+ else
+ PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
+ result = PyString_FromFormat(
+ "can't translate character u'\\%s' in position %zd: %.400s",
+ badchar_str,
+ uself->start,
+ PyString_AS_STRING(reason_str));
+ } else {
+ result = PyString_FromFormat(
+ "can't translate characters in position %zd-%zd: %.400s",
+ uself->start,
+ uself->end-1,
+ PyString_AS_STRING(reason_str));
+ }
+done:
+ Py_XDECREF(reason_str);
+ return result;
+}
+
+static PyTypeObject _PyExc_UnicodeTranslateError = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ EXC_MODULE_NAME "UnicodeTranslateError",
+ sizeof(PyUnicodeErrorObject), 0,
+ (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ PyDoc_STR("Unicode translation error."), (traverseproc)UnicodeError_traverse,
+ (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
+ 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
+ (initproc)UnicodeTranslateError_init, 0, BaseException_new,
+};
+PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
+
+PyObject *
+PyUnicodeTranslateError_Create(
+ const Py_UNICODE *object, Py_ssize_t length,
+ Py_ssize_t start, Py_ssize_t end, const char *reason)
+{
+ return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
+ object, length, start, end, reason);
+}
+#endif
+
+
+/*
+ * AssertionError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, AssertionError,
+ "Assertion failed.");
+
+
+/*
+ * ArithmeticError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ArithmeticError,
+ "Base class for arithmetic errors.");
+
+
+/*
+ * FloatingPointError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
+ "Floating point operation failed.");
+
+
+/*
+ * OverflowError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
+ "Result too large to be represented.");
+
+
+/*
+ * ZeroDivisionError extends ArithmeticError
+ */
+SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
+ "Second argument to a division or modulo operation was zero.");
+
+
+/*
+ * SystemError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, SystemError,
+ "Internal error in the Python interpreter.\n"
+ "\n"
+ "Please report this to the Python maintainer, along with the traceback,\n"
+ "the Python version, and the hardware/OS platform and version.");
+
+
+/*
+ * ReferenceError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, ReferenceError,
+ "Weak ref proxy used after referent went away.");
+
+
+/*
+ * MemoryError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
+
+/*
+ * BufferError extends StandardError
+ */
+SimpleExtendsException(PyExc_StandardError, BufferError, "Buffer error.");
+
+
+/* Warning category docstrings */
+
+/*
+ * Warning extends Exception
+ */
+SimpleExtendsException(PyExc_Exception, Warning,
+ "Base class for warning categories.");
+
+
+/*
+ * UserWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UserWarning,
+ "Base class for warnings generated by user code.");
+
+
+/*
+ * DeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, DeprecationWarning,
+ "Base class for warnings about deprecated features.");
+
+
+/*
+ * PendingDeprecationWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
+ "Base class for warnings about features which will be deprecated\n"
+ "in the future.");
+
+
+/*
+ * SyntaxWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, SyntaxWarning,
+ "Base class for warnings about dubious syntax.");
+
+
+/*
+ * RuntimeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, RuntimeWarning,
+ "Base class for warnings about dubious runtime behavior.");
+
+
+/*
+ * FutureWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, FutureWarning,
+ "Base class for warnings about constructs that will change semantically\n"
+ "in the future.");
+
+
+/*
+ * ImportWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, ImportWarning,
+ "Base class for warnings about probable mistakes in module imports");
+
+
+/*
+ * UnicodeWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, UnicodeWarning,
+ "Base class for warnings about Unicode related problems, mostly\n"
+ "related to conversion problems.");
+
+/*
+ * BytesWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, BytesWarning,
+ "Base class for warnings about bytes and buffer related problems, mostly\n"
+ "related to conversion from str or comparing to str.");
+
+/* Pre-computed MemoryError instance. Best to create this as early as
+ * possible and not wait until a MemoryError is actually raised!
+ */
+PyObject *PyExc_MemoryErrorInst=NULL;
+
+/* Pre-computed RuntimeError instance for when recursion depth is reached.
+ Meant to be used when normalizing the exception for exceeding the recursion
+ depth will cause its own infinite recursion.
+*/
+PyObject *PyExc_RecursionErrorInst = NULL;
+
+/* module global functions */
+static PyMethodDef functions[] = {
+ /* Sentinel */
+ {NULL, NULL}
+};
+
+#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
+ Py_FatalError("exceptions bootstrapping error.");
+
+#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
+ PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
+ if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
+ Py_FatalError("Module dictionary insertion problem.");
+
+
+PyMODINIT_FUNC
+_PyExc_Init(void)
+{
+ PyObject *m, *bltinmod, *bdict;
+
+ PRE_INIT(BaseException)
+ PRE_INIT(Exception)
+ PRE_INIT(StandardError)
+ PRE_INIT(TypeError)
+ PRE_INIT(StopIteration)
+ PRE_INIT(GeneratorExit)
+ PRE_INIT(SystemExit)
+ PRE_INIT(KeyboardInterrupt)
+ PRE_INIT(ImportError)
+ PRE_INIT(EnvironmentError)
+ PRE_INIT(IOError)
+ PRE_INIT(OSError)
+#ifdef MS_WINDOWS
+ PRE_INIT(WindowsError)
+#endif
+#ifdef __VMS
+ PRE_INIT(VMSError)
+#endif
+ PRE_INIT(EOFError)
+ PRE_INIT(RuntimeError)
+ PRE_INIT(NotImplementedError)
+ PRE_INIT(NameError)
+ PRE_INIT(UnboundLocalError)
+ PRE_INIT(AttributeError)
+ PRE_INIT(SyntaxError)
+ PRE_INIT(IndentationError)
+ PRE_INIT(TabError)
+ PRE_INIT(LookupError)
+ PRE_INIT(IndexError)
+ PRE_INIT(KeyError)
+ PRE_INIT(ValueError)
+ PRE_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+ PRE_INIT(UnicodeEncodeError)
+ PRE_INIT(UnicodeDecodeError)
+ PRE_INIT(UnicodeTranslateError)
+#endif
+ PRE_INIT(AssertionError)
+ PRE_INIT(ArithmeticError)
+ PRE_INIT(FloatingPointError)
+ PRE_INIT(OverflowError)
+ PRE_INIT(ZeroDivisionError)
+ PRE_INIT(SystemError)
+ PRE_INIT(ReferenceError)
+ PRE_INIT(MemoryError)
+ PRE_INIT(BufferError)
+ PRE_INIT(Warning)
+ PRE_INIT(UserWarning)
+ PRE_INIT(DeprecationWarning)
+ PRE_INIT(PendingDeprecationWarning)
+ PRE_INIT(SyntaxWarning)
+ PRE_INIT(RuntimeWarning)
+ PRE_INIT(FutureWarning)
+ PRE_INIT(ImportWarning)
+ PRE_INIT(UnicodeWarning)
+ PRE_INIT(BytesWarning)
+
+ m = Py_InitModule4("exceptions", functions, exceptions_doc,
+ (PyObject *)NULL, PYTHON_API_VERSION);
+ if (m == NULL)
+ return;
+
+ bltinmod = PyImport_ImportModule("__builtin__");
+ if (bltinmod == NULL)
+ Py_FatalError("exceptions bootstrapping error.");
+ bdict = PyModule_GetDict(bltinmod);
+ if (bdict == NULL)
+ Py_FatalError("exceptions bootstrapping error.");
+
+ POST_INIT(BaseException)
+ POST_INIT(Exception)
+ POST_INIT(StandardError)
+ POST_INIT(TypeError)
+ POST_INIT(StopIteration)
+ POST_INIT(GeneratorExit)
+ POST_INIT(SystemExit)
+ POST_INIT(KeyboardInterrupt)
+ POST_INIT(ImportError)
+ POST_INIT(EnvironmentError)
+ POST_INIT(IOError)
+ POST_INIT(OSError)
+#ifdef MS_WINDOWS
+ POST_INIT(WindowsError)
+#endif
+#ifdef __VMS
+ POST_INIT(VMSError)
+#endif
+ POST_INIT(EOFError)
+ POST_INIT(RuntimeError)
+ POST_INIT(NotImplementedError)
+ POST_INIT(NameError)
+ POST_INIT(UnboundLocalError)
+ POST_INIT(AttributeError)
+ POST_INIT(SyntaxError)
+ POST_INIT(IndentationError)
+ POST_INIT(TabError)
+ POST_INIT(LookupError)
+ POST_INIT(IndexError)
+ POST_INIT(KeyError)
+ POST_INIT(ValueError)
+ POST_INIT(UnicodeError)
+#ifdef Py_USING_UNICODE
+ POST_INIT(UnicodeEncodeError)
+ POST_INIT(UnicodeDecodeError)
+ POST_INIT(UnicodeTranslateError)
+#endif
+ POST_INIT(AssertionError)
+ POST_INIT(ArithmeticError)
+ POST_INIT(FloatingPointError)
+ POST_INIT(OverflowError)
+ POST_INIT(ZeroDivisionError)
+ POST_INIT(SystemError)
+ POST_INIT(ReferenceError)
+ POST_INIT(MemoryError)
+ POST_INIT(BufferError)
+ POST_INIT(Warning)
+ POST_INIT(UserWarning)
+ POST_INIT(DeprecationWarning)
+ POST_INIT(PendingDeprecationWarning)
+ POST_INIT(SyntaxWarning)
+ POST_INIT(RuntimeWarning)
+ POST_INIT(FutureWarning)
+ POST_INIT(ImportWarning)
+ POST_INIT(UnicodeWarning)
+ POST_INIT(BytesWarning)
+
+ PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
+ if (!PyExc_MemoryErrorInst)
+ Py_FatalError("Cannot pre-allocate MemoryError instance");
+
+ PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
+ if (!PyExc_RecursionErrorInst)
+ Py_FatalError("Cannot pre-allocate RuntimeError instance for "
+ "recursion errors");
+ else {
+ PyBaseExceptionObject *err_inst =
+ (PyBaseExceptionObject *)PyExc_RecursionErrorInst;
+ PyObject *args_tuple;
+ PyObject *exc_message;
+ exc_message = PyString_FromString("maximum recursion depth exceeded");
+ if (!exc_message)
+ Py_FatalError("cannot allocate argument for RuntimeError "
+ "pre-allocation");
+ args_tuple = PyTuple_Pack(1, exc_message);
+ if (!args_tuple)
+ Py_FatalError("cannot allocate tuple for RuntimeError "
+ "pre-allocation");
+ Py_DECREF(exc_message);
+ if (BaseException_init(err_inst, args_tuple, NULL))
+ Py_FatalError("init of pre-allocated RuntimeError failed");
+ Py_DECREF(args_tuple);
+ }
+ Py_DECREF(bltinmod);
+}
+
+void
+_PyExc_Fini(void)
+{
+ Py_CLEAR(PyExc_MemoryErrorInst);
+ Py_CLEAR(PyExc_RecursionErrorInst);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/fileobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/fileobject.c
new file mode 100644
index 0000000000..a26e03e810
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/fileobject.c
@@ -0,0 +1,2889 @@
+/* File object implementation */
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef MS_WINDOWS
+#define fileno _fileno
+/* can simulate truncate with Win32 API functions; see file_truncate */
+#define HAVE_FTRUNCATE
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include <io.h>
+#endif
+
+#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_GETC_UNLOCKED
+#define GETC(f) getc_unlocked(f)
+#define FLOCKFILE(f) flockfile(f)
+#define FUNLOCKFILE(f) funlockfile(f)
+#else
+#define GETC(f) getc(f)
+#define FLOCKFILE(f)
+#define FUNLOCKFILE(f)
+#endif
+
+/* Bits in f_newlinetypes */
+#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
+#define NEWLINE_CR 1 /* \r newline seen */
+#define NEWLINE_LF 2 /* \n newline seen */
+#define NEWLINE_CRLF 4 /* \r\n newline seen */
+
+/*
+ * These macros release the GIL while preventing the f_close() function being
+ * called in the interval between them. For that purpose, a running total of
+ * the number of currently running unlocked code sections is kept in
+ * the unlocked_count field of the PyFileObject. The close() method raises
+ * an IOError if that field is non-zero. See issue #815646, #595601.
+ */
+
+#define FILE_BEGIN_ALLOW_THREADS(fobj) \
+{ \
+ fobj->unlocked_count++; \
+ Py_BEGIN_ALLOW_THREADS
+
+#define FILE_END_ALLOW_THREADS(fobj) \
+ Py_END_ALLOW_THREADS \
+ fobj->unlocked_count--; \
+ assert(fobj->unlocked_count >= 0); \
+}
+
+#define FILE_ABORT_ALLOW_THREADS(fobj) \
+ Py_BLOCK_THREADS \
+ fobj->unlocked_count--; \
+ assert(fobj->unlocked_count >= 0);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FILE *
+PyFile_AsFile(PyObject *f)
+{
+ if (f == NULL || !PyFile_Check(f))
+ return NULL;
+ else
+ return ((PyFileObject *)f)->f_fp;
+}
+
+void PyFile_IncUseCount(PyFileObject *fobj)
+{
+ fobj->unlocked_count++;
+}
+
+void PyFile_DecUseCount(PyFileObject *fobj)
+{
+ fobj->unlocked_count--;
+ assert(fobj->unlocked_count >= 0);
+}
+
+PyObject *
+PyFile_Name(PyObject *f)
+{
+ if (f == NULL || !PyFile_Check(f))
+ return NULL;
+ else
+ return ((PyFileObject *)f)->f_name;
+}
+
+/* This is a safe wrapper around PyObject_Print to print to the FILE
+ of a PyFileObject. PyObject_Print releases the GIL but knows nothing
+ about PyFileObject. */
+static int
+file_PyObject_Print(PyObject *op, PyFileObject *f, int flags)
+{
+ int result;
+ PyFile_IncUseCount(f);
+ result = PyObject_Print(op, f->f_fp, flags);
+ PyFile_DecUseCount(f);
+ return result;
+}
+
+/* On Unix, fopen will succeed for directories.
+ In Python, there should be no file objects referring to
+ directories, so we need a check. */
+
+static PyFileObject*
+dircheck(PyFileObject* f)
+{
+#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
+ struct stat buf;
+ if (f->f_fp == NULL)
+ return f;
+ if (fstat(fileno(f->f_fp), &buf) == 0 &&
+ S_ISDIR(buf.st_mode)) {
+ char *msg = strerror(EISDIR);
+ PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)",
+ EISDIR, msg, f->f_name);
+ PyErr_SetObject(PyExc_IOError, exc);
+ Py_XDECREF(exc);
+ return NULL;
+ }
+#endif
+ return f;
+}
+
+
+static PyObject *
+fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
+ int (*close)(FILE *))
+{
+ assert(name != NULL);
+ assert(f != NULL);
+ assert(PyFile_Check(f));
+ assert(f->f_fp == NULL);
+
+ Py_DECREF(f->f_name);
+ Py_DECREF(f->f_mode);
+ Py_DECREF(f->f_encoding);
+ Py_DECREF(f->f_errors);
+
+ Py_INCREF(name);
+ f->f_name = name;
+
+ f->f_mode = PyString_FromString(mode);
+
+ f->f_close = close;
+ f->f_softspace = 0;
+ f->f_binary = strchr(mode,'b') != NULL;
+ f->f_buf = NULL;
+ f->f_univ_newline = (strchr(mode, 'U') != NULL);
+ f->f_newlinetypes = NEWLINE_UNKNOWN;
+ f->f_skipnextlf = 0;
+ Py_INCREF(Py_None);
+ f->f_encoding = Py_None;
+ Py_INCREF(Py_None);
+ f->f_errors = Py_None;
+ f->readable = f->writable = 0;
+ if (strchr(mode, 'r') != NULL || f->f_univ_newline)
+ f->readable = 1;
+ if (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL)
+ f->writable = 1;
+ if (strchr(mode, '+') != NULL)
+ f->readable = f->writable = 1;
+
+ if (f->f_mode == NULL)
+ return NULL;
+ f->f_fp = fp;
+ f = dircheck(f);
+ return (PyObject *) f;
+}
+
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+#define Py_VERIFY_WINNT
+/* The CRT on windows compiled with Visual Studio 2005 and higher may
+ * assert if given invalid mode strings. This is all fine and well
+ * in static languages like C where the mode string is typcially hard
+ * coded. But in Python, were we pass in the mode string from the user,
+ * we need to verify it first manually
+ */
+static int _PyVerify_Mode_WINNT(const char *mode)
+{
+ /* See if mode string is valid on Windows to avoid hard assertions */
+ /* remove leading spacese */
+ int singles = 0;
+ int pairs = 0;
+ int encoding = 0;
+ const char *s, *c;
+
+ while(*mode == ' ') /* strip initial spaces */
+ ++mode;
+ if (!strchr("rwa", *mode)) /* must start with one of these */
+ return 0;
+ while (*++mode) {
+ if (*mode == ' ' || *mode == 'N') /* ignore spaces and N */
+ continue;
+ s = "+TD"; /* each of this can appear only once */
+ c = strchr(s, *mode);
+ if (c) {
+ ptrdiff_t idx = s-c;
+ if (singles & (1<<idx))
+ return 0;
+ singles |= (1<<idx);
+ continue;
+ }
+ s = "btcnSR"; /* only one of each letter in the pairs allowed */
+ c = strchr(s, *mode);
+ if (c) {
+ ptrdiff_t idx = (s-c)/2;
+ if (pairs & (1<<idx))
+ return 0;
+ pairs |= (1<<idx);
+ continue;
+ }
+ if (*mode == ',') {
+ encoding = 1;
+ break;
+ }
+ return 0; /* found an invalid char */
+ }
+
+ if (encoding) {
+ char *e[] = {"UTF-8", "UTF-16LE", "UNICODE"};
+ while (*mode == ' ')
+ ++mode;
+ /* find 'ccs =' */
+ if (strncmp(mode, "ccs", 3))
+ return 0;
+ mode += 3;
+ while (*mode == ' ')
+ ++mode;
+ if (*mode != '=')
+ return 0;
+ while (*mode == ' ')
+ ++mode;
+ for(encoding = 0; encoding<_countof(e); ++encoding) {
+ size_t l = strlen(e[encoding]);
+ if (!strncmp(mode, e[encoding], l)) {
+ mode += l; /* found a valid encoding */
+ break;
+ }
+ }
+ if (encoding == _countof(e))
+ return 0;
+ }
+ /* skip trailing spaces */
+ while (*mode == ' ')
+ ++mode;
+
+ return *mode == '\0'; /* must be at the end of the string */
+}
+#endif
+
+/* check for known incorrect mode strings - problem is, platforms are
+ free to accept any mode characters they like and are supposed to
+ ignore stuff they don't understand... write or append mode with
+ universal newline support is expressly forbidden by PEP 278.
+ Additionally, remove the 'U' from the mode string as platforms
+ won't know what it is. Non-zero return signals an exception */
+int
+_PyFile_SanitizeMode(char *mode)
+{
+ char *upos;
+ size_t len = strlen(mode);
+
+ if (!len) {
+ PyErr_SetString(PyExc_ValueError, "empty mode string");
+ return -1;
+ }
+
+ upos = strchr(mode, 'U');
+ if (upos) {
+ memmove(upos, upos+1, len-(upos-mode)); /* incl null char */
+
+ if (mode[0] == 'w' || mode[0] == 'a') {
+ PyErr_Format(PyExc_ValueError, "universal newline "
+ "mode can only be used with modes "
+ "starting with 'r'");
+ return -1;
+ }
+
+ if (mode[0] != 'r') {
+ memmove(mode+1, mode, strlen(mode)+1);
+ mode[0] = 'r';
+ }
+
+ if (!strchr(mode, 'b')) {
+ memmove(mode+2, mode+1, strlen(mode));
+ mode[1] = 'b';
+ }
+ } else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
+ PyErr_Format(PyExc_ValueError, "mode string must begin with "
+ "one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
+ return -1;
+ }
+#ifdef Py_VERIFY_WINNT
+ /* additional checks on NT with visual studio 2005 and higher */
+ if (!_PyVerify_Mode_WINNT(mode)) {
+ PyErr_Format(PyExc_ValueError, "Invalid mode ('%.50s')", mode);
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+static PyObject *
+open_the_file(PyFileObject *f, char *name, char *mode)
+{
+ char *newmode;
+ assert(f != NULL);
+ assert(PyFile_Check(f));
+#ifdef MS_WINDOWS
+ /* windows ignores the passed name in order to support Unicode */
+ assert(f->f_name != NULL);
+#else
+ assert(name != NULL);
+#endif
+ assert(mode != NULL);
+ assert(f->f_fp == NULL);
+
+ /* probably need to replace 'U' by 'rb' */
+ newmode = PyMem_MALLOC(strlen(mode) + 3);
+ if (!newmode) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ strcpy(newmode, mode);
+
+ if (_PyFile_SanitizeMode(newmode)) {
+ f = NULL;
+ goto cleanup;
+ }
+
+ /* rexec.py can't stop a user from getting the file() constructor --
+ all they have to do is get *any* file object f, and then do
+ type(f). Here we prevent them from doing damage with it. */
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_IOError,
+ "file() constructor not accessible in restricted mode");
+ f = NULL;
+ goto cleanup;
+ }
+ errno = 0;
+
+#ifdef MS_WINDOWS
+ if (PyUnicode_Check(f->f_name)) {
+ PyObject *wmode;
+ wmode = PyUnicode_DecodeASCII(newmode, strlen(newmode), NULL);
+ if (f->f_name && wmode) {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ /* PyUnicode_AS_UNICODE OK without thread
+ lock as it is a simple dereference. */
+ f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name),
+ PyUnicode_AS_UNICODE(wmode));
+ FILE_END_ALLOW_THREADS(f)
+ }
+ Py_XDECREF(wmode);
+ }
+#endif
+ if (NULL == f->f_fp && NULL != name) {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ f->f_fp = fopen(name, newmode);
+ FILE_END_ALLOW_THREADS(f)
+ }
+
+ if (f->f_fp == NULL) {
+#if defined _MSC_VER && (_MSC_VER < 1400 || !defined(__STDC_SECURE_LIB__))
+ /* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings,
+ * across all Windows flavors. When it sets EINVAL varies
+ * across Windows flavors, the exact conditions aren't
+ * documented, and the answer lies in the OS's implementation
+ * of Win32's CreateFile function (whose source is secret).
+ * Seems the best we can do is map EINVAL to ENOENT.
+ * Starting with Visual Studio .NET 2005, EINVAL is correctly
+ * set by our CRT error handler (set in exceptions.c.)
+ */
+ if (errno == 0) /* bad mode string */
+ errno = EINVAL;
+ else if (errno == EINVAL) /* unknown, but not a mode string */
+ errno = ENOENT;
+#endif
+ /* EINVAL is returned when an invalid filename or
+ * an invalid mode is supplied. */
+ if (errno == EINVAL) {
+ PyObject *v;
+ char message[100];
+ PyOS_snprintf(message, 100,
+ "invalid mode ('%.50s') or filename", mode);
+ v = Py_BuildValue("(isO)", errno, message, f->f_name);
+ if (v != NULL) {
+ PyErr_SetObject(PyExc_IOError, v);
+ Py_DECREF(v);
+ }
+ }
+ else
+ PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
+ f = NULL;
+ }
+ if (f != NULL)
+ f = dircheck(f);
+
+cleanup:
+ PyMem_FREE(newmode);
+
+ return (PyObject *)f;
+}
+
+static PyObject *
+close_the_file(PyFileObject *f)
+{
+ int sts = 0;
+ int (*local_close)(FILE *);
+ FILE *local_fp = f->f_fp;
+ char *local_setbuf = f->f_setbuf;
+ if (local_fp != NULL) {
+ local_close = f->f_close;
+ if (local_close != NULL && f->unlocked_count > 0) {
+ if (f->ob_refcnt > 0) {
+ PyErr_SetString(PyExc_IOError,
+ "close() called during concurrent "
+ "operation on the same file object.");
+ } else {
+ /* This should not happen unless someone is
+ * carelessly playing with the PyFileObject
+ * struct fields and/or its associated FILE
+ * pointer. */
+ PyErr_SetString(PyExc_SystemError,
+ "PyFileObject locking error in "
+ "destructor (refcnt <= 0 at close).");
+ }
+ return NULL;
+ }
+ /* NULL out the FILE pointer before releasing the GIL, because
+ * it will not be valid anymore after the close() function is
+ * called. */
+ f->f_fp = NULL;
+ if (local_close != NULL) {
+ /* Issue #9295: must temporarily reset f_setbuf so that another
+ thread doesn't free it when running file_close() concurrently.
+ Otherwise this close() will crash when flushing the buffer. */
+ f->f_setbuf = NULL;
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+ sts = (*local_close)(local_fp);
+ Py_END_ALLOW_THREADS
+ f->f_setbuf = local_setbuf;
+ if (sts == EOF)
+ return PyErr_SetFromErrno(PyExc_IOError);
+ if (sts != 0)
+ return PyInt_FromLong((long)sts);
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+PyObject *
+PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
+{
+ PyFileObject *f;
+ PyObject *o_name;
+
+ f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, NULL, NULL);
+ if (f == NULL)
+ return NULL;
+ o_name = PyString_FromString(name);
+ if (o_name == NULL) {
+ if (close != NULL && fp != NULL)
+ close(fp);
+ Py_DECREF(f);
+ return NULL;
+ }
+ if (fill_file_fields(f, fp, o_name, mode, close) == NULL) {
+ Py_DECREF(f);
+ Py_DECREF(o_name);
+ return NULL;
+ }
+ Py_DECREF(o_name);
+ return (PyObject *)f;
+}
+
+PyObject *
+PyFile_FromString(char *name, char *mode)
+{
+ extern int fclose(FILE *);
+ PyFileObject *f;
+
+ f = (PyFileObject *)PyFile_FromFile((FILE *)NULL, name, mode, fclose);
+ if (f != NULL) {
+ if (open_the_file(f, name, mode) == NULL) {
+ Py_DECREF(f);
+ f = NULL;
+ }
+ }
+ return (PyObject *)f;
+}
+
+void
+PyFile_SetBufSize(PyObject *f, int bufsize)
+{
+ PyFileObject *file = (PyFileObject *)f;
+ if (bufsize >= 0) {
+ int type;
+ switch (bufsize) {
+ case 0:
+ type = _IONBF;
+ break;
+#ifdef HAVE_SETVBUF
+ case 1:
+ type = _IOLBF;
+ bufsize = BUFSIZ;
+ break;
+#endif
+ default:
+ type = _IOFBF;
+#ifndef HAVE_SETVBUF
+ bufsize = BUFSIZ;
+#endif
+ break;
+ }
+ fflush(file->f_fp);
+ if (type == _IONBF) {
+ PyMem_Free(file->f_setbuf);
+ file->f_setbuf = NULL;
+ } else {
+ file->f_setbuf = (char *)PyMem_Realloc(file->f_setbuf,
+ bufsize);
+ }
+#ifdef HAVE_SETVBUF
+ setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
+#else /* !HAVE_SETVBUF */
+ setbuf(file->f_fp, file->f_setbuf);
+#endif /* !HAVE_SETVBUF */
+ }
+}
+
+/* Set the encoding used to output Unicode strings.
+ Return 1 on success, 0 on failure. */
+
+int
+PyFile_SetEncoding(PyObject *f, const char *enc)
+{
+ return PyFile_SetEncodingAndErrors(f, enc, NULL);
+}
+
+int
+PyFile_SetEncodingAndErrors(PyObject *f, const char *enc, char* errors)
+{
+ PyFileObject *file = (PyFileObject*)f;
+ PyObject *str, *oerrors;
+
+ assert(PyFile_Check(f));
+ str = PyString_FromString(enc);
+ if (!str)
+ return 0;
+ if (errors) {
+ oerrors = PyString_FromString(errors);
+ if (!oerrors) {
+ Py_DECREF(str);
+ return 0;
+ }
+ } else {
+ oerrors = Py_None;
+ Py_INCREF(Py_None);
+ }
+ Py_DECREF(file->f_encoding);
+ file->f_encoding = str;
+ Py_DECREF(file->f_errors);
+ file->f_errors = oerrors;
+ return 1;
+}
+
+static PyObject *
+err_closed(void)
+{
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
+ return NULL;
+}
+
+static PyObject *
+err_mode(char *action)
+{
+ PyErr_Format(PyExc_IOError, "File not open for %s", action);
+ return NULL;
+}
+
+/* Refuse regular file I/O if there's data in the iteration-buffer.
+ * Mixing them would cause data to arrive out of order, as the read*
+ * methods don't use the iteration buffer. */
+static PyObject *
+err_iterbuffered(void)
+{
+ PyErr_SetString(PyExc_ValueError,
+ "Mixing iteration and read methods would lose data");
+ return NULL;
+}
+
+static void drop_readahead(PyFileObject *);
+
+/* Methods */
+
+static void
+file_dealloc(PyFileObject *f)
+{
+ PyObject *ret;
+ if (f->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) f);
+ ret = close_the_file(f);
+ if (!ret) {
+ PySys_WriteStderr("close failed in file object destructor:\n");
+ PyErr_Print();
+ }
+ else {
+ Py_DECREF(ret);
+ }
+ PyMem_Free(f->f_setbuf);
+ Py_XDECREF(f->f_name);
+ Py_XDECREF(f->f_mode);
+ Py_XDECREF(f->f_encoding);
+ Py_XDECREF(f->f_errors);
+ drop_readahead(f);
+ Py_TYPE(f)->tp_free((PyObject *)f);
+}
+
+static PyObject *
+file_repr(PyFileObject *f)
+{
+ PyObject *ret = NULL;
+ PyObject *name = NULL;
+ if (PyUnicode_Check(f->f_name)) {
+#ifdef Py_USING_UNICODE
+ const char *name_str;
+ name = PyUnicode_AsUnicodeEscapeString(f->f_name);
+ name_str = name ? PyString_AsString(name) : "?";
+ ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
+ f->f_fp == NULL ? "closed" : "open",
+ name_str,
+ PyString_AsString(f->f_mode),
+ f);
+ Py_XDECREF(name);
+ return ret;
+#endif
+ } else {
+ name = PyObject_Repr(f->f_name);
+ if (name == NULL)
+ return NULL;
+ ret = PyString_FromFormat("<%s file %s, mode '%s' at %p>",
+ f->f_fp == NULL ? "closed" : "open",
+ PyString_AsString(name),
+ PyString_AsString(f->f_mode),
+ f);
+ Py_XDECREF(name);
+ return ret;
+ }
+}
+
+static PyObject *
+file_close(PyFileObject *f)
+{
+ PyObject *sts = close_the_file(f);
+ if (sts) {
+ PyMem_Free(f->f_setbuf);
+ f->f_setbuf = NULL;
+ }
+ return sts;
+}
+
+
+/* Our very own off_t-like type, 64-bit if possible */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
+
+/* a portable fseek() function
+ return 0 on success, non-zero on failure (with errno set) */
+static int
+_portable_fseek(FILE *fp, Py_off_t offset, int whence)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ return fseek(fp, offset, whence);
+#elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8
+ return fseeko(fp, offset, whence);
+#elif defined(HAVE_FSEEK64)
+ return fseek64(fp, offset, whence);
+#elif defined(__BEOS__)
+ return _fseek(fp, offset, whence);
+#elif SIZEOF_FPOS_T >= 8
+ /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos()
+ and fgetpos() to implement fseek()*/
+ fpos_t pos;
+ switch (whence) {
+ case SEEK_END:
+#ifdef MS_WINDOWS
+ fflush(fp);
+ if (_lseeki64(fileno(fp), 0, 2) == -1)
+ return -1;
+#else
+ if (fseek(fp, 0, SEEK_END) != 0)
+ return -1;
+#endif
+ /* fall through */
+ case SEEK_CUR:
+ if (fgetpos(fp, &pos) != 0)
+ return -1;
+ offset += pos;
+ break;
+ /* case SEEK_SET: break; */
+ }
+ return fsetpos(fp, &offset);
+#else
+#error "Large file support, but no way to fseek."
+#endif
+}
+
+
+/* a portable ftell() function
+ Return -1 on failure with errno set appropriately, current file
+ position on success */
+static Py_off_t
+_portable_ftell(FILE* fp)
+{
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ return ftell(fp);
+#elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8
+ return ftello(fp);
+#elif defined(HAVE_FTELL64)
+ return ftell64(fp);
+#elif SIZEOF_FPOS_T >= 8
+ fpos_t pos;
+ if (fgetpos(fp, &pos) != 0)
+ return -1;
+ return pos;
+#else
+#error "Large file support, but no way to ftell."
+#endif
+}
+
+
+static PyObject *
+file_seek(PyFileObject *f, PyObject *args)
+{
+ int whence;
+ int ret;
+ Py_off_t offset;
+ PyObject *offobj, *off_index;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ drop_readahead(f);
+ whence = 0;
+ if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
+ return NULL;
+ off_index = PyNumber_Index(offobj);
+ if (!off_index) {
+ if (!PyFloat_Check(offobj))
+ return NULL;
+ /* Deprecated in 2.6 */
+ PyErr_Clear();
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "integer argument expected, got float",
+ 1) < 0)
+ return NULL;
+ off_index = offobj;
+ Py_INCREF(offobj);
+ }
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ offset = PyInt_AsLong(off_index);
+#else
+ offset = PyLong_Check(off_index) ?
+ PyLong_AsLongLong(off_index) : PyInt_AsLong(off_index);
+#endif
+ Py_DECREF(off_index);
+ if (PyErr_Occurred())
+ return NULL;
+
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ ret = _portable_fseek(f->f_fp, offset, whence);
+ FILE_END_ALLOW_THREADS(f)
+
+ if (ret != 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ f->f_skipnextlf = 0;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+#ifdef HAVE_FTRUNCATE
+static PyObject *
+file_truncate(PyFileObject *f, PyObject *args)
+{
+ Py_off_t newsize;
+ PyObject *newsizeobj = NULL;
+ Py_off_t initialpos;
+ int ret;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
+ if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
+ return NULL;
+
+ /* Get current file position. If the file happens to be open for
+ * update and the last operation was an input operation, C doesn't
+ * define what the later fflush() will do, but we promise truncate()
+ * won't change the current position (and fflush() *does* change it
+ * then at least on Windows). The easiest thing is to capture
+ * current pos now and seek back to it at the end.
+ */
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ initialpos = _portable_ftell(f->f_fp);
+ FILE_END_ALLOW_THREADS(f)
+ if (initialpos == -1)
+ goto onioerror;
+
+ /* Set newsize to current postion if newsizeobj NULL, else to the
+ * specified value.
+ */
+ if (newsizeobj != NULL) {
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ newsize = PyInt_AsLong(newsizeobj);
+#else
+ newsize = PyLong_Check(newsizeobj) ?
+ PyLong_AsLongLong(newsizeobj) :
+ PyInt_AsLong(newsizeobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+ }
+ else /* default to current position */
+ newsize = initialpos;
+
+ /* Flush the stream. We're mixing stream-level I/O with lower-level
+ * I/O, and a flush may be necessary to synch both platform views
+ * of the current file state.
+ */
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ ret = fflush(f->f_fp);
+ FILE_END_ALLOW_THREADS(f)
+ if (ret != 0)
+ goto onioerror;
+
+#ifdef MS_WINDOWS
+ /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
+ so don't even try using it. */
+ {
+ HANDLE hFile;
+
+ /* Have to move current pos to desired endpoint on Windows. */
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ ret = _portable_fseek(f->f_fp, newsize, SEEK_SET) != 0;
+ FILE_END_ALLOW_THREADS(f)
+ if (ret)
+ goto onioerror;
+
+ /* Truncate. Note that this may grow the file! */
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
+ ret = hFile == (HANDLE)-1;
+ if (ret == 0) {
+ ret = SetEndOfFile(hFile) == 0;
+ if (ret)
+ errno = EACCES;
+ }
+ FILE_END_ALLOW_THREADS(f)
+ if (ret)
+ goto onioerror;
+ }
+#else
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ ret = ftruncate(fileno(f->f_fp), newsize);
+ FILE_END_ALLOW_THREADS(f)
+ if (ret != 0)
+ goto onioerror;
+#endif /* !MS_WINDOWS */
+
+ /* Restore original file position. */
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ ret = _portable_fseek(f->f_fp, initialpos, SEEK_SET) != 0;
+ FILE_END_ALLOW_THREADS(f)
+ if (ret)
+ goto onioerror;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+onioerror:
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ return NULL;
+}
+#endif /* HAVE_FTRUNCATE */
+
+static PyObject *
+file_tell(PyFileObject *f)
+{
+ Py_off_t pos;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ pos = _portable_ftell(f->f_fp);
+ FILE_END_ALLOW_THREADS(f)
+
+ if (pos == -1) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ if (f->f_skipnextlf) {
+ int c;
+ c = GETC(f->f_fp);
+ if (c == '\n') {
+ f->f_newlinetypes |= NEWLINE_CRLF;
+ pos++;
+ f->f_skipnextlf = 0;
+ } else if (c != EOF) ungetc(c, f->f_fp);
+ }
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ return PyInt_FromLong(pos);
+#else
+ return PyLong_FromLongLong(pos);
+#endif
+}
+
+static PyObject *
+file_fileno(PyFileObject *f)
+{
+ if (f->f_fp == NULL)
+ return err_closed();
+ return PyInt_FromLong((long) fileno(f->f_fp));
+}
+
+static PyObject *
+file_flush(PyFileObject *f)
+{
+ int res;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ res = fflush(f->f_fp);
+ FILE_END_ALLOW_THREADS(f)
+ if (res != 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+file_isatty(PyFileObject *f)
+{
+ long res;
+ if (f->f_fp == NULL)
+ return err_closed();
+ FILE_BEGIN_ALLOW_THREADS(f)
+ res = isatty((int)fileno(f->f_fp));
+ FILE_END_ALLOW_THREADS(f)
+ return PyBool_FromLong(res);
+}
+
+
+#if BUFSIZ < 8192
+#define SMALLCHUNK 8192
+#else
+#define SMALLCHUNK BUFSIZ
+#endif
+
+static size_t
+new_buffersize(PyFileObject *f, size_t currentsize)
+{
+#ifdef HAVE_FSTAT
+ off_t pos, end;
+ struct stat st;
+ if (fstat(fileno(f->f_fp), &st) == 0) {
+ end = st.st_size;
+ /* The following is not a bug: we really need to call lseek()
+ *and* ftell(). The reason is that some stdio libraries
+ mistakenly flush their buffer when ftell() is called and
+ the lseek() call it makes fails, thereby throwing away
+ data that cannot be recovered in any way. To avoid this,
+ we first test lseek(), and only call ftell() if lseek()
+ works. We can't use the lseek() value either, because we
+ need to take the amount of buffered data into account.
+ (Yet another reason why stdio stinks. :-) */
+ pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
+ if (pos >= 0) {
+ pos = ftell(f->f_fp);
+ }
+ if (pos < 0)
+ clearerr(f->f_fp);
+ if (end > pos && pos >= 0)
+ return currentsize + end - pos + 1;
+ /* Add 1 so if the file were to grow we'd notice. */
+ }
+#endif
+ /* Expand the buffer by an amount proportional to the current size,
+ giving us amortized linear-time behavior. Use a less-than-double
+ growth factor to avoid excessive allocation. */
+ return currentsize + (currentsize >> 3) + 6;
+}
+
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN)
+#else
+#ifdef EWOULDBLOCK
+#define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define BLOCKED_ERRNO(x) ((x) == EAGAIN)
+#else
+#define BLOCKED_ERRNO(x) 0
+#endif
+#endif
+#endif
+
+static PyObject *
+file_read(PyFileObject *f, PyObject *args)
+{
+ long bytesrequested = -1;
+ size_t bytesread, buffersize, chunksize;
+ PyObject *v;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
+ if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
+ return NULL;
+ if (bytesrequested < 0)
+ buffersize = new_buffersize(f, (size_t)0);
+ else
+ buffersize = bytesrequested;
+ if (buffersize > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "requested number of bytes is more than a Python string can hold");
+ return NULL;
+ }
+ v = PyString_FromStringAndSize((char *)NULL, buffersize);
+ if (v == NULL)
+ return NULL;
+ bytesread = 0;
+ for (;;) {
+ int interrupted;
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread,
+ buffersize - bytesread, f->f_fp, (PyObject *)f);
+ interrupted = ferror(f->f_fp) && errno == EINTR;
+ FILE_END_ALLOW_THREADS(f)
+ if (interrupted) {
+ clearerr(f->f_fp);
+ if (PyErr_CheckSignals()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ }
+ if (chunksize == 0) {
+ if (interrupted)
+ continue;
+ if (!ferror(f->f_fp))
+ break;
+ clearerr(f->f_fp);
+ /* When in non-blocking mode, data shouldn't
+ * be discarded if a blocking signal was
+ * received. That will also happen if
+ * chunksize != 0, but bytesread < buffersize. */
+ if (bytesread > 0 && BLOCKED_ERRNO(errno))
+ break;
+ PyErr_SetFromErrno(PyExc_IOError);
+ Py_DECREF(v);
+ return NULL;
+ }
+ bytesread += chunksize;
+ if (bytesread < buffersize && !interrupted) {
+ clearerr(f->f_fp);
+ break;
+ }
+ if (bytesrequested < 0) {
+ buffersize = new_buffersize(f, buffersize);
+ if (_PyString_Resize(&v, buffersize) < 0)
+ return NULL;
+ } else {
+ /* Got what was requested. */
+ break;
+ }
+ }
+ if (bytesread != buffersize && _PyString_Resize(&v, bytesread))
+ return NULL;
+ return v;
+}
+
+static PyObject *
+file_readinto(PyFileObject *f, PyObject *args)
+{
+ char *ptr;
+ Py_ssize_t ntodo;
+ Py_ssize_t ndone, nnow;
+ Py_buffer pbuf;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
+ if (!PyArg_ParseTuple(args, "w*", &pbuf))
+ return NULL;
+ ptr = pbuf.buf;
+ ntodo = pbuf.len;
+ ndone = 0;
+ while (ntodo > 0) {
+ int interrupted;
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp,
+ (PyObject *)f);
+ interrupted = ferror(f->f_fp) && errno == EINTR;
+ FILE_END_ALLOW_THREADS(f)
+ if (interrupted) {
+ clearerr(f->f_fp);
+ if (PyErr_CheckSignals()) {
+ PyBuffer_Release(&pbuf);
+ return NULL;
+ }
+ }
+ if (nnow == 0) {
+ if (interrupted)
+ continue;
+ if (!ferror(f->f_fp))
+ break;
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ PyBuffer_Release(&pbuf);
+ return NULL;
+ }
+ ndone += nnow;
+ ntodo -= nnow;
+ }
+ PyBuffer_Release(&pbuf);
+ return PyInt_FromSsize_t(ndone);
+}
+
+/**************************************************************************
+Routine to get next line using platform fgets().
+
+Under MSVC 6:
+
++ MS threadsafe getc is very slow (multiple layers of function calls before+
+ after each character, to lock+unlock the stream).
++ The stream-locking functions are MS-internal -- can't access them from user
+ code.
++ There's nothing Tim could find in the MS C or platform SDK libraries that
+ can worm around this.
++ MS fgets locks/unlocks only once per line; it's the only hook we have.
+
+So we use fgets for speed(!), despite that it's painful.
+
+MS realloc is also slow.
+
+Reports from other platforms on this method vs getc_unlocked (which MS doesn't
+have):
+ Linux a wash
+ Solaris a wash
+ Tru64 Unix getline_via_fgets significantly faster
+
+CAUTION: The C std isn't clear about this: in those cases where fgets
+writes something into the buffer, can it write into any position beyond the
+required trailing null byte? MSVC 6 fgets does not, and no platform is (yet)
+known on which it does; and it would be a strange way to code fgets. Still,
+getline_via_fgets may not work correctly if it does. The std test
+test_bufio.py should fail if platform fgets() routinely writes beyond the
+trailing null byte. #define DONT_USE_FGETS_IN_GETLINE to disable this code.
+**************************************************************************/
+
+/* Use this routine if told to, or by default on non-get_unlocked()
+ * platforms unless told not to. Yikes! Let's spell that out:
+ * On a platform with getc_unlocked():
+ * By default, use getc_unlocked().
+ * If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
+ * On a platform without getc_unlocked():
+ * By default, use fgets().
+ * If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
+ */
+#if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
+#define USE_FGETS_IN_GETLINE
+#endif
+
+#if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
+#undef USE_FGETS_IN_GETLINE
+#endif
+
+#ifdef USE_FGETS_IN_GETLINE
+static PyObject*
+getline_via_fgets(PyFileObject *f, FILE *fp)
+{
+/* INITBUFSIZE is the maximum line length that lets us get away with the fast
+ * no-realloc, one-fgets()-call path. Boosting it isn't free, because we have
+ * to fill this much of the buffer with a known value in order to figure out
+ * how much of the buffer fgets() overwrites. So if INITBUFSIZE is larger
+ * than "most" lines, we waste time filling unused buffer slots. 100 is
+ * surely adequate for most peoples' email archives, chewing over source code,
+ * etc -- "regular old text files".
+ * MAXBUFSIZE is the maximum line length that lets us get away with the less
+ * fast (but still zippy) no-realloc, two-fgets()-call path. See above for
+ * cautions about boosting that. 300 was chosen because the worst real-life
+ * text-crunching job reported on Python-Dev was a mail-log crawler where over
+ * half the lines were 254 chars.
+ */
+#define INITBUFSIZE 100
+#define MAXBUFSIZE 300
+ char* p; /* temp */
+ char buf[MAXBUFSIZE];
+ PyObject* v; /* the string object result */
+ char* pvfree; /* address of next free slot */
+ char* pvend; /* address one beyond last free slot */
+ size_t nfree; /* # of free buffer slots; pvend-pvfree */
+ size_t total_v_size; /* total # of slots in buffer */
+ size_t increment; /* amount to increment the buffer */
+ size_t prev_v_size;
+
+ /* Optimize for normal case: avoid _PyString_Resize if at all
+ * possible via first reading into stack buffer "buf".
+ */
+ total_v_size = INITBUFSIZE; /* start small and pray */
+ pvfree = buf;
+ for (;;) {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ pvend = buf + total_v_size;
+ nfree = pvend - pvfree;
+ memset(pvfree, '\n', nfree);
+ assert(nfree < INT_MAX); /* Should be atmost MAXBUFSIZE */
+ p = fgets(pvfree, (int)nfree, fp);
+ FILE_END_ALLOW_THREADS(f)
+
+ if (p == NULL) {
+ clearerr(fp);
+ if (PyErr_CheckSignals())
+ return NULL;
+ v = PyString_FromStringAndSize(buf, pvfree - buf);
+ return v;
+ }
+ /* fgets read *something* */
+ p = memchr(pvfree, '\n', nfree);
+ if (p != NULL) {
+ /* Did the \n come from fgets or from us?
+ * Since fgets stops at the first \n, and then writes
+ * \0, if it's from fgets a \0 must be next. But if
+ * that's so, it could not have come from us, since
+ * the \n's we filled the buffer with have only more
+ * \n's to the right.
+ */
+ if (p+1 < pvend && *(p+1) == '\0') {
+ /* It's from fgets: we win! In particular,
+ * we haven't done any mallocs yet, and can
+ * build the final result on the first try.
+ */
+ ++p; /* include \n from fgets */
+ }
+ else {
+ /* Must be from us: fgets didn't fill the
+ * buffer and didn't find a newline, so it
+ * must be the last and newline-free line of
+ * the file.
+ */
+ assert(p > pvfree && *(p-1) == '\0');
+ --p; /* don't include \0 from fgets */
+ }
+ v = PyString_FromStringAndSize(buf, p - buf);
+ return v;
+ }
+ /* yuck: fgets overwrote all the newlines, i.e. the entire
+ * buffer. So this line isn't over yet, or maybe it is but
+ * we're exactly at EOF. If we haven't already, try using the
+ * rest of the stack buffer.
+ */
+ assert(*(pvend-1) == '\0');
+ if (pvfree == buf) {
+ pvfree = pvend - 1; /* overwrite trailing null */
+ total_v_size = MAXBUFSIZE;
+ }
+ else
+ break;
+ }
+
+ /* The stack buffer isn't big enough; malloc a string object and read
+ * into its buffer.
+ */
+ total_v_size = MAXBUFSIZE << 1;
+ v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
+ if (v == NULL)
+ return v;
+ /* copy over everything except the last null byte */
+ memcpy(BUF(v), buf, MAXBUFSIZE-1);
+ pvfree = BUF(v) + MAXBUFSIZE - 1;
+
+ /* Keep reading stuff into v; if it ever ends successfully, break
+ * after setting p one beyond the end of the line. The code here is
+ * very much like the code above, except reads into v's buffer; see
+ * the code above for detailed comments about the logic.
+ */
+ for (;;) {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ pvend = BUF(v) + total_v_size;
+ nfree = pvend - pvfree;
+ memset(pvfree, '\n', nfree);
+ assert(nfree < INT_MAX);
+ p = fgets(pvfree, (int)nfree, fp);
+ FILE_END_ALLOW_THREADS(f)
+
+ if (p == NULL) {
+ clearerr(fp);
+ if (PyErr_CheckSignals()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ p = pvfree;
+ break;
+ }
+ p = memchr(pvfree, '\n', nfree);
+ if (p != NULL) {
+ if (p+1 < pvend && *(p+1) == '\0') {
+ /* \n came from fgets */
+ ++p;
+ break;
+ }
+ /* \n came from us; last line of file, no newline */
+ assert(p > pvfree && *(p-1) == '\0');
+ --p;
+ break;
+ }
+ /* expand buffer and try again */
+ assert(*(pvend-1) == '\0');
+ increment = total_v_size >> 2; /* mild exponential growth */
+ prev_v_size = total_v_size;
+ total_v_size += increment;
+ /* check for overflow */
+ if (total_v_size <= prev_v_size ||
+ total_v_size > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "line is longer than a Python string can hold");
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (_PyString_Resize(&v, (int)total_v_size) < 0)
+ return NULL;
+ /* overwrite the trailing null byte */
+ pvfree = BUF(v) + (prev_v_size - 1);
+ }
+ if (BUF(v) + total_v_size != p && _PyString_Resize(&v, p - BUF(v)))
+ return NULL;
+ return v;
+#undef INITBUFSIZE
+#undef MAXBUFSIZE
+}
+#endif /* ifdef USE_FGETS_IN_GETLINE */
+
+/* Internal routine to get a line.
+ Size argument interpretation:
+ > 0: max length;
+ <= 0: read arbitrary line
+*/
+
+static PyObject *
+get_line(PyFileObject *f, int n)
+{
+ FILE *fp = f->f_fp;
+ int c;
+ char *buf, *end;
+ size_t total_v_size; /* total # of slots in buffer */
+ size_t used_v_size; /* # used slots in buffer */
+ size_t increment; /* amount to increment the buffer */
+ PyObject *v;
+ int newlinetypes = f->f_newlinetypes;
+ int skipnextlf = f->f_skipnextlf;
+ int univ_newline = f->f_univ_newline;
+
+#if defined(USE_FGETS_IN_GETLINE)
+ if (n <= 0 && !univ_newline )
+ return getline_via_fgets(f, fp);
+#endif
+ total_v_size = n > 0 ? n : 100;
+ v = PyString_FromStringAndSize((char *)NULL, total_v_size);
+ if (v == NULL)
+ return NULL;
+ buf = BUF(v);
+ end = buf + total_v_size;
+
+ for (;;) {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ FLOCKFILE(fp);
+ if (univ_newline) {
+ c = 'x'; /* Shut up gcc warning */
+ while ( buf != end && (c = GETC(fp)) != EOF ) {
+ if (skipnextlf ) {
+ skipnextlf = 0;
+ if (c == '\n') {
+ /* Seeing a \n here with
+ * skipnextlf true means we
+ * saw a \r before.
+ */
+ newlinetypes |= NEWLINE_CRLF;
+ c = GETC(fp);
+ if (c == EOF) break;
+ } else {
+ newlinetypes |= NEWLINE_CR;
+ }
+ }
+ if (c == '\r') {
+ skipnextlf = 1;
+ c = '\n';
+ } else if ( c == '\n')
+ newlinetypes |= NEWLINE_LF;
+ *buf++ = c;
+ if (c == '\n') break;
+ }
+ if (c == EOF) {
+ if (ferror(fp) && errno == EINTR) {
+ FUNLOCKFILE(fp);
+ FILE_ABORT_ALLOW_THREADS(f)
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+
+ if (PyErr_CheckSignals()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ /* We executed Python signal handlers and got no exception.
+ * Now back to reading the line where we left off. */
+ clearerr(fp);
+ continue;
+ }
+ if (skipnextlf)
+ newlinetypes |= NEWLINE_CR;
+ }
+ } else /* If not universal newlines use the normal loop */
+ while ((c = GETC(fp)) != EOF &&
+ (*buf++ = c) != '\n' &&
+ buf != end)
+ ;
+ FUNLOCKFILE(fp);
+ FILE_END_ALLOW_THREADS(f)
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+ if (c == '\n')
+ break;
+ if (c == EOF) {
+ if (ferror(fp)) {
+ if (errno == EINTR) {
+ if (PyErr_CheckSignals()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ /* We executed Python signal handlers and got no exception.
+ * Now back to reading the line where we left off. */
+ clearerr(fp);
+ continue;
+ }
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(fp);
+ Py_DECREF(v);
+ return NULL;
+ }
+ clearerr(fp);
+ if (PyErr_CheckSignals()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ break;
+ }
+ /* Must be because buf == end */
+ if (n > 0)
+ break;
+ used_v_size = total_v_size;
+ increment = total_v_size >> 2; /* mild exponential growth */
+ total_v_size += increment;
+ if (total_v_size > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "line is longer than a Python string can hold");
+ Py_DECREF(v);
+ return NULL;
+ }
+ if (_PyString_Resize(&v, total_v_size) < 0)
+ return NULL;
+ buf = BUF(v) + used_v_size;
+ end = BUF(v) + total_v_size;
+ }
+
+ used_v_size = buf - BUF(v);
+ if (used_v_size != total_v_size && _PyString_Resize(&v, used_v_size))
+ return NULL;
+ return v;
+}
+
+/* External C interface */
+
+PyObject *
+PyFile_GetLine(PyObject *f, int n)
+{
+ PyObject *result;
+
+ if (f == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ if (PyFile_Check(f)) {
+ PyFileObject *fo = (PyFileObject *)f;
+ if (fo->f_fp == NULL)
+ return err_closed();
+ if (!fo->readable)
+ return err_mode("reading");
+ /* refuse to mix with f.next() */
+ if (fo->f_buf != NULL &&
+ (fo->f_bufend - fo->f_bufptr) > 0 &&
+ fo->f_buf[0] != '\0')
+ return err_iterbuffered();
+ result = get_line(fo, n);
+ }
+ else {
+ PyObject *reader;
+ PyObject *args;
+
+ reader = PyObject_GetAttrString(f, "readline");
+ if (reader == NULL)
+ return NULL;
+ if (n <= 0)
+ args = PyTuple_New(0);
+ else
+ args = Py_BuildValue("(i)", n);
+ if (args == NULL) {
+ Py_DECREF(reader);
+ return NULL;
+ }
+ result = PyEval_CallObject(reader, args);
+ Py_DECREF(reader);
+ Py_DECREF(args);
+ if (result != NULL && !PyString_Check(result) &&
+ !PyUnicode_Check(result)) {
+ Py_DECREF(result);
+ result = NULL;
+ PyErr_SetString(PyExc_TypeError,
+ "object.readline() returned non-string");
+ }
+ }
+
+ if (n < 0 && result != NULL && PyString_Check(result)) {
+ char *s = PyString_AS_STRING(result);
+ Py_ssize_t len = PyString_GET_SIZE(result);
+ if (len == 0) {
+ Py_DECREF(result);
+ result = NULL;
+ PyErr_SetString(PyExc_EOFError,
+ "EOF when reading a line");
+ }
+ else if (s[len-1] == '\n') {
+ if (result->ob_refcnt == 1) {
+ if (_PyString_Resize(&result, len-1))
+ return NULL;
+ }
+ else {
+ PyObject *v;
+ v = PyString_FromStringAndSize(s, len-1);
+ Py_DECREF(result);
+ result = v;
+ }
+ }
+ }
+#ifdef Py_USING_UNICODE
+ if (n < 0 && result != NULL && PyUnicode_Check(result)) {
+ Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
+ Py_ssize_t len = PyUnicode_GET_SIZE(result);
+ if (len == 0) {
+ Py_DECREF(result);
+ result = NULL;
+ PyErr_SetString(PyExc_EOFError,
+ "EOF when reading a line");
+ }
+ else if (s[len-1] == '\n') {
+ if (result->ob_refcnt == 1)
+ PyUnicode_Resize(&result, len-1);
+ else {
+ PyObject *v;
+ v = PyUnicode_FromUnicode(s, len-1);
+ Py_DECREF(result);
+ result = v;
+ }
+ }
+ }
+#endif
+ return result;
+}
+
+/* Python method */
+
+static PyObject *
+file_readline(PyFileObject *f, PyObject *args)
+{
+ int n = -1;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
+ if (!PyArg_ParseTuple(args, "|i:readline", &n))
+ return NULL;
+ if (n == 0)
+ return PyString_FromString("");
+ if (n < 0)
+ n = 0;
+ return get_line(f, n);
+}
+
+static PyObject *
+file_readlines(PyFileObject *f, PyObject *args)
+{
+ long sizehint = 0;
+ PyObject *list = NULL;
+ PyObject *line;
+ char small_buffer[SMALLCHUNK];
+ char *buffer = small_buffer;
+ size_t buffersize = SMALLCHUNK;
+ PyObject *big_buffer = NULL;
+ size_t nfilled = 0;
+ size_t nread;
+ size_t totalread = 0;
+ char *p, *q, *end;
+ int err;
+ int shortread = 0; /* bool, did the previous read come up short? */
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
+ if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
+ return NULL;
+ if ((list = PyList_New(0)) == NULL)
+ return NULL;
+ for (;;) {
+ if (shortread)
+ nread = 0;
+ else {
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ nread = Py_UniversalNewlineFread(buffer+nfilled,
+ buffersize-nfilled, f->f_fp, (PyObject *)f);
+ FILE_END_ALLOW_THREADS(f)
+ shortread = (nread < buffersize-nfilled);
+ }
+ if (nread == 0) {
+ sizehint = 0;
+ if (!ferror(f->f_fp))
+ break;
+ if (errno == EINTR) {
+ if (PyErr_CheckSignals()) {
+ goto error;
+ }
+ clearerr(f->f_fp);
+ shortread = 0;
+ continue;
+ }
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ goto error;
+ }
+ totalread += nread;
+ p = (char *)memchr(buffer+nfilled, '\n', nread);
+ if (p == NULL) {
+ /* Need a larger buffer to fit this line */
+ nfilled += nread;
+ buffersize *= 2;
+ if (buffersize > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "line is longer than a Python string can hold");
+ goto error;
+ }
+ if (big_buffer == NULL) {
+ /* Create the big buffer */
+ big_buffer = PyString_FromStringAndSize(
+ NULL, buffersize);
+ if (big_buffer == NULL)
+ goto error;
+ buffer = PyString_AS_STRING(big_buffer);
+ memcpy(buffer, small_buffer, nfilled);
+ }
+ else {
+ /* Grow the big buffer */
+ if ( _PyString_Resize(&big_buffer, buffersize) < 0 )
+ goto error;
+ buffer = PyString_AS_STRING(big_buffer);
+ }
+ continue;
+ }
+ end = buffer+nfilled+nread;
+ q = buffer;
+ do {
+ /* Process complete lines */
+ p++;
+ line = PyString_FromStringAndSize(q, p-q);
+ if (line == NULL)
+ goto error;
+ err = PyList_Append(list, line);
+ Py_DECREF(line);
+ if (err != 0)
+ goto error;
+ q = p;
+ p = (char *)memchr(q, '\n', end-q);
+ } while (p != NULL);
+ /* Move the remaining incomplete line to the start */
+ nfilled = end-q;
+ memmove(buffer, q, nfilled);
+ if (sizehint > 0)
+ if (totalread >= (size_t)sizehint)
+ break;
+ }
+ if (nfilled != 0) {
+ /* Partial last line */
+ line = PyString_FromStringAndSize(buffer, nfilled);
+ if (line == NULL)
+ goto error;
+ if (sizehint > 0) {
+ /* Need to complete the last line */
+ PyObject *rest = get_line(f, 0);
+ if (rest == NULL) {
+ Py_DECREF(line);
+ goto error;
+ }
+ PyString_Concat(&line, rest);
+ Py_DECREF(rest);
+ if (line == NULL)
+ goto error;
+ }
+ err = PyList_Append(list, line);
+ Py_DECREF(line);
+ if (err != 0)
+ goto error;
+ }
+
+cleanup:
+ Py_XDECREF(big_buffer);
+ return list;
+
+error:
+ Py_CLEAR(list);
+ goto cleanup;
+}
+
+static PyObject *
+file_write(PyFileObject *f, PyObject *args)
+{
+ Py_buffer pbuf;
+ const char *s;
+ Py_ssize_t n, n2;
+ PyObject *encoded = NULL;
+ int err_flag = 0, err;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
+ if (f->f_binary) {
+ if (!PyArg_ParseTuple(args, "s*", &pbuf))
+ return NULL;
+ s = pbuf.buf;
+ n = pbuf.len;
+ }
+ else {
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, "O", &text))
+ return NULL;
+
+ if (PyString_Check(text)) {
+ s = PyString_AS_STRING(text);
+ n = PyString_GET_SIZE(text);
+#ifdef Py_USING_UNICODE
+ } else if (PyUnicode_Check(text)) {
+ const char *encoding, *errors;
+ if (f->f_encoding != Py_None)
+ encoding = PyString_AS_STRING(f->f_encoding);
+ else
+ encoding = PyUnicode_GetDefaultEncoding();
+ if (f->f_errors != Py_None)
+ errors = PyString_AS_STRING(f->f_errors);
+ else
+ errors = "strict";
+ encoded = PyUnicode_AsEncodedString(text, encoding, errors);
+ if (encoded == NULL)
+ return NULL;
+ s = PyString_AS_STRING(encoded);
+ n = PyString_GET_SIZE(encoded);
+#endif
+ } else {
+ if (PyObject_AsCharBuffer(text, &s, &n))
+ return NULL;
+ }
+ }
+ f->f_softspace = 0;
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ n2 = fwrite(s, 1, n, f->f_fp);
+ if (n2 != n || ferror(f->f_fp)) {
+ err_flag = 1;
+ err = errno;
+ }
+ FILE_END_ALLOW_THREADS(f)
+ Py_XDECREF(encoded);
+ if (f->f_binary)
+ PyBuffer_Release(&pbuf);
+ if (err_flag) {
+ errno = err;
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+file_writelines(PyFileObject *f, PyObject *seq)
+{
+#define CHUNKSIZE 1000
+ PyObject *list, *line;
+ PyObject *it; /* iter(seq) */
+ PyObject *result;
+ int index, islist;
+ Py_ssize_t i, j, nwritten, len;
+
+ assert(seq != NULL);
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
+
+ result = NULL;
+ list = NULL;
+ islist = PyList_Check(seq);
+ if (islist)
+ it = NULL;
+ else {
+ it = PyObject_GetIter(seq);
+ if (it == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "writelines() requires an iterable argument");
+ return NULL;
+ }
+ /* From here on, fail by going to error, to reclaim "it". */
+ list = PyList_New(CHUNKSIZE);
+ if (list == NULL)
+ goto error;
+ }
+
+ /* Strategy: slurp CHUNKSIZE lines into a private list,
+ checking that they are all strings, then write that list
+ without holding the interpreter lock, then come back for more. */
+ for (index = 0; ; index += CHUNKSIZE) {
+ if (islist) {
+ Py_XDECREF(list);
+ list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
+ if (list == NULL)
+ goto error;
+ j = PyList_GET_SIZE(list);
+ }
+ else {
+ for (j = 0; j < CHUNKSIZE; j++) {
+ line = PyIter_Next(it);
+ if (line == NULL) {
+ if (PyErr_Occurred())
+ goto error;
+ break;
+ }
+ PyList_SetItem(list, j, line);
+ }
+ /* The iterator might have closed the file on us. */
+ if (f->f_fp == NULL) {
+ err_closed();
+ goto error;
+ }
+ }
+ if (j == 0)
+ break;
+
+ /* Check that all entries are indeed strings. If not,
+ apply the same rules as for file.write() and
+ convert the results to strings. This is slow, but
+ seems to be the only way since all conversion APIs
+ could potentially execute Python code. */
+ for (i = 0; i < j; i++) {
+ PyObject *v = PyList_GET_ITEM(list, i);
+ if (!PyString_Check(v)) {
+ const char *buffer;
+ int res;
+ if (f->f_binary) {
+ res = PyObject_AsReadBuffer(v, (const void**)&buffer, &len);
+ } else {
+ res = PyObject_AsCharBuffer(v, &buffer, &len);
+ }
+ if (res) {
+ PyErr_SetString(PyExc_TypeError,
+ "writelines() argument must be a sequence of strings");
+ goto error;
+ }
+ line = PyString_FromStringAndSize(buffer,
+ len);
+ if (line == NULL)
+ goto error;
+ Py_DECREF(v);
+ PyList_SET_ITEM(list, i, line);
+ }
+ }
+
+ /* Since we are releasing the global lock, the
+ following code may *not* execute Python code. */
+ f->f_softspace = 0;
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ for (i = 0; i < j; i++) {
+ line = PyList_GET_ITEM(list, i);
+ len = PyString_GET_SIZE(line);
+ nwritten = fwrite(PyString_AS_STRING(line),
+ 1, len, f->f_fp);
+ if (nwritten != len) {
+ FILE_ABORT_ALLOW_THREADS(f)
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ goto error;
+ }
+ }
+ FILE_END_ALLOW_THREADS(f)
+
+ if (j < CHUNKSIZE)
+ break;
+ }
+
+ Py_INCREF(Py_None);
+ result = Py_None;
+ error:
+ Py_XDECREF(list);
+ Py_XDECREF(it);
+ return result;
+#undef CHUNKSIZE
+}
+
+static PyObject *
+file_self(PyFileObject *f)
+{
+ if (f->f_fp == NULL)
+ return err_closed();
+ Py_INCREF(f);
+ return (PyObject *)f;
+}
+
+static PyObject *
+file_xreadlines(PyFileObject *f)
+{
+ if (PyErr_WarnPy3k("f.xreadlines() not supported in 3.x, "
+ "try 'for line in f' instead", 1) < 0)
+ return NULL;
+ return file_self(f);
+}
+
+static PyObject *
+file_exit(PyObject *f, PyObject *args)
+{
+ PyObject *ret = PyObject_CallMethod(f, "close", NULL);
+ if (!ret)
+ /* If error occurred, pass through */
+ return NULL;
+ Py_DECREF(ret);
+ /* We cannot return the result of close since a true
+ * value will be interpreted as "yes, swallow the
+ * exception if one was raised inside the with block". */
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(readline_doc,
+"readline([size]) -> next line from the file, as a string.\n"
+"\n"
+"Retain newline. A non-negative size argument limits the maximum\n"
+"number of bytes to return (an incomplete line may be returned then).\n"
+"Return an empty string at EOF.");
+
+PyDoc_STRVAR(read_doc,
+"read([size]) -> read at most size bytes, returned as a string.\n"
+"\n"
+"If the size argument is negative or omitted, read until EOF is reached.\n"
+"Notice that when in non-blocking mode, less data than what was requested\n"
+"may be returned, even if no size parameter was given.");
+
+PyDoc_STRVAR(write_doc,
+"write(str) -> None. Write string str to file.\n"
+"\n"
+"Note that due to buffering, flush() or close() may be needed before\n"
+"the file on disk reflects the data written.");
+
+PyDoc_STRVAR(fileno_doc,
+"fileno() -> integer \"file descriptor\".\n"
+"\n"
+"This is needed for lower-level file interfaces, such os.read().");
+
+PyDoc_STRVAR(seek_doc,
+"seek(offset[, whence]) -> None. Move to new file position.\n"
+"\n"
+"Argument offset is a byte count. Optional argument whence defaults to\n"
+"0 (offset from start of file, offset should be >= 0); other values are 1\n"
+"(move relative to current position, positive or negative), and 2 (move\n"
+"relative to end of file, usually negative, although many platforms allow\n"
+"seeking beyond the end of a file). If the file is opened in text mode,\n"
+"only offsets returned by tell() are legal. Use of other offsets causes\n"
+"undefined behavior."
+"\n"
+"Note that not all file objects are seekable.");
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(truncate_doc,
+"truncate([size]) -> None. Truncate the file to at most size bytes.\n"
+"\n"
+"Size defaults to the current file position, as returned by tell().");
+#endif
+
+PyDoc_STRVAR(tell_doc,
+"tell() -> current file position, an integer (may be a long integer).");
+
+PyDoc_STRVAR(readinto_doc,
+"readinto() -> Undocumented. Don't use this; it may go away.");
+
+PyDoc_STRVAR(readlines_doc,
+"readlines([size]) -> list of strings, each a line from the file.\n"
+"\n"
+"Call readline() repeatedly and return a list of the lines so read.\n"
+"The optional size argument, if given, is an approximate bound on the\n"
+"total number of bytes in the lines returned.");
+
+PyDoc_STRVAR(xreadlines_doc,
+"xreadlines() -> returns self.\n"
+"\n"
+"For backward compatibility. File objects now include the performance\n"
+"optimizations previously implemented in the xreadlines module.");
+
+PyDoc_STRVAR(writelines_doc,
+"writelines(sequence_of_strings) -> None. Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added. The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
+
+PyDoc_STRVAR(flush_doc,
+"flush() -> None. Flush the internal I/O buffer.");
+
+PyDoc_STRVAR(close_doc,
+"close() -> None or (perhaps) an integer. Close the file.\n"
+"\n"
+"Sets data attribute .closed to True. A closed file cannot be used for\n"
+"further I/O operations. close() may be called more than once without\n"
+"error. Some kinds of file objects (for example, opened by popen())\n"
+"may return an exit status upon closing.");
+
+PyDoc_STRVAR(isatty_doc,
+"isatty() -> true or false. True if the file is connected to a tty device.");
+
+PyDoc_STRVAR(enter_doc,
+ "__enter__() -> self.");
+
+PyDoc_STRVAR(exit_doc,
+ "__exit__(*excinfo) -> None. Closes the file.");
+
+static PyMethodDef file_methods[] = {
+ {"readline", (PyCFunction)file_readline, METH_VARARGS, readline_doc},
+ {"read", (PyCFunction)file_read, METH_VARARGS, read_doc},
+ {"write", (PyCFunction)file_write, METH_VARARGS, write_doc},
+ {"fileno", (PyCFunction)file_fileno, METH_NOARGS, fileno_doc},
+ {"seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc},
+#ifdef HAVE_FTRUNCATE
+ {"truncate", (PyCFunction)file_truncate, METH_VARARGS, truncate_doc},
+#endif
+ {"tell", (PyCFunction)file_tell, METH_NOARGS, tell_doc},
+ {"readinto", (PyCFunction)file_readinto, METH_VARARGS, readinto_doc},
+ {"readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc},
+ {"xreadlines",(PyCFunction)file_xreadlines, METH_NOARGS, xreadlines_doc},
+ {"writelines",(PyCFunction)file_writelines, METH_O, writelines_doc},
+ {"flush", (PyCFunction)file_flush, METH_NOARGS, flush_doc},
+ {"close", (PyCFunction)file_close, METH_NOARGS, close_doc},
+ {"isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc},
+ {"__enter__", (PyCFunction)file_self, METH_NOARGS, enter_doc},
+ {"__exit__", (PyCFunction)file_exit, METH_VARARGS, exit_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+#define OFF(x) offsetof(PyFileObject, x)
+
+static PyMemberDef file_memberlist[] = {
+ {"mode", T_OBJECT, OFF(f_mode), RO,
+ "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"},
+ {"name", T_OBJECT, OFF(f_name), RO,
+ "file name"},
+ {"encoding", T_OBJECT, OFF(f_encoding), RO,
+ "file encoding"},
+ {"errors", T_OBJECT, OFF(f_errors), RO,
+ "Unicode error handler"},
+ /* getattr(f, "closed") is implemented without this table */
+ {NULL} /* Sentinel */
+};
+
+static PyObject *
+get_closed(PyFileObject *f, void *closure)
+{
+ return PyBool_FromLong((long)(f->f_fp == 0));
+}
+static PyObject *
+get_newlines(PyFileObject *f, void *closure)
+{
+ switch (f->f_newlinetypes) {
+ case NEWLINE_UNKNOWN:
+ Py_INCREF(Py_None);
+ return Py_None;
+ case NEWLINE_CR:
+ return PyString_FromString("\r");
+ case NEWLINE_LF:
+ return PyString_FromString("\n");
+ case NEWLINE_CR|NEWLINE_LF:
+ return Py_BuildValue("(ss)", "\r", "\n");
+ case NEWLINE_CRLF:
+ return PyString_FromString("\r\n");
+ case NEWLINE_CR|NEWLINE_CRLF:
+ return Py_BuildValue("(ss)", "\r", "\r\n");
+ case NEWLINE_LF|NEWLINE_CRLF:
+ return Py_BuildValue("(ss)", "\n", "\r\n");
+ case NEWLINE_CR|NEWLINE_LF|NEWLINE_CRLF:
+ return Py_BuildValue("(sss)", "\r", "\n", "\r\n");
+ default:
+ PyErr_Format(PyExc_SystemError,
+ "Unknown newlines value 0x%x\n",
+ f->f_newlinetypes);
+ return NULL;
+ }
+}
+
+static PyObject *
+get_softspace(PyFileObject *f, void *closure)
+{
+ if (PyErr_WarnPy3k("file.softspace not supported in 3.x", 1) < 0)
+ return NULL;
+ return PyInt_FromLong(f->f_softspace);
+}
+
+static int
+set_softspace(PyFileObject *f, PyObject *value)
+{
+ int new;
+ if (PyErr_WarnPy3k("file.softspace not supported in 3.x", 1) < 0)
+ return -1;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete softspace attribute");
+ return -1;
+ }
+
+ new = PyInt_AsLong(value);
+ if (new == -1 && PyErr_Occurred())
+ return -1;
+ f->f_softspace = new;
+ return 0;
+}
+
+static PyGetSetDef file_getsetlist[] = {
+ {"closed", (getter)get_closed, NULL, "True if the file is closed"},
+ {"newlines", (getter)get_newlines, NULL,
+ "end-of-line convention used in this file"},
+ {"softspace", (getter)get_softspace, (setter)set_softspace,
+ "flag indicating that a space needs to be printed; used by print"},
+ {0},
+};
+
+static void
+drop_readahead(PyFileObject *f)
+{
+ if (f->f_buf != NULL) {
+ PyMem_Free(f->f_buf);
+ f->f_buf = NULL;
+ }
+}
+
+/* Make sure that file has a readahead buffer with at least one byte
+ (unless at EOF) and no more than bufsize. Returns negative value on
+ error, will set MemoryError if bufsize bytes cannot be allocated. */
+static int
+readahead(PyFileObject *f, Py_ssize_t bufsize)
+{
+ Py_ssize_t chunksize;
+
+ if (f->f_buf != NULL) {
+ if( (f->f_bufend - f->f_bufptr) >= 1)
+ return 0;
+ else
+ drop_readahead(f);
+ }
+ if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ FILE_BEGIN_ALLOW_THREADS(f)
+ errno = 0;
+ chunksize = Py_UniversalNewlineFread(
+ f->f_buf, bufsize, f->f_fp, (PyObject *)f);
+ FILE_END_ALLOW_THREADS(f)
+ if (chunksize == 0) {
+ if (ferror(f->f_fp)) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(f->f_fp);
+ drop_readahead(f);
+ return -1;
+ }
+ }
+ f->f_bufptr = f->f_buf;
+ f->f_bufend = f->f_buf + chunksize;
+ return 0;
+}
+
+/* Used by file_iternext. The returned string will start with 'skip'
+ uninitialized bytes followed by the remainder of the line. Don't be
+ horrified by the recursive call: maximum recursion depth is limited by
+ logarithmic buffer growth to about 50 even when reading a 1gb line. */
+
+static PyStringObject *
+readahead_get_line_skip(PyFileObject *f, Py_ssize_t skip, Py_ssize_t bufsize)
+{
+ PyStringObject* s;
+ char *bufptr;
+ char *buf;
+ Py_ssize_t len;
+
+ if (f->f_buf == NULL)
+ if (readahead(f, bufsize) < 0)
+ return NULL;
+
+ len = f->f_bufend - f->f_bufptr;
+ if (len == 0)
+ return (PyStringObject *)
+ PyString_FromStringAndSize(NULL, skip);
+ bufptr = (char *)memchr(f->f_bufptr, '\n', len);
+ if (bufptr != NULL) {
+ bufptr++; /* Count the '\n' */
+ len = bufptr - f->f_bufptr;
+ s = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, skip + len);
+ if (s == NULL)
+ return NULL;
+ memcpy(PyString_AS_STRING(s) + skip, f->f_bufptr, len);
+ f->f_bufptr = bufptr;
+ if (bufptr == f->f_bufend)
+ drop_readahead(f);
+ } else {
+ bufptr = f->f_bufptr;
+ buf = f->f_buf;
+ f->f_buf = NULL; /* Force new readahead buffer */
+ assert(len <= PY_SSIZE_T_MAX - skip);
+ s = readahead_get_line_skip(f, skip + len, bufsize + (bufsize>>2));
+ if (s == NULL) {
+ PyMem_Free(buf);
+ return NULL;
+ }
+ memcpy(PyString_AS_STRING(s) + skip, bufptr, len);
+ PyMem_Free(buf);
+ }
+ return s;
+}
+
+/* A larger buffer size may actually decrease performance. */
+#define READAHEAD_BUFSIZE 8192
+
+static PyObject *
+file_iternext(PyFileObject *f)
+{
+ PyStringObject* l;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
+
+ l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
+ if (l == NULL || PyString_GET_SIZE(l) == 0) {
+ Py_XDECREF(l);
+ return NULL;
+ }
+ return (PyObject *)l;
+}
+
+
+static PyObject *
+file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+ static PyObject *not_yet_string;
+
+ assert(type != NULL && type->tp_alloc != NULL);
+
+ if (not_yet_string == NULL) {
+ not_yet_string = PyString_InternFromString("<uninitialized file>");
+ if (not_yet_string == NULL)
+ return NULL;
+ }
+
+ self = type->tp_alloc(type, 0);
+ if (self != NULL) {
+ /* Always fill in the name and mode, so that nobody else
+ needs to special-case NULLs there. */
+ Py_INCREF(not_yet_string);
+ ((PyFileObject *)self)->f_name = not_yet_string;
+ Py_INCREF(not_yet_string);
+ ((PyFileObject *)self)->f_mode = not_yet_string;
+ Py_INCREF(Py_None);
+ ((PyFileObject *)self)->f_encoding = Py_None;
+ Py_INCREF(Py_None);
+ ((PyFileObject *)self)->f_errors = Py_None;
+ ((PyFileObject *)self)->weakreflist = NULL;
+ ((PyFileObject *)self)->unlocked_count = 0;
+ }
+ return self;
+}
+
+static int
+file_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyFileObject *foself = (PyFileObject *)self;
+ int ret = 0;
+ static char *kwlist[] = {"name", "mode", "buffering", 0};
+ char *name = NULL;
+ char *mode = "r";
+ int bufsize = -1;
+ int wideargument = 0;
+#ifdef MS_WINDOWS
+ PyObject *po;
+#endif
+
+ assert(PyFile_Check(self));
+ if (foself->f_fp != NULL) {
+ /* Have to close the existing file first. */
+ PyObject *closeresult = file_close(foself);
+ if (closeresult == NULL)
+ return -1;
+ Py_DECREF(closeresult);
+ }
+
+#ifdef MS_WINDOWS
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
+ kwlist, &po, &mode, &bufsize)) {
+ wideargument = 1;
+ if (fill_file_fields(foself, NULL, po, mode,
+ fclose) == NULL)
+ goto Error;
+ } else {
+ /* Drop the argument parsing error as narrow
+ strings are also valid. */
+ PyErr_Clear();
+ }
+#endif
+
+ if (!wideargument) {
+ PyObject *o_name;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
+ Py_FileSystemDefaultEncoding,
+ &name,
+ &mode, &bufsize))
+ return -1;
+
+ /* We parse again to get the name as a PyObject */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:file",
+ kwlist, &o_name, &mode,
+ &bufsize))
+ goto Error;
+
+ if (fill_file_fields(foself, NULL, o_name, mode,
+ fclose) == NULL)
+ goto Error;
+ }
+ if (open_the_file(foself, name, mode) == NULL)
+ goto Error;
+ foself->f_setbuf = NULL;
+ PyFile_SetBufSize(self, bufsize);
+ goto Done;
+
+Error:
+ ret = -1;
+ /* fall through */
+Done:
+ PyMem_Free(name); /* free the encoded string */
+ return ret;
+}
+
+PyDoc_VAR(file_doc) =
+PyDoc_STR(
+"file(name[, mode[, buffering]]) -> file object\n"
+"\n"
+"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
+"writing or appending. The file will be created if it doesn't exist\n"
+"when opened for writing or appending; it will be truncated when\n"
+"opened for writing. Add a 'b' to the mode for binary files.\n"
+"Add a '+' to the mode to allow simultaneous reading and writing.\n"
+"If the buffering argument is given, 0 means unbuffered, 1 means line\n"
+"buffered, and larger numbers specify the buffer size. The preferred way\n"
+"to open a file is with the builtin open() function.\n"
+)
+PyDoc_STR(
+"Add a 'U' to mode to open the file for input with universal newline\n"
+"support. Any line ending in the input file will be seen as a '\\n'\n"
+"in Python. Also, a file so opened gains the attribute 'newlines';\n"
+"the value for this attribute is one of None (no newline read yet),\n"
+"'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n"
+"\n"
+"'U' cannot be combined with 'w' or '+' mode.\n"
+);
+
+PyTypeObject PyFile_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "file",
+ sizeof(PyFileObject),
+ 0,
+ (destructor)file_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)file_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 */
+ /* softspace is writable: we must supply tp_setattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
+ file_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyFileObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)file_self, /* tp_iter */
+ (iternextfunc)file_iternext, /* tp_iternext */
+ file_methods, /* tp_methods */
+ file_memberlist, /* tp_members */
+ file_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ file_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ file_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+/* Interface for the 'soft space' between print items. */
+
+int
+PyFile_SoftSpace(PyObject *f, int newflag)
+{
+ long oldflag = 0;
+ if (f == NULL) {
+ /* Do nothing */
+ }
+ else if (PyFile_Check(f)) {
+ oldflag = ((PyFileObject *)f)->f_softspace;
+ ((PyFileObject *)f)->f_softspace = newflag;
+ }
+ else {
+ PyObject *v;
+ v = PyObject_GetAttrString(f, "softspace");
+ if (v == NULL)
+ PyErr_Clear();
+ else {
+ if (PyInt_Check(v))
+ oldflag = PyInt_AsLong(v);
+ assert(oldflag < INT_MAX);
+ Py_DECREF(v);
+ }
+ v = PyInt_FromLong((long)newflag);
+ if (v == NULL)
+ PyErr_Clear();
+ else {
+ if (PyObject_SetAttrString(f, "softspace", v) != 0)
+ PyErr_Clear();
+ Py_DECREF(v);
+ }
+ }
+ return (int)oldflag;
+}
+
+/* Interfaces to write objects/strings to file-like objects */
+
+int
+PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
+{
+ PyObject *writer, *value, *args, *result;
+ if (f == NULL) {
+ PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
+ return -1;
+ }
+ else if (PyFile_Check(f)) {
+ PyFileObject *fobj = (PyFileObject *) f;
+#ifdef Py_USING_UNICODE
+ PyObject *enc = fobj->f_encoding;
+ int result;
+#endif
+ if (fobj->f_fp == NULL) {
+ err_closed();
+ return -1;
+ }
+#ifdef Py_USING_UNICODE
+ if ((flags & Py_PRINT_RAW) &&
+ PyUnicode_Check(v) && enc != Py_None) {
+ char *cenc = PyString_AS_STRING(enc);
+ char *errors = fobj->f_errors == Py_None ?
+ "strict" : PyString_AS_STRING(fobj->f_errors);
+ value = PyUnicode_AsEncodedString(v, cenc, errors);
+ if (value == NULL)
+ return -1;
+ } else {
+ value = v;
+ Py_INCREF(value);
+ }
+ result = file_PyObject_Print(value, fobj, flags);
+ Py_DECREF(value);
+ return result;
+#else
+ return file_PyObject_Print(v, fobj, flags);
+#endif
+ }
+ writer = PyObject_GetAttrString(f, "write");
+ if (writer == NULL)
+ return -1;
+ if (flags & Py_PRINT_RAW) {
+ if (PyUnicode_Check(v)) {
+ value = v;
+ Py_INCREF(value);
+ } else
+ value = PyObject_Str(v);
+ }
+ else
+ value = PyObject_Repr(v);
+ if (value == NULL) {
+ Py_DECREF(writer);
+ return -1;
+ }
+ args = PyTuple_Pack(1, value);
+ if (args == NULL) {
+ Py_DECREF(value);
+ Py_DECREF(writer);
+ return -1;
+ }
+ result = PyEval_CallObject(writer, args);
+ Py_DECREF(args);
+ Py_DECREF(value);
+ Py_DECREF(writer);
+ if (result == NULL)
+ return -1;
+ Py_DECREF(result);
+ return 0;
+}
+
+int
+PyFile_WriteString(const char *s, PyObject *f)
+{
+
+ if (f == NULL) {
+ /* Should be caused by a pre-existing error */
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError,
+ "null file for PyFile_WriteString");
+ return -1;
+ }
+ else if (PyFile_Check(f)) {
+ PyFileObject *fobj = (PyFileObject *) f;
+ FILE *fp = PyFile_AsFile(f);
+ if (fp == NULL) {
+ err_closed();
+ return -1;
+ }
+ FILE_BEGIN_ALLOW_THREADS(fobj)
+ fputs(s, fp);
+ FILE_END_ALLOW_THREADS(fobj)
+ return 0;
+ }
+ else if (!PyErr_Occurred()) {
+ PyObject *v = PyString_FromString(s);
+ int err;
+ if (v == NULL)
+ return -1;
+ err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
+ Py_DECREF(v);
+ return err;
+ }
+ else
+ return -1;
+}
+
+/* Try to get a file-descriptor from a Python object. If the object
+ is an integer or long integer, its value is returned. If not, the
+ object's fileno() method is called if it exists; the method must return
+ an integer or long integer, which is returned as the file descriptor value.
+ -1 is returned on failure.
+*/
+
+int PyObject_AsFileDescriptor(PyObject *o)
+{
+ int fd;
+ PyObject *meth;
+
+ if (PyInt_Check(o)) {
+ fd = _PyInt_AsInt(o);
+ }
+ else if (PyLong_Check(o)) {
+ fd = _PyLong_AsInt(o);
+ }
+ else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
+ {
+ PyObject *fno = PyEval_CallObject(meth, NULL);
+ Py_DECREF(meth);
+ if (fno == NULL)
+ return -1;
+
+ if (PyInt_Check(fno)) {
+ fd = _PyInt_AsInt(fno);
+ Py_DECREF(fno);
+ }
+ else if (PyLong_Check(fno)) {
+ fd = _PyLong_AsInt(fno);
+ Py_DECREF(fno);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "fileno() returned a non-integer");
+ Py_DECREF(fno);
+ return -1;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be an int, or have a fileno() method.");
+ return -1;
+ }
+
+ if (fd < 0) {
+ PyErr_Format(PyExc_ValueError,
+ "file descriptor cannot be a negative integer (%i)",
+ fd);
+ return -1;
+ }
+ return fd;
+}
+
+/* From here on we need access to the real fgets and fread */
+#undef fgets
+#undef fread
+
+/*
+** Py_UniversalNewlineFgets is an fgets variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** If fobj is NULL the routine always does newline conversion, and
+** it may peek one char ahead to gobble the second char in \r\n.
+** If fobj is non-NULL it must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+** Note that we need no error handling: fgets() treats error and eof
+** identically.
+*/
+char *
+Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
+{
+ char *p = buf;
+ int c;
+ int newlinetypes = 0;
+ int skipnextlf = 0;
+ int univ_newline = 1;
+
+ if (fobj) {
+ if (!PyFile_Check(fobj)) {
+ errno = ENXIO; /* What can you do... */
+ return NULL;
+ }
+ univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
+ if ( !univ_newline )
+ return fgets(buf, n, stream);
+ newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes;
+ skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf;
+ }
+ FLOCKFILE(stream);
+ c = 'x'; /* Shut up gcc warning */
+ while (--n > 0 && (c = GETC(stream)) != EOF ) {
+ if (skipnextlf ) {
+ skipnextlf = 0;
+ if (c == '\n') {
+ /* Seeing a \n here with skipnextlf true
+ ** means we saw a \r before.
+ */
+ newlinetypes |= NEWLINE_CRLF;
+ c = GETC(stream);
+ if (c == EOF) break;
+ } else {
+ /*
+ ** Note that c == EOF also brings us here,
+ ** so we're okay if the last char in the file
+ ** is a CR.
+ */
+ newlinetypes |= NEWLINE_CR;
+ }
+ }
+ if (c == '\r') {
+ /* A \r is translated into a \n, and we skip
+ ** an adjacent \n, if any. We don't set the
+ ** newlinetypes flag until we've seen the next char.
+ */
+ skipnextlf = 1;
+ c = '\n';
+ } else if ( c == '\n') {
+ newlinetypes |= NEWLINE_LF;
+ }
+ *p++ = c;
+ if (c == '\n') break;
+ }
+ if ( c == EOF && skipnextlf )
+ newlinetypes |= NEWLINE_CR;
+ FUNLOCKFILE(stream);
+ *p = '\0';
+ if (fobj) {
+ ((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
+ ((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
+ } else if ( skipnextlf ) {
+ /* If we have no file object we cannot save the
+ ** skipnextlf flag. We have to readahead, which
+ ** will cause a pause if we're reading from an
+ ** interactive stream, but that is very unlikely
+ ** unless we're doing something silly like
+ ** execfile("/dev/tty").
+ */
+ c = GETC(stream);
+ if ( c != '\n' )
+ ungetc(c, stream);
+ }
+ if (p == buf)
+ return NULL;
+ return buf;
+}
+
+/*
+** Py_UniversalNewlineFread is an fread variation that understands
+** all of \r, \n and \r\n conventions.
+** The stream should be opened in binary mode.
+** fobj must be a PyFileObject. In this case there
+** is no readahead but in stead a flag is used to skip a following
+** \n on the next read. Also, if the file is open in binary mode
+** the whole conversion is skipped. Finally, the routine keeps track of
+** the different types of newlines seen.
+*/
+size_t
+Py_UniversalNewlineFread(char *buf, size_t n,
+ FILE *stream, PyObject *fobj)
+{
+ char *dst = buf;
+ PyFileObject *f = (PyFileObject *)fobj;
+ int newlinetypes, skipnextlf;
+
+ assert(buf != NULL);
+ assert(stream != NULL);
+
+ if (!fobj || !PyFile_Check(fobj)) {
+ errno = ENXIO; /* What can you do... */
+ return 0;
+ }
+ if (!f->f_univ_newline)
+ return fread(buf, 1, n, stream);
+ newlinetypes = f->f_newlinetypes;
+ skipnextlf = f->f_skipnextlf;
+ /* Invariant: n is the number of bytes remaining to be filled
+ * in the buffer.
+ */
+ while (n) {
+ size_t nread;
+ int shortread;
+ char *src = dst;
+
+ nread = fread(dst, 1, n, stream);
+ assert(nread <= n);
+ if (nread == 0)
+ break;
+
+ n -= nread; /* assuming 1 byte out for each in; will adjust */
+ shortread = n != 0; /* true iff EOF or error */
+ while (nread--) {
+ char c = *src++;
+ if (c == '\r') {
+ /* Save as LF and set flag to skip next LF. */
+ *dst++ = '\n';
+ skipnextlf = 1;
+ }
+ else if (skipnextlf && c == '\n') {
+ /* Skip LF, and remember we saw CR LF. */
+ skipnextlf = 0;
+ newlinetypes |= NEWLINE_CRLF;
+ ++n;
+ }
+ else {
+ /* Normal char to be stored in buffer. Also
+ * update the newlinetypes flag if either this
+ * is an LF or the previous char was a CR.
+ */
+ if (c == '\n')
+ newlinetypes |= NEWLINE_LF;
+ else if (skipnextlf)
+ newlinetypes |= NEWLINE_CR;
+ *dst++ = c;
+ skipnextlf = 0;
+ }
+ }
+ if (shortread) {
+ /* If this is EOF, update type flags. */
+ if (skipnextlf && feof(stream))
+ newlinetypes |= NEWLINE_CR;
+ break;
+ }
+ }
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+ return dst - buf;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/floatobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/floatobject.c
new file mode 100644
index 0000000000..41db7a9b12
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/floatobject.c
@@ -0,0 +1,2708 @@
+
+/* Float object implementation */
+
+/* XXX There should be overflow checks here, but it's hard to check
+ for any kind of float exception without losing portability. */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <ctype.h>
+#include <float.h>
+
+#undef MAX
+#undef MIN
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#ifdef _OSF_SOURCE
+/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
+extern int finite(double);
+#endif
+
+/* Special free list -- see comments for same code in intobject.c. */
+#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
+#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
+#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
+
+struct _floatblock {
+ struct _floatblock *next;
+ PyFloatObject objects[N_FLOATOBJECTS];
+};
+
+typedef struct _floatblock PyFloatBlock;
+
+static PyFloatBlock *block_list = NULL;
+static PyFloatObject *free_list = NULL;
+
+static PyFloatObject *
+fill_free_list(void)
+{
+ PyFloatObject *p, *q;
+ /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
+ p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
+ if (p == NULL)
+ return (PyFloatObject *) PyErr_NoMemory();
+ ((PyFloatBlock *)p)->next = block_list;
+ block_list = (PyFloatBlock *)p;
+ p = &((PyFloatBlock *)p)->objects[0];
+ q = p + N_FLOATOBJECTS;
+ while (--q > p)
+ Py_TYPE(q) = (struct _typeobject *)(q-1);
+ Py_TYPE(q) = NULL;
+ return p + N_FLOATOBJECTS - 1;
+}
+
+double
+PyFloat_GetMax(void)
+{
+ return DBL_MAX;
+}
+
+double
+PyFloat_GetMin(void)
+{
+ return DBL_MIN;
+}
+
+static PyTypeObject FloatInfoType = {0, 0, 0, 0, 0, 0};
+
+PyDoc_STRVAR(floatinfo__doc__,
+"sys.float_info\n\
+\n\
+A structseq holding information about the float type. It contains low level\n\
+information about the precision and internal representation. Please study\n\
+your system's :file:`float.h` for more information.");
+
+static PyStructSequence_Field floatinfo_fields[] = {
+ {"max", "DBL_MAX -- maximum representable finite float"},
+ {"max_exp", "DBL_MAX_EXP -- maximum int e such that radix**(e-1) "
+ "is representable"},
+ {"max_10_exp", "DBL_MAX_10_EXP -- maximum int e such that 10**e "
+ "is representable"},
+ {"min", "DBL_MIN -- Minimum positive normalizer float"},
+ {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) "
+ "is a normalized float"},
+ {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is "
+ "a normalized"},
+ {"dig", "DBL_DIG -- digits"},
+ {"mant_dig", "DBL_MANT_DIG -- mantissa digits"},
+ {"epsilon", "DBL_EPSILON -- Difference between 1 and the next "
+ "representable float"},
+ {"radix", "FLT_RADIX -- radix of exponent"},
+ {"rounds", "FLT_ROUNDS -- addition rounds"},
+ {0}
+};
+
+static PyStructSequence_Desc floatinfo_desc = {
+ "sys.float_info", /* name */
+ floatinfo__doc__, /* doc */
+ floatinfo_fields, /* fields */
+ 11
+};
+
+PyObject *
+PyFloat_GetInfo(void)
+{
+ PyObject* floatinfo;
+ int pos = 0;
+
+ floatinfo = PyStructSequence_New(&FloatInfoType);
+ if (floatinfo == NULL) {
+ return NULL;
+ }
+
+#define SetIntFlag(flag) \
+ PyStructSequence_SET_ITEM(floatinfo, pos++, PyInt_FromLong(flag))
+#define SetDblFlag(flag) \
+ PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))
+
+ SetDblFlag(DBL_MAX);
+ SetIntFlag(DBL_MAX_EXP);
+ SetIntFlag(DBL_MAX_10_EXP);
+ SetDblFlag(DBL_MIN);
+ SetIntFlag(DBL_MIN_EXP);
+ SetIntFlag(DBL_MIN_10_EXP);
+ SetIntFlag(DBL_DIG);
+ SetIntFlag(DBL_MANT_DIG);
+ SetDblFlag(DBL_EPSILON);
+ SetIntFlag(FLT_RADIX);
+ SetIntFlag(FLT_ROUNDS);
+#undef SetIntFlag
+#undef SetDblFlag
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(floatinfo);
+ return NULL;
+ }
+ return floatinfo;
+}
+
+PyObject *
+PyFloat_FromDouble(double fval)
+{
+ register PyFloatObject *op;
+ if (free_list == NULL) {
+ if ((free_list = fill_free_list()) == NULL)
+ return NULL;
+ }
+ /* Inline PyObject_New */
+ op = free_list;
+ free_list = (PyFloatObject *)Py_TYPE(op);
+ PyObject_INIT(op, &PyFloat_Type);
+ op->ob_fval = fval;
+ return (PyObject *) op;
+}
+
+/**************************************************************************
+RED_FLAG 22-Sep-2000 tim
+PyFloat_FromString's pend argument is braindead. Prior to this RED_FLAG,
+
+1. If v was a regular string, *pend was set to point to its terminating
+ null byte. That's useless (the caller can find that without any
+ help from this function!).
+
+2. If v was a Unicode string, or an object convertible to a character
+ buffer, *pend was set to point into stack trash (the auto temp
+ vector holding the character buffer). That was downright dangerous.
+
+Since we can't change the interface of a public API function, pend is
+still supported but now *officially* useless: if pend is not NULL,
+*pend is set to NULL.
+**************************************************************************/
+PyObject *
+PyFloat_FromString(PyObject *v, char **pend)
+{
+ const char *s, *last, *end;
+ double x;
+ char buffer[256]; /* for errors */
+#ifdef Py_USING_UNICODE
+ char *s_buffer = NULL;
+#endif
+ Py_ssize_t len;
+ PyObject *result = NULL;
+
+ if (pend)
+ *pend = NULL;
+ if (PyString_Check(v)) {
+ s = PyString_AS_STRING(v);
+ len = PyString_GET_SIZE(v);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(v)) {
+ s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+ if (s_buffer == NULL)
+ return PyErr_NoMemory();
+ if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
+ PyUnicode_GET_SIZE(v),
+ s_buffer,
+ NULL))
+ goto error;
+ s = s_buffer;
+ len = strlen(s);
+ }
+#endif
+ else if (PyObject_AsCharBuffer(v, &s, &len)) {
+ PyErr_SetString(PyExc_TypeError,
+ "float() argument must be a string or a number");
+ return NULL;
+ }
+ last = s + len;
+
+ while (Py_ISSPACE(*s))
+ s++;
+ /* We don't care about overflow or underflow. If the platform
+ * supports them, infinities and signed zeroes (on underflow) are
+ * fine. */
+ x = PyOS_string_to_double(s, (char **)&end, NULL);
+ if (x == -1.0 && PyErr_Occurred())
+ goto error;
+ while (Py_ISSPACE(*end))
+ end++;
+ if (end == last)
+ result = PyFloat_FromDouble(x);
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "invalid literal for float(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ result = NULL;
+ }
+
+ error:
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return result;
+}
+
+static void
+float_dealloc(PyFloatObject *op)
+{
+ if (PyFloat_CheckExact(op)) {
+ Py_TYPE(op) = (struct _typeobject *)free_list;
+ free_list = op;
+ }
+ else
+ Py_TYPE(op)->tp_free((PyObject *)op);
+}
+
+double
+PyFloat_AsDouble(PyObject *op)
+{
+ PyNumberMethods *nb;
+ PyFloatObject *fo;
+ double val;
+
+ if (op && PyFloat_Check(op))
+ return PyFloat_AS_DOUBLE((PyFloatObject*) op);
+
+ if (op == NULL) {
+ PyErr_BadArgument();
+ return -1;
+ }
+
+ if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) {
+ PyErr_SetString(PyExc_TypeError, "a float is required");
+ return -1;
+ }
+
+ fo = (PyFloatObject*) (*nb->nb_float) (op);
+ if (fo == NULL)
+ return -1;
+ if (!PyFloat_Check(fo)) {
+ Py_DECREF(fo);
+ PyErr_SetString(PyExc_TypeError,
+ "nb_float should return float object");
+ return -1;
+ }
+
+ val = PyFloat_AS_DOUBLE(fo);
+ Py_DECREF(fo);
+
+ return val;
+}
+
+/* Methods */
+
+/* Macro and helper that convert PyObject obj to a C double and store
+ the value in dbl; this replaces the functionality of the coercion
+ slot function. If conversion to double raises an exception, obj is
+ set to NULL, and the function invoking this macro returns NULL. If
+ obj is not of float, int or long type, Py_NotImplemented is incref'ed,
+ stored in obj, and returned from the function invoking this macro.
+*/
+#define CONVERT_TO_DOUBLE(obj, dbl) \
+ if (PyFloat_Check(obj)) \
+ dbl = PyFloat_AS_DOUBLE(obj); \
+ else if (convert_to_double(&(obj), &(dbl)) < 0) \
+ return obj;
+
+static int
+convert_to_double(PyObject **v, double *dbl)
+{
+ register PyObject *obj = *v;
+
+ if (PyInt_Check(obj)) {
+ *dbl = (double)PyInt_AS_LONG(obj);
+ }
+ else if (PyLong_Check(obj)) {
+ *dbl = PyLong_AsDouble(obj);
+ if (*dbl == -1.0 && PyErr_Occurred()) {
+ *v = NULL;
+ return -1;
+ }
+ }
+ else {
+ Py_INCREF(Py_NotImplemented);
+ *v = Py_NotImplemented;
+ return -1;
+ }
+ return 0;
+}
+
+/* XXX PyFloat_AsString and PyFloat_AsReprString are deprecated:
+ XXX they pass a char buffer without passing a length.
+*/
+void
+PyFloat_AsString(char *buf, PyFloatObject *v)
+{
+ char *tmp = PyOS_double_to_string(v->ob_fval, 'g',
+ PyFloat_STR_PRECISION,
+ Py_DTSF_ADD_DOT_0, NULL);
+ strcpy(buf, tmp);
+ PyMem_Free(tmp);
+}
+
+void
+PyFloat_AsReprString(char *buf, PyFloatObject *v)
+{
+ char * tmp = PyOS_double_to_string(v->ob_fval, 'r', 0,
+ Py_DTSF_ADD_DOT_0, NULL);
+ strcpy(buf, tmp);
+ PyMem_Free(tmp);
+}
+
+/* ARGSUSED */
+static int
+float_print(PyFloatObject *v, FILE *fp, int flags)
+{
+ char *buf;
+ if (flags & Py_PRINT_RAW)
+ buf = PyOS_double_to_string(v->ob_fval,
+ 'g', PyFloat_STR_PRECISION,
+ Py_DTSF_ADD_DOT_0, NULL);
+ else
+ buf = PyOS_double_to_string(v->ob_fval,
+ 'r', 0, Py_DTSF_ADD_DOT_0, NULL);
+ Py_BEGIN_ALLOW_THREADS
+ fputs(buf, fp);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(buf);
+ return 0;
+}
+
+static PyObject *
+float_str_or_repr(PyFloatObject *v, int precision, char format_code)
+{
+ PyObject *result;
+ char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
+ format_code, precision,
+ Py_DTSF_ADD_DOT_0,
+ NULL);
+ if (!buf)
+ return PyErr_NoMemory();
+ result = PyString_FromString(buf);
+ PyMem_Free(buf);
+ return result;
+}
+
+static PyObject *
+float_repr(PyFloatObject *v)
+{
+ return float_str_or_repr(v, 0, 'r');
+}
+
+static PyObject *
+float_str(PyFloatObject *v)
+{
+ return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');
+}
+
+/* Comparison is pretty much a nightmare. When comparing float to float,
+ * we do it as straightforwardly (and long-windedly) as conceivable, so
+ * that, e.g., Python x == y delivers the same result as the platform
+ * C x == y when x and/or y is a NaN.
+ * When mixing float with an integer type, there's no good *uniform* approach.
+ * Converting the double to an integer obviously doesn't work, since we
+ * may lose info from fractional bits. Converting the integer to a double
+ * also has two failure modes: (1) a long int may trigger overflow (too
+ * large to fit in the dynamic range of a C double); (2) even a C long may have
+ * more bits than fit in a C double (e.g., on a a 64-bit box long may have
+ * 63 bits of precision, but a C double probably has only 53), and then
+ * we can falsely claim equality when low-order integer bits are lost by
+ * coercion to double. So this part is painful too.
+ */
+
+static PyObject*
+float_richcompare(PyObject *v, PyObject *w, int op)
+{
+ double i, j;
+ int r = 0;
+
+ assert(PyFloat_Check(v));
+ i = PyFloat_AS_DOUBLE(v);
+
+ /* Switch on the type of w. Set i and j to doubles to be compared,
+ * and op to the richcomp to use.
+ */
+ if (PyFloat_Check(w))
+ j = PyFloat_AS_DOUBLE(w);
+
+ else if (!Py_IS_FINITE(i)) {
+ if (PyInt_Check(w) || PyLong_Check(w))
+ /* If i is an infinity, its magnitude exceeds any
+ * finite integer, so it doesn't matter which int we
+ * compare i with. If i is a NaN, similarly.
+ */
+ j = 0.0;
+ else
+ goto Unimplemented;
+ }
+
+ else if (PyInt_Check(w)) {
+ long jj = PyInt_AS_LONG(w);
+ /* In the worst realistic case I can imagine, C double is a
+ * Cray single with 48 bits of precision, and long has 64
+ * bits.
+ */
+#if SIZEOF_LONG > 6
+ unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj);
+ if (abs >> 48) {
+ /* Needs more than 48 bits. Make it take the
+ * PyLong path.
+ */
+ PyObject *result;
+ PyObject *ww = PyLong_FromLong(jj);
+
+ if (ww == NULL)
+ return NULL;
+ result = float_richcompare(v, ww, op);
+ Py_DECREF(ww);
+ return result;
+ }
+#endif
+ j = (double)jj;
+ assert((long)j == jj);
+ }
+
+ else if (PyLong_Check(w)) {
+ int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
+ int wsign = _PyLong_Sign(w);
+ size_t nbits;
+ int exponent;
+
+ if (vsign != wsign) {
+ /* Magnitudes are irrelevant -- the signs alone
+ * determine the outcome.
+ */
+ i = (double)vsign;
+ j = (double)wsign;
+ goto Compare;
+ }
+ /* The signs are the same. */
+ /* Convert w to a double if it fits. In particular, 0 fits. */
+ nbits = _PyLong_NumBits(w);
+ if (nbits == (size_t)-1 && PyErr_Occurred()) {
+ /* This long is so large that size_t isn't big enough
+ * to hold the # of bits. Replace with little doubles
+ * that give the same outcome -- w is so large that
+ * its magnitude must exceed the magnitude of any
+ * finite float.
+ */
+ PyErr_Clear();
+ i = (double)vsign;
+ assert(wsign != 0);
+ j = wsign * 2.0;
+ goto Compare;
+ }
+ if (nbits <= 48) {
+ j = PyLong_AsDouble(w);
+ /* It's impossible that <= 48 bits overflowed. */
+ assert(j != -1.0 || ! PyErr_Occurred());
+ goto Compare;
+ }
+ assert(wsign != 0); /* else nbits was 0 */
+ assert(vsign != 0); /* if vsign were 0, then since wsign is
+ * not 0, we would have taken the
+ * vsign != wsign branch at the start */
+ /* We want to work with non-negative numbers. */
+ if (vsign < 0) {
+ /* "Multiply both sides" by -1; this also swaps the
+ * comparator.
+ */
+ i = -i;
+ op = _Py_SwappedOp[op];
+ }
+ assert(i > 0.0);
+ (void) frexp(i, &exponent);
+ /* exponent is the # of bits in v before the radix point;
+ * we know that nbits (the # of bits in w) > 48 at this point
+ */
+ if (exponent < 0 || (size_t)exponent < nbits) {
+ i = 1.0;
+ j = 2.0;
+ goto Compare;
+ }
+ if ((size_t)exponent > nbits) {
+ i = 2.0;
+ j = 1.0;
+ goto Compare;
+ }
+ /* v and w have the same number of bits before the radix
+ * point. Construct two longs that have the same comparison
+ * outcome.
+ */
+ {
+ double fracpart;
+ double intpart;
+ PyObject *result = NULL;
+ PyObject *one = NULL;
+ PyObject *vv = NULL;
+ PyObject *ww = w;
+
+ if (wsign < 0) {
+ ww = PyNumber_Negative(w);
+ if (ww == NULL)
+ goto Error;
+ }
+ else
+ Py_INCREF(ww);
+
+ fracpart = modf(i, &intpart);
+ vv = PyLong_FromDouble(intpart);
+ if (vv == NULL)
+ goto Error;
+
+ if (fracpart != 0.0) {
+ /* Shift left, and or a 1 bit into vv
+ * to represent the lost fraction.
+ */
+ PyObject *temp;
+
+ one = PyInt_FromLong(1);
+ if (one == NULL)
+ goto Error;
+
+ temp = PyNumber_Lshift(ww, one);
+ if (temp == NULL)
+ goto Error;
+ Py_DECREF(ww);
+ ww = temp;
+
+ temp = PyNumber_Lshift(vv, one);
+ if (temp == NULL)
+ goto Error;
+ Py_DECREF(vv);
+ vv = temp;
+
+ temp = PyNumber_Or(vv, one);
+ if (temp == NULL)
+ goto Error;
+ Py_DECREF(vv);
+ vv = temp;
+ }
+
+ r = PyObject_RichCompareBool(vv, ww, op);
+ if (r < 0)
+ goto Error;
+ result = PyBool_FromLong(r);
+ Error:
+ Py_XDECREF(vv);
+ Py_XDECREF(ww);
+ Py_XDECREF(one);
+ return result;
+ }
+ } /* else if (PyLong_Check(w)) */
+
+ else /* w isn't float, int, or long */
+ goto Unimplemented;
+
+ Compare:
+ PyFPE_START_PROTECT("richcompare", return NULL)
+ switch (op) {
+ case Py_EQ:
+ r = i == j;
+ break;
+ case Py_NE:
+ r = i != j;
+ break;
+ case Py_LE:
+ r = i <= j;
+ break;
+ case Py_GE:
+ r = i >= j;
+ break;
+ case Py_LT:
+ r = i < j;
+ break;
+ case Py_GT:
+ r = i > j;
+ break;
+ }
+ PyFPE_END_PROTECT(r)
+ return PyBool_FromLong(r);
+
+ Unimplemented:
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static long
+float_hash(PyFloatObject *v)
+{
+ return _Py_HashDouble(v->ob_fval);
+}
+
+static PyObject *
+float_add(PyObject *v, PyObject *w)
+{
+ double a,b;
+ CONVERT_TO_DOUBLE(v, a);
+ CONVERT_TO_DOUBLE(w, b);
+ PyFPE_START_PROTECT("add", return 0)
+ a = a + b;
+ PyFPE_END_PROTECT(a)
+ return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_sub(PyObject *v, PyObject *w)
+{
+ double a,b;
+ CONVERT_TO_DOUBLE(v, a);
+ CONVERT_TO_DOUBLE(w, b);
+ PyFPE_START_PROTECT("subtract", return 0)
+ a = a - b;
+ PyFPE_END_PROTECT(a)
+ return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_mul(PyObject *v, PyObject *w)
+{
+ double a,b;
+ CONVERT_TO_DOUBLE(v, a);
+ CONVERT_TO_DOUBLE(w, b);
+ PyFPE_START_PROTECT("multiply", return 0)
+ a = a * b;
+ PyFPE_END_PROTECT(a)
+ return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_div(PyObject *v, PyObject *w)
+{
+ double a,b;
+ CONVERT_TO_DOUBLE(v, a);
+ CONVERT_TO_DOUBLE(w, b);
+#ifdef Py_NAN
+ if (b == 0.0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "float division by zero");
+ return NULL;
+ }
+#endif
+ PyFPE_START_PROTECT("divide", return 0)
+ a = a / b;
+ PyFPE_END_PROTECT(a)
+ return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_classic_div(PyObject *v, PyObject *w)
+{
+ double a,b;
+ CONVERT_TO_DOUBLE(v, a);
+ CONVERT_TO_DOUBLE(w, b);
+ if (Py_DivisionWarningFlag >= 2 &&
+ PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0)
+ return NULL;
+#ifdef Py_NAN
+ if (b == 0.0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "float division by zero");
+ return NULL;
+ }
+#endif
+ PyFPE_START_PROTECT("divide", return 0)
+ a = a / b;
+ PyFPE_END_PROTECT(a)
+ return PyFloat_FromDouble(a);
+}
+
+static PyObject *
+float_rem(PyObject *v, PyObject *w)
+{
+ double vx, wx;
+ double mod;
+ CONVERT_TO_DOUBLE(v, vx);
+ CONVERT_TO_DOUBLE(w, wx);
+#ifdef Py_NAN
+ if (wx == 0.0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "float modulo");
+ return NULL;
+ }
+#endif
+ PyFPE_START_PROTECT("modulo", return 0)
+ mod = fmod(vx, wx);
+ if (mod) {
+ /* ensure the remainder has the same sign as the denominator */
+ if ((wx < 0) != (mod < 0)) {
+ mod += wx;
+ }
+ }
+ else {
+ /* the remainder is zero, and in the presence of signed zeroes
+ fmod returns different results across platforms; ensure
+ it has the same sign as the denominator; we'd like to do
+ "mod = wx * 0.0", but that may get optimized away */
+ mod *= mod; /* hide "mod = +0" from optimizer */
+ if (wx < 0.0)
+ mod = -mod;
+ }
+ PyFPE_END_PROTECT(mod)
+ return PyFloat_FromDouble(mod);
+}
+
+static PyObject *
+float_divmod(PyObject *v, PyObject *w)
+{
+ double vx, wx;
+ double div, mod, floordiv;
+ CONVERT_TO_DOUBLE(v, vx);
+ CONVERT_TO_DOUBLE(w, wx);
+ if (wx == 0.0) {
+ PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
+ return NULL;
+ }
+ PyFPE_START_PROTECT("divmod", return 0)
+ mod = fmod(vx, wx);
+ /* fmod is typically exact, so vx-mod is *mathematically* an
+ exact multiple of wx. But this is fp arithmetic, and fp
+ vx - mod is an approximation; the result is that div may
+ not be an exact integral value after the division, although
+ it will always be very close to one.
+ */
+ div = (vx - mod) / wx;
+ if (mod) {
+ /* ensure the remainder has the same sign as the denominator */
+ if ((wx < 0) != (mod < 0)) {
+ mod += wx;
+ div -= 1.0;
+ }
+ }
+ else {
+ /* the remainder is zero, and in the presence of signed zeroes
+ fmod returns different results across platforms; ensure
+ it has the same sign as the denominator; we'd like to do
+ "mod = wx * 0.0", but that may get optimized away */
+ mod *= mod; /* hide "mod = +0" from optimizer */
+ if (wx < 0.0)
+ mod = -mod;
+ }
+ /* snap quotient to nearest integral value */
+ if (div) {
+ floordiv = floor(div);
+ if (div - floordiv > 0.5)
+ floordiv += 1.0;
+ }
+ else {
+ /* div is zero - get the same sign as the true quotient */
+ div *= div; /* hide "div = +0" from optimizers */
+ floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
+ }
+ PyFPE_END_PROTECT(floordiv)
+ return Py_BuildValue("(dd)", floordiv, mod);
+}
+
+static PyObject *
+float_floor_div(PyObject *v, PyObject *w)
+{
+ PyObject *t, *r;
+
+ t = float_divmod(v, w);
+ if (t == NULL || t == Py_NotImplemented)
+ return t;
+ assert(PyTuple_CheckExact(t));
+ r = PyTuple_GET_ITEM(t, 0);
+ Py_INCREF(r);
+ Py_DECREF(t);
+ return r;
+}
+
+/* determine whether x is an odd integer or not; assumes that
+ x is not an infinity or nan. */
+#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0)
+
+static PyObject *
+float_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+ double iv, iw, ix;
+ int negate_result = 0;
+
+ if ((PyObject *)z != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
+ "allowed unless all arguments are integers");
+ return NULL;
+ }
+
+ CONVERT_TO_DOUBLE(v, iv);
+ CONVERT_TO_DOUBLE(w, iw);
+
+ /* Sort out special cases here instead of relying on pow() */
+ if (iw == 0) { /* v**0 is 1, even 0**0 */
+ return PyFloat_FromDouble(1.0);
+ }
+ if (Py_IS_NAN(iv)) { /* nan**w = nan, unless w == 0 */
+ return PyFloat_FromDouble(iv);
+ }
+ if (Py_IS_NAN(iw)) { /* v**nan = nan, unless v == 1; 1**nan = 1 */
+ return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw);
+ }
+ if (Py_IS_INFINITY(iw)) {
+ /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if
+ * abs(v) > 1 (including case where v infinite)
+ *
+ * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if
+ * abs(v) > 1 (including case where v infinite)
+ */
+ iv = fabs(iv);
+ if (iv == 1.0)
+ return PyFloat_FromDouble(1.0);
+ else if ((iw > 0.0) == (iv > 1.0))
+ return PyFloat_FromDouble(fabs(iw)); /* return inf */
+ else
+ return PyFloat_FromDouble(0.0);
+ }
+ if (Py_IS_INFINITY(iv)) {
+ /* (+-inf)**w is: inf for w positive, 0 for w negative; in
+ * both cases, we need to add the appropriate sign if w is
+ * an odd integer.
+ */
+ int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
+ if (iw > 0.0)
+ return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv));
+ else
+ return PyFloat_FromDouble(iw_is_odd ?
+ copysign(0.0, iv) : 0.0);
+ }
+ if (iv == 0.0) { /* 0**w is: 0 for w positive, 1 for w zero
+ (already dealt with above), and an error
+ if w is negative. */
+ int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
+ if (iw < 0.0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "0.0 cannot be raised to a "
+ "negative power");
+ return NULL;
+ }
+ /* use correct sign if iw is odd */
+ return PyFloat_FromDouble(iw_is_odd ? iv : 0.0);
+ }
+
+ if (iv < 0.0) {
+ /* Whether this is an error is a mess, and bumps into libm
+ * bugs so we have to figure it out ourselves.
+ */
+ if (iw != floor(iw)) {
+ PyErr_SetString(PyExc_ValueError, "negative number "
+ "cannot be raised to a fractional power");
+ return NULL;
+ }
+ /* iw is an exact integer, albeit perhaps a very large
+ * one. Replace iv by its absolute value and remember
+ * to negate the pow result if iw is odd.
+ */
+ iv = -iv;
+ negate_result = DOUBLE_IS_ODD_INTEGER(iw);
+ }
+
+ if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
+ /* (-1) ** large_integer also ends up here. Here's an
+ * extract from the comments for the previous
+ * implementation explaining why this special case is
+ * necessary:
+ *
+ * -1 raised to an exact integer should never be exceptional.
+ * Alas, some libms (chiefly glibc as of early 2003) return
+ * NaN and set EDOM on pow(-1, large_int) if the int doesn't
+ * happen to be representable in a *C* integer. That's a
+ * bug.
+ */
+ return PyFloat_FromDouble(negate_result ? -1.0 : 1.0);
+ }
+
+ /* Now iv and iw are finite, iw is nonzero, and iv is
+ * positive and not equal to 1.0. We finally allow
+ * the platform pow to step in and do the rest.
+ */
+ errno = 0;
+ PyFPE_START_PROTECT("pow", return NULL)
+ ix = pow(iv, iw);
+ PyFPE_END_PROTECT(ix)
+ Py_ADJUST_ERANGE1(ix);
+ if (negate_result)
+ ix = -ix;
+
+ if (errno != 0) {
+ /* We don't expect any errno value other than ERANGE, but
+ * the range of libm bugs appears unbounded.
+ */
+ PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+ PyExc_ValueError);
+ return NULL;
+ }
+ return PyFloat_FromDouble(ix);
+}
+
+#undef DOUBLE_IS_ODD_INTEGER
+
+static PyObject *
+float_neg(PyFloatObject *v)
+{
+ return PyFloat_FromDouble(-v->ob_fval);
+}
+
+static PyObject *
+float_abs(PyFloatObject *v)
+{
+ return PyFloat_FromDouble(fabs(v->ob_fval));
+}
+
+static int
+float_nonzero(PyFloatObject *v)
+{
+ return v->ob_fval != 0.0;
+}
+
+static int
+float_coerce(PyObject **pv, PyObject **pw)
+{
+ if (PyInt_Check(*pw)) {
+ long x = PyInt_AsLong(*pw);
+ *pw = PyFloat_FromDouble((double)x);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyLong_Check(*pw)) {
+ double x = PyLong_AsDouble(*pw);
+ if (x == -1.0 && PyErr_Occurred())
+ return -1;
+ *pw = PyFloat_FromDouble(x);
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyFloat_Check(*pw)) {
+ Py_INCREF(*pv);
+ Py_INCREF(*pw);
+ return 0;
+ }
+ return 1; /* Can't do it */
+}
+
+static PyObject *
+float_is_integer(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ PyObject *o;
+
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ if (!Py_IS_FINITE(x))
+ Py_RETURN_FALSE;
+ errno = 0;
+ PyFPE_START_PROTECT("is_integer", return NULL)
+ o = (floor(x) == x) ? Py_True : Py_False;
+ PyFPE_END_PROTECT(x)
+ if (errno != 0) {
+ PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
+ PyExc_ValueError);
+ return NULL;
+ }
+ Py_INCREF(o);
+ return o;
+}
+
+#if 0
+static PyObject *
+float_is_inf(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_INFINITY(x));
+}
+
+static PyObject *
+float_is_nan(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_NAN(x));
+}
+
+static PyObject *
+float_is_finite(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)Py_IS_FINITE(x));
+}
+#endif
+
+static PyObject *
+float_trunc(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ double wholepart; /* integral portion of x, rounded toward 0 */
+
+ (void)modf(x, &wholepart);
+ /* Try to get out cheap if this fits in a Python int. The attempt
+ * to cast to long must be protected, as C doesn't define what
+ * happens if the double is too big to fit in a long. Some rare
+ * systems raise an exception then (RISCOS was mentioned as one,
+ * and someone using a non-default option on Sun also bumped into
+ * that). Note that checking for <= LONG_MAX is unsafe: if a long
+ * has more bits of precision than a double, casting LONG_MAX to
+ * double may yield an approximation, and if that's rounded up,
+ * then, e.g., wholepart=LONG_MAX+1 would yield true from the C
+ * expression wholepart<=LONG_MAX, despite that wholepart is
+ * actually greater than LONG_MAX. However, assuming a two's complement
+ * machine with no trap representation, LONG_MIN will be a power of 2 (and
+ * hence exactly representable as a double), and LONG_MAX = -1-LONG_MIN, so
+ * the comparisons with (double)LONG_MIN below should be safe.
+ */
+ if ((double)LONG_MIN <= wholepart && wholepart < -(double)LONG_MIN) {
+ const long aslong = (long)wholepart;
+ return PyInt_FromLong(aslong);
+ }
+ return PyLong_FromDouble(wholepart);
+}
+
+static PyObject *
+float_long(PyObject *v)
+{
+ double x = PyFloat_AsDouble(v);
+ return PyLong_FromDouble(x);
+}
+
+/* _Py_double_round: rounds a finite nonzero double to the closest multiple of
+ 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
+ ndigits <= 323). Returns a Python float, or sets a Python error and
+ returns NULL on failure (OverflowError and memory errors are possible). */
+
+#ifndef PY_NO_SHORT_FLOAT_REPR
+/* version of _Py_double_round that uses the correctly-rounded string<->double
+ conversions from Python/dtoa.c */
+
+/* FIVE_POW_LIMIT is the largest k such that 5**k is exactly representable as
+ a double. Since we're using the code in Python/dtoa.c, it should be safe
+ to assume that C doubles are IEEE 754 binary64 format. To be on the safe
+ side, we check this. */
+#if DBL_MANT_DIG == 53
+#define FIVE_POW_LIMIT 22
+#else
+#error "C doubles do not appear to be IEEE 754 binary64 format"
+#endif
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+
+ double rounded, m;
+ Py_ssize_t buflen, mybuflen=100;
+ char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
+ int decpt, sign, val, halfway_case;
+ PyObject *result = NULL;
+ _Py_SET_53BIT_PRECISION_HEADER;
+
+ /* Easy path for the common case ndigits == 0. */
+ if (ndigits == 0) {
+ rounded = round(x);
+ if (fabs(rounded - x) == 0.5)
+ /* halfway between two integers; use round-away-from-zero */
+ rounded = x + (x > 0.0 ? 0.5 : -0.5);
+ return PyFloat_FromDouble(rounded);
+ }
+
+ /* The basic idea is very simple: convert and round the double to a
+ decimal string using _Py_dg_dtoa, then convert that decimal string
+ back to a double with _Py_dg_strtod. There's one minor difficulty:
+ Python 2.x expects round to do round-half-away-from-zero, while
+ _Py_dg_dtoa does round-half-to-even. So we need some way to detect
+ and correct the halfway cases.
+
+ Detection: a halfway value has the form k * 0.5 * 10**-ndigits for
+ some odd integer k. Or in other words, a rational number x is
+ exactly halfway between two multiples of 10**-ndigits if its
+ 2-valuation is exactly -ndigits-1 and its 5-valuation is at least
+ -ndigits. For ndigits >= 0 the latter condition is automatically
+ satisfied for a binary float x, since any such float has
+ nonnegative 5-valuation. For 0 > ndigits >= -22, x needs to be an
+ integral multiple of 5**-ndigits; we can check this using fmod.
+ For -22 > ndigits, there are no halfway cases: 5**23 takes 54 bits
+ to represent exactly, so any odd multiple of 0.5 * 10**n for n >=
+ 23 takes at least 54 bits of precision to represent exactly.
+
+ Correction: a simple strategy for dealing with halfway cases is to
+ (for the halfway cases only) call _Py_dg_dtoa with an argument of
+ ndigits+1 instead of ndigits (thus doing an exact conversion to
+ decimal), round the resulting string manually, and then convert
+ back using _Py_dg_strtod.
+ */
+
+ /* nans, infinities and zeros should have already been dealt
+ with by the caller (in this case, builtin_round) */
+ assert(Py_IS_FINITE(x) && x != 0.0);
+
+ /* find 2-valuation val of x */
+ m = frexp(x, &val);
+ while (m != floor(m)) {
+ m *= 2.0;
+ val--;
+ }
+
+ /* determine whether this is a halfway case */
+ if (val == -ndigits-1) {
+ if (ndigits >= 0)
+ halfway_case = 1;
+ else if (ndigits >= -FIVE_POW_LIMIT) {
+ double five_pow = 1.0;
+ int i;
+ for (i=0; i < -ndigits; i++)
+ five_pow *= 5.0;
+ halfway_case = fmod(x, five_pow) == 0.0;
+ }
+ else
+ halfway_case = 0;
+ }
+ else
+ halfway_case = 0;
+
+ /* round to a decimal string; use an extra place for halfway case */
+ _Py_SET_53BIT_PRECISION_START;
+ buf = _Py_dg_dtoa(x, 3, ndigits+halfway_case, &decpt, &sign, &buf_end);
+ _Py_SET_53BIT_PRECISION_END;
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ buflen = buf_end - buf;
+
+ /* in halfway case, do the round-half-away-from-zero manually */
+ if (halfway_case) {
+ int i, carry;
+ /* sanity check: _Py_dg_dtoa should not have stripped
+ any zeros from the result: there should be exactly
+ ndigits+1 places following the decimal point, and
+ the last digit in the buffer should be a '5'.*/
+ assert(buflen - decpt == ndigits+1);
+ assert(buf[buflen-1] == '5');
+
+ /* increment and shift right at the same time. */
+ decpt += 1;
+ carry = 1;
+ for (i=buflen-1; i-- > 0;) {
+ carry += buf[i] - '0';
+ buf[i+1] = carry % 10 + '0';
+ carry /= 10;
+ }
+ buf[0] = carry + '0';
+ }
+
+ /* Get new buffer if shortbuf is too small. Space needed <= buf_end -
+ buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */
+ if (buflen + 8 > mybuflen) {
+ mybuflen = buflen+8;
+ mybuf = (char *)PyMem_Malloc(mybuflen);
+ if (mybuf == NULL) {
+ PyErr_NoMemory();
+ goto exit;
+ }
+ }
+ /* copy buf to mybuf, adding exponent, sign and leading 0 */
+ PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),
+ buf, decpt - (int)buflen);
+
+ /* and convert the resulting string back to a double */
+ errno = 0;
+ _Py_SET_53BIT_PRECISION_START;
+ rounded = _Py_dg_strtod(mybuf, NULL);
+ _Py_SET_53BIT_PRECISION_END;
+ if (errno == ERANGE && fabs(rounded) >= 1.)
+ PyErr_SetString(PyExc_OverflowError,
+ "rounded value too large to represent");
+ else
+ result = PyFloat_FromDouble(rounded);
+
+ /* done computing value; now clean up */
+ if (mybuf != shortbuf)
+ PyMem_Free(mybuf);
+ exit:
+ _Py_dg_freedtoa(buf);
+ return result;
+}
+
+#undef FIVE_POW_LIMIT
+
+#else /* PY_NO_SHORT_FLOAT_REPR */
+
+/* fallback version, to be used when correctly rounded binary<->decimal
+ conversions aren't available */
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+ double pow1, pow2, y, z;
+ if (ndigits >= 0) {
+ if (ndigits > 22) {
+ /* pow1 and pow2 are each safe from overflow, but
+ pow1*pow2 ~= pow(10.0, ndigits) might overflow */
+ pow1 = pow(10.0, (double)(ndigits-22));
+ pow2 = 1e22;
+ }
+ else {
+ pow1 = pow(10.0, (double)ndigits);
+ pow2 = 1.0;
+ }
+ y = (x*pow1)*pow2;
+ /* if y overflows, then rounded value is exactly x */
+ if (!Py_IS_FINITE(y))
+ return PyFloat_FromDouble(x);
+ }
+ else {
+ pow1 = pow(10.0, (double)-ndigits);
+ pow2 = 1.0; /* unused; silences a gcc compiler warning */
+ y = x / pow1;
+ }
+
+ z = round(y);
+ if (fabs(y-z) == 0.5)
+ /* halfway between two integers; use round-away-from-zero */
+ z = y + copysign(0.5, y);
+
+ if (ndigits >= 0)
+ z = (z / pow2) / pow1;
+ else
+ z *= pow1;
+
+ /* if computation resulted in overflow, raise OverflowError */
+ if (!Py_IS_FINITE(z)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "overflow occurred during round");
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(z);
+}
+
+#endif /* PY_NO_SHORT_FLOAT_REPR */
+
+static PyObject *
+float_float(PyObject *v)
+{
+ if (PyFloat_CheckExact(v))
+ Py_INCREF(v);
+ else
+ v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
+ return v;
+}
+
+/* turn ASCII hex characters into integer values and vice versa */
+
+static char
+char_from_hex(int x)
+{
+ assert(0 <= x && x < 16);
+ return "0123456789abcdef"[x];
+}
+
+static int
+hex_from_char(char c) {
+ int x;
+ switch(c) {
+ case '0':
+ x = 0;
+ break;
+ case '1':
+ x = 1;
+ break;
+ case '2':
+ x = 2;
+ break;
+ case '3':
+ x = 3;
+ break;
+ case '4':
+ x = 4;
+ break;
+ case '5':
+ x = 5;
+ break;
+ case '6':
+ x = 6;
+ break;
+ case '7':
+ x = 7;
+ break;
+ case '8':
+ x = 8;
+ break;
+ case '9':
+ x = 9;
+ break;
+ case 'a':
+ case 'A':
+ x = 10;
+ break;
+ case 'b':
+ case 'B':
+ x = 11;
+ break;
+ case 'c':
+ case 'C':
+ x = 12;
+ break;
+ case 'd':
+ case 'D':
+ x = 13;
+ break;
+ case 'e':
+ case 'E':
+ x = 14;
+ break;
+ case 'f':
+ case 'F':
+ x = 15;
+ break;
+ default:
+ x = -1;
+ break;
+ }
+ return x;
+}
+
+/* convert a float to a hexadecimal string */
+
+/* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer
+ of the form 4k+1. */
+#define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4
+
+static PyObject *
+float_hex(PyObject *v)
+{
+ double x, m;
+ int e, shift, i, si, esign;
+ /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
+ trailing NUL byte. */
+ char s[(TOHEX_NBITS-1)/4+3];
+
+ CONVERT_TO_DOUBLE(v, x);
+
+ if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
+ return float_str((PyFloatObject *)v);
+
+ if (x == 0.0) {
+ if (copysign(1.0, x) == -1.0)
+ return PyString_FromString("-0x0.0p+0");
+ else
+ return PyString_FromString("0x0.0p+0");
+ }
+
+ m = frexp(fabs(x), &e);
+ shift = 1 - MAX(DBL_MIN_EXP - e, 0);
+ m = ldexp(m, shift);
+ e -= shift;
+
+ si = 0;
+ s[si] = char_from_hex((int)m);
+ si++;
+ m -= (int)m;
+ s[si] = '.';
+ si++;
+ for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
+ m *= 16.0;
+ s[si] = char_from_hex((int)m);
+ si++;
+ m -= (int)m;
+ }
+ s[si] = '\0';
+
+ if (e < 0) {
+ esign = (int)'-';
+ e = -e;
+ }
+ else
+ esign = (int)'+';
+
+ if (x < 0.0)
+ return PyString_FromFormat("-0x%sp%c%d", s, esign, e);
+ else
+ return PyString_FromFormat("0x%sp%c%d", s, esign, e);
+}
+
+PyDoc_STRVAR(float_hex_doc,
+"float.hex() -> string\n\
+\n\
+Return a hexadecimal representation of a floating-point number.\n\
+>>> (-0.1).hex()\n\
+'-0x1.999999999999ap-4'\n\
+>>> 3.14159.hex()\n\
+'0x1.921f9f01b866ep+1'");
+
+/* Case-insensitive locale-independent string match used for nan and inf
+ detection. t should be lower-case and null-terminated. Return a nonzero
+ result if the first strlen(t) characters of s match t and 0 otherwise. */
+
+static int
+case_insensitive_match(const char *s, const char *t)
+{
+ while(*t && Py_TOLOWER(*s) == *t) {
+ s++;
+ t++;
+ }
+ return *t ? 0 : 1;
+}
+
+/* Convert a hexadecimal string to a float. */
+
+static PyObject *
+float_fromhex(PyObject *cls, PyObject *arg)
+{
+ PyObject *result_as_float, *result;
+ double x;
+ long exp, top_exp, lsb, key_digit;
+ char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end;
+ int half_eps, digit, round_up, sign=1;
+ Py_ssize_t length, ndigits, fdigits, i;
+
+ /*
+ * For the sake of simplicity and correctness, we impose an artificial
+ * limit on ndigits, the total number of hex digits in the coefficient
+ * The limit is chosen to ensure that, writing exp for the exponent,
+ *
+ * (1) if exp > LONG_MAX/2 then the value of the hex string is
+ * guaranteed to overflow (provided it's nonzero)
+ *
+ * (2) if exp < LONG_MIN/2 then the value of the hex string is
+ * guaranteed to underflow to 0.
+ *
+ * (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of
+ * overflow in the calculation of exp and top_exp below.
+ *
+ * More specifically, ndigits is assumed to satisfy the following
+ * inequalities:
+ *
+ * 4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2
+ * 4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP
+ *
+ * If either of these inequalities is not satisfied, a ValueError is
+ * raised. Otherwise, write x for the value of the hex string, and
+ * assume x is nonzero. Then
+ *
+ * 2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits).
+ *
+ * Now if exp > LONG_MAX/2 then:
+ *
+ * exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP)
+ * = DBL_MAX_EXP
+ *
+ * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C
+ * double, so overflows. If exp < LONG_MIN/2, then
+ *
+ * exp + 4*ndigits <= LONG_MIN/2 - 1 + (
+ * DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2)
+ * = DBL_MIN_EXP - DBL_MANT_DIG - 1
+ *
+ * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0
+ * when converted to a C double.
+ *
+ * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both
+ * exp+4*ndigits and exp-4*ndigits are within the range of a long.
+ */
+
+ if (PyString_AsStringAndSize(arg, &s, &length))
+ return NULL;
+ s_end = s + length;
+
+ /********************
+ * Parse the string *
+ ********************/
+
+ /* leading whitespace and optional sign */
+ while (Py_ISSPACE(*s))
+ s++;
+ if (*s == '-') {
+ s++;
+ sign = -1;
+ }
+ else if (*s == '+')
+ s++;
+
+ /* infinities and nans */
+ if (*s == 'i' || *s == 'I') {
+ if (!case_insensitive_match(s+1, "nf"))
+ goto parse_error;
+ s += 3;
+ x = Py_HUGE_VAL;
+ if (case_insensitive_match(s, "inity"))
+ s += 5;
+ goto finished;
+ }
+ if (*s == 'n' || *s == 'N') {
+ if (!case_insensitive_match(s+1, "an"))
+ goto parse_error;
+ s += 3;
+ x = Py_NAN;
+ goto finished;
+ }
+
+ /* [0x] */
+ s_store = s;
+ if (*s == '0') {
+ s++;
+ if (*s == 'x' || *s == 'X')
+ s++;
+ else
+ s = s_store;
+ }
+
+ /* coefficient: <integer> [. <fraction>] */
+ coeff_start = s;
+ while (hex_from_char(*s) >= 0)
+ s++;
+ s_store = s;
+ if (*s == '.') {
+ s++;
+ while (hex_from_char(*s) >= 0)
+ s++;
+ coeff_end = s-1;
+ }
+ else
+ coeff_end = s;
+
+ /* ndigits = total # of hex digits; fdigits = # after point */
+ ndigits = coeff_end - coeff_start;
+ fdigits = coeff_end - s_store;
+ if (ndigits == 0)
+ goto parse_error;
+ if (ndigits > MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2,
+ LONG_MAX/2 + 1 - DBL_MAX_EXP)/4)
+ goto insane_length_error;
+
+ /* [p <exponent>] */
+ if (*s == 'p' || *s == 'P') {
+ s++;
+ exp_start = s;
+ if (*s == '-' || *s == '+')
+ s++;
+ if (!('0' <= *s && *s <= '9'))
+ goto parse_error;
+ s++;
+ while ('0' <= *s && *s <= '9')
+ s++;
+ exp = strtol(exp_start, NULL, 10);
+ }
+ else
+ exp = 0;
+
+/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */
+#define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ? \
+ coeff_end-(j) : \
+ coeff_end-1-(j)))
+
+ /*******************************************
+ * Compute rounded value of the hex string *
+ *******************************************/
+
+ /* Discard leading zeros, and catch extreme overflow and underflow */
+ while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0)
+ ndigits--;
+ if (ndigits == 0 || exp < LONG_MIN/2) {
+ x = 0.0;
+ goto finished;
+ }
+ if (exp > LONG_MAX/2)
+ goto overflow_error;
+
+ /* Adjust exponent for fractional part. */
+ exp = exp - 4*((long)fdigits);
+
+ /* top_exp = 1 more than exponent of most sig. bit of coefficient */
+ top_exp = exp + 4*((long)ndigits - 1);
+ for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2)
+ top_exp++;
+
+ /* catch almost all nonextreme cases of overflow and underflow here */
+ if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) {
+ x = 0.0;
+ goto finished;
+ }
+ if (top_exp > DBL_MAX_EXP)
+ goto overflow_error;
+
+ /* lsb = exponent of least significant bit of the *rounded* value.
+ This is top_exp - DBL_MANT_DIG unless result is subnormal. */
+ lsb = MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG;
+
+ x = 0.0;
+ if (exp >= lsb) {
+ /* no rounding required */
+ for (i = ndigits-1; i >= 0; i--)
+ x = 16.0*x + HEX_DIGIT(i);
+ x = ldexp(x, (int)(exp));
+ goto finished;
+ }
+ /* rounding required. key_digit is the index of the hex digit
+ containing the first bit to be rounded away. */
+ half_eps = 1 << (int)((lsb - exp - 1) % 4);
+ key_digit = (lsb - exp - 1) / 4;
+ for (i = ndigits-1; i > key_digit; i--)
+ x = 16.0*x + HEX_DIGIT(i);
+ digit = HEX_DIGIT(key_digit);
+ x = 16.0*x + (double)(digit & (16-2*half_eps));
+
+ /* round-half-even: round up if bit lsb-1 is 1 and at least one of
+ bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */
+ if ((digit & half_eps) != 0) {
+ round_up = 0;
+ if ((digit & (3*half_eps-1)) != 0 ||
+ (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0))
+ round_up = 1;
+ else
+ for (i = key_digit-1; i >= 0; i--)
+ if (HEX_DIGIT(i) != 0) {
+ round_up = 1;
+ break;
+ }
+ if (round_up == 1) {
+ x += 2*half_eps;
+ if (top_exp == DBL_MAX_EXP &&
+ x == ldexp((double)(2*half_eps), DBL_MANT_DIG))
+ /* overflow corner case: pre-rounded value <
+ 2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */
+ goto overflow_error;
+ }
+ }
+ x = ldexp(x, (int)(exp+4*key_digit));
+
+ finished:
+ /* optional trailing whitespace leading to the end of the string */
+ while (Py_ISSPACE(*s))
+ s++;
+ if (s != s_end)
+ goto parse_error;
+ result_as_float = Py_BuildValue("(d)", sign * x);
+ if (result_as_float == NULL)
+ return NULL;
+ result = PyObject_CallObject(cls, result_as_float);
+ Py_DECREF(result_as_float);
+ return result;
+
+ overflow_error:
+ PyErr_SetString(PyExc_OverflowError,
+ "hexadecimal value too large to represent as a float");
+ return NULL;
+
+ parse_error:
+ PyErr_SetString(PyExc_ValueError,
+ "invalid hexadecimal floating-point string");
+ return NULL;
+
+ insane_length_error:
+ PyErr_SetString(PyExc_ValueError,
+ "hexadecimal string too long to convert");
+ return NULL;
+}
+
+PyDoc_STRVAR(float_fromhex_doc,
+"float.fromhex(string) -> float\n\
+\n\
+Create a floating-point number from a hexadecimal string.\n\
+>>> float.fromhex('0x1.ffffp10')\n\
+2047.984375\n\
+>>> float.fromhex('-0x1p-1074')\n\
+-4.9406564584124654e-324");
+
+
+static PyObject *
+float_as_integer_ratio(PyObject *v, PyObject *unused)
+{
+ double self;
+ double float_part;
+ int exponent;
+ int i;
+
+ PyObject *prev;
+ PyObject *py_exponent = NULL;
+ PyObject *numerator = NULL;
+ PyObject *denominator = NULL;
+ PyObject *result_pair = NULL;
+ PyNumberMethods *long_methods = PyLong_Type.tp_as_number;
+
+#define INPLACE_UPDATE(obj, call) \
+ prev = obj; \
+ obj = call; \
+ Py_DECREF(prev); \
+
+ CONVERT_TO_DOUBLE(v, self);
+
+ if (Py_IS_INFINITY(self)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Cannot pass infinity to float.as_integer_ratio.");
+ return NULL;
+ }
+#ifdef Py_NAN
+ if (Py_IS_NAN(self)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot pass NaN to float.as_integer_ratio.");
+ return NULL;
+ }
+#endif
+
+ PyFPE_START_PROTECT("as_integer_ratio", goto error);
+ float_part = frexp(self, &exponent); /* self == float_part * 2**exponent exactly */
+ PyFPE_END_PROTECT(float_part);
+
+ for (i=0; i<300 && float_part != floor(float_part) ; i++) {
+ float_part *= 2.0;
+ exponent--;
+ }
+ /* self == float_part * 2**exponent exactly and float_part is integral.
+ If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part
+ to be truncated by PyLong_FromDouble(). */
+
+ numerator = PyLong_FromDouble(float_part);
+ if (numerator == NULL) goto error;
+
+ /* fold in 2**exponent */
+ denominator = PyLong_FromLong(1);
+ py_exponent = PyLong_FromLong(labs((long)exponent));
+ if (py_exponent == NULL) goto error;
+ INPLACE_UPDATE(py_exponent,
+ long_methods->nb_lshift(denominator, py_exponent));
+ if (py_exponent == NULL) goto error;
+ if (exponent > 0) {
+ INPLACE_UPDATE(numerator,
+ long_methods->nb_multiply(numerator, py_exponent));
+ if (numerator == NULL) goto error;
+ }
+ else {
+ Py_DECREF(denominator);
+ denominator = py_exponent;
+ py_exponent = NULL;
+ }
+
+ /* Returns ints instead of longs where possible */
+ INPLACE_UPDATE(numerator, PyNumber_Int(numerator));
+ if (numerator == NULL) goto error;
+ INPLACE_UPDATE(denominator, PyNumber_Int(denominator));
+ if (denominator == NULL) goto error;
+
+ result_pair = PyTuple_Pack(2, numerator, denominator);
+
+#undef INPLACE_UPDATE
+error:
+ Py_XDECREF(py_exponent);
+ Py_XDECREF(denominator);
+ Py_XDECREF(numerator);
+ return result_pair;
+}
+
+PyDoc_STRVAR(float_as_integer_ratio_doc,
+"float.as_integer_ratio() -> (int, int)\n"
+"\n"
+"Return a pair of integers, whose ratio is exactly equal to the original\n"
+"float and with a positive denominator.\n"
+"Raise OverflowError on infinities and a ValueError on NaNs.\n"
+"\n"
+">>> (10.0).as_integer_ratio()\n"
+"(10, 1)\n"
+">>> (0.0).as_integer_ratio()\n"
+"(0, 1)\n"
+">>> (-.25).as_integer_ratio()\n"
+"(-1, 4)");
+
+
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *x = Py_False; /* Integer zero */
+ static char *kwlist[] = {"x", 0};
+
+ if (type != &PyFloat_Type)
+ return float_subtype_new(type, args, kwds); /* Wimp out */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
+ return NULL;
+ /* If it's a string, but not a string subclass, use
+ PyFloat_FromString. */
+ if (PyString_CheckExact(x))
+ return PyFloat_FromString(x, NULL);
+ return PyNumber_Float(x);
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of float:
+ first create a regular float from whatever arguments we got,
+ then allocate a subtype instance and initialize its ob_fval
+ from the regular float. The regular float is then thrown away.
+*/
+static PyObject *
+float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *tmp, *newobj;
+
+ assert(PyType_IsSubtype(type, &PyFloat_Type));
+ tmp = float_new(&PyFloat_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyFloat_CheckExact(tmp));
+ newobj = type->tp_alloc(type, 0);
+ if (newobj == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
+ Py_DECREF(tmp);
+ return newobj;
+}
+
+static PyObject *
+float_getnewargs(PyFloatObject *v)
+{
+ return Py_BuildValue("(d)", v->ob_fval);
+}
+
+/* this is for the benefit of the pack/unpack routines below */
+
+typedef enum {
+ unknown_format, ieee_big_endian_format, ieee_little_endian_format
+} float_format_type;
+
+static float_format_type double_format, float_format;
+static float_format_type detected_double_format, detected_float_format;
+
+static PyObject *
+float_getformat(PyTypeObject *v, PyObject* arg)
+{
+ char* s;
+ float_format_type r;
+
+ if (!PyString_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "__getformat__() argument must be string, not %.500s",
+ Py_TYPE(arg)->tp_name);
+ return NULL;
+ }
+ s = PyString_AS_STRING(arg);
+ if (strcmp(s, "double") == 0) {
+ r = double_format;
+ }
+ else if (strcmp(s, "float") == 0) {
+ r = float_format;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "__getformat__() argument 1 must be "
+ "'double' or 'float'");
+ return NULL;
+ }
+
+ switch (r) {
+ case unknown_format:
+ return PyString_FromString("unknown");
+ case ieee_little_endian_format:
+ return PyString_FromString("IEEE, little-endian");
+ case ieee_big_endian_format:
+ return PyString_FromString("IEEE, big-endian");
+ default:
+ Py_FatalError("insane float_format or double_format");
+ return NULL;
+ }
+}
+
+PyDoc_STRVAR(float_getformat_doc,
+"float.__getformat__(typestr) -> string\n"
+"\n"
+"You probably don't want to use this function. It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'. This function returns whichever of\n"
+"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
+"format of floating point numbers used by the C type named by typestr.");
+
+static PyObject *
+float_setformat(PyTypeObject *v, PyObject* args)
+{
+ char* typestr;
+ char* format;
+ float_format_type f;
+ float_format_type detected;
+ float_format_type *p;
+
+ if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
+ return NULL;
+
+ if (strcmp(typestr, "double") == 0) {
+ p = &double_format;
+ detected = detected_double_format;
+ }
+ else if (strcmp(typestr, "float") == 0) {
+ p = &float_format;
+ detected = detected_float_format;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "__setformat__() argument 1 must "
+ "be 'double' or 'float'");
+ return NULL;
+ }
+
+ if (strcmp(format, "unknown") == 0) {
+ f = unknown_format;
+ }
+ else if (strcmp(format, "IEEE, little-endian") == 0) {
+ f = ieee_little_endian_format;
+ }
+ else if (strcmp(format, "IEEE, big-endian") == 0) {
+ f = ieee_big_endian_format;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "__setformat__() argument 2 must be "
+ "'unknown', 'IEEE, little-endian' or "
+ "'IEEE, big-endian'");
+ return NULL;
+
+ }
+
+ if (f != unknown_format && f != detected) {
+ PyErr_Format(PyExc_ValueError,
+ "can only set %s format to 'unknown' or the "
+ "detected platform value", typestr);
+ return NULL;
+ }
+
+ *p = f;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(float_setformat_doc,
+"float.__setformat__(typestr, fmt) -> None\n"
+"\n"
+"You probably don't want to use this function. It exists mainly to be\n"
+"used in Python's test suite.\n"
+"\n"
+"typestr must be 'double' or 'float'. fmt must be one of 'unknown',\n"
+"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
+"one of the latter two if it appears to match the underlying C reality.\n"
+"\n"
+"Override the automatic determination of C-level floating point type.\n"
+"This affects how floats are converted to and from binary strings.");
+
+static PyObject *
+float_getzero(PyObject *v, void *closure)
+{
+ return PyFloat_FromDouble(0.0);
+}
+
+static PyObject *
+float__format__(PyObject *self, PyObject *args)
+{
+ PyObject *format_spec;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+ if (PyBytes_Check(format_spec))
+ return _PyFloat_FormatAdvanced(self,
+ PyBytes_AS_STRING(format_spec),
+ PyBytes_GET_SIZE(format_spec));
+ if (PyUnicode_Check(format_spec)) {
+ /* Convert format_spec to a str */
+ PyObject *result;
+ PyObject *str_spec = PyObject_Str(format_spec);
+
+ if (str_spec == NULL)
+ return NULL;
+
+ result = _PyFloat_FormatAdvanced(self,
+ PyBytes_AS_STRING(str_spec),
+ PyBytes_GET_SIZE(str_spec));
+
+ Py_DECREF(str_spec);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+ return NULL;
+}
+
+PyDoc_STRVAR(float__format__doc,
+"float.__format__(format_spec) -> string\n"
+"\n"
+"Formats the float according to format_spec.");
+
+
+static PyMethodDef float_methods[] = {
+ {"conjugate", (PyCFunction)float_float, METH_NOARGS,
+ "Return self, the complex conjugate of any float."},
+ {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS,
+ "Return the Integral closest to x between 0 and x."},
+ {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,
+ float_as_integer_ratio_doc},
+ {"fromhex", (PyCFunction)float_fromhex,
+ METH_O|METH_CLASS, float_fromhex_doc},
+ {"hex", (PyCFunction)float_hex,
+ METH_NOARGS, float_hex_doc},
+ {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS,
+ "Return True if the float is an integer."},
+#if 0
+ {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS,
+ "Return True if the float is positive or negative infinite."},
+ {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS,
+ "Return True if the float is finite, neither infinite nor NaN."},
+ {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS,
+ "Return True if the float is not a number (NaN)."},
+#endif
+ {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS},
+ {"__getformat__", (PyCFunction)float_getformat,
+ METH_O|METH_CLASS, float_getformat_doc},
+ {"__setformat__", (PyCFunction)float_setformat,
+ METH_VARARGS|METH_CLASS, float_setformat_doc},
+ {"__format__", (PyCFunction)float__format__,
+ METH_VARARGS, float__format__doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyGetSetDef float_getset[] = {
+ {"real",
+ (getter)float_float, (setter)NULL,
+ "the real part of a complex number",
+ NULL},
+ {"imag",
+ (getter)float_getzero, (setter)NULL,
+ "the imaginary part of a complex number",
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(float_doc,
+"float(x) -> floating point number\n\
+\n\
+Convert a string or number to a floating point number, if possible.");
+
+
+static PyNumberMethods float_as_number = {
+ float_add, /*nb_add*/
+ float_sub, /*nb_subtract*/
+ float_mul, /*nb_multiply*/
+ float_classic_div, /*nb_divide*/
+ float_rem, /*nb_remainder*/
+ float_divmod, /*nb_divmod*/
+ float_pow, /*nb_power*/
+ (unaryfunc)float_neg, /*nb_negative*/
+ (unaryfunc)float_float, /*nb_positive*/
+ (unaryfunc)float_abs, /*nb_absolute*/
+ (inquiry)float_nonzero, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ float_coerce, /*nb_coerce*/
+ float_trunc, /*nb_int*/
+ float_long, /*nb_long*/
+ float_float, /*nb_float*/
+ 0, /* nb_oct */
+ 0, /* nb_hex */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ float_floor_div, /* nb_floor_divide */
+ float_div, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+};
+
+PyTypeObject PyFloat_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "float",
+ sizeof(PyFloatObject),
+ 0,
+ (destructor)float_dealloc, /* tp_dealloc */
+ (printfunc)float_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)float_repr, /* tp_repr */
+ &float_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)float_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)float_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ float_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ float_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ float_methods, /* tp_methods */
+ 0, /* tp_members */
+ float_getset, /* 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 */
+ float_new, /* tp_new */
+};
+
+void
+_PyFloat_Init(void)
+{
+ /* We attempt to determine if this machine is using IEEE
+ floating point formats by peering at the bits of some
+ carefully chosen values. If it looks like we are on an
+ IEEE platform, the float packing/unpacking routines can
+ just copy bits, if not they resort to arithmetic & shifts
+ and masks. The shifts & masks approach works on all finite
+ values, but what happens to infinities, NaNs and signed
+ zeroes on packing is an accident, and attempting to unpack
+ a NaN or an infinity will raise an exception.
+
+ Note that if we're on some whacked-out platform which uses
+ IEEE formats but isn't strictly little-endian or big-
+ endian, we will fall back to the portable shifts & masks
+ method. */
+
+#if SIZEOF_DOUBLE == 8
+ {
+ double x = 9006104071832581.0;
+ if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
+ detected_double_format = ieee_big_endian_format;
+ else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
+ detected_double_format = ieee_little_endian_format;
+ else
+ detected_double_format = unknown_format;
+ }
+#else
+ detected_double_format = unknown_format;
+#endif
+
+#if SIZEOF_FLOAT == 4
+ {
+ float y = 16711938.0;
+ if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
+ detected_float_format = ieee_big_endian_format;
+ else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
+ detected_float_format = ieee_little_endian_format;
+ else
+ detected_float_format = unknown_format;
+ }
+#else
+ detected_float_format = unknown_format;
+#endif
+
+ double_format = detected_double_format;
+ float_format = detected_float_format;
+
+ /* Init float info */
+ if (FloatInfoType.tp_name == 0)
+ PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
+}
+
+int
+PyFloat_ClearFreeList(void)
+{
+ PyFloatObject *p;
+ PyFloatBlock *list, *next;
+ int i;
+ int u; /* remaining unfreed ints per block */
+ int freelist_size = 0;
+
+ list = block_list;
+ block_list = NULL;
+ free_list = NULL;
+ while (list != NULL) {
+ u = 0;
+ for (i = 0, p = &list->objects[0];
+ i < N_FLOATOBJECTS;
+ i++, p++) {
+ if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
+ u++;
+ }
+ next = list->next;
+ if (u) {
+ list->next = block_list;
+ block_list = list;
+ for (i = 0, p = &list->objects[0];
+ i < N_FLOATOBJECTS;
+ i++, p++) {
+ if (!PyFloat_CheckExact(p) ||
+ Py_REFCNT(p) == 0) {
+ Py_TYPE(p) = (struct _typeobject *)
+ free_list;
+ free_list = p;
+ }
+ }
+ }
+ else {
+ PyMem_FREE(list);
+ }
+ freelist_size += u;
+ list = next;
+ }
+ return freelist_size;
+}
+
+void
+PyFloat_Fini(void)
+{
+ PyFloatObject *p;
+ PyFloatBlock *list;
+ int i;
+ int u; /* total unfreed floats per block */
+
+ u = PyFloat_ClearFreeList();
+
+ if (!Py_VerboseFlag)
+ return;
+ fprintf(stderr, "# cleanup floats");
+ if (!u) {
+ fprintf(stderr, "\n");
+ }
+ else {
+ fprintf(stderr,
+ ": %d unfreed float%s\n",
+ u, u == 1 ? "" : "s");
+ }
+ if (Py_VerboseFlag > 1) {
+ list = block_list;
+ while (list != NULL) {
+ for (i = 0, p = &list->objects[0];
+ i < N_FLOATOBJECTS;
+ i++, p++) {
+ if (PyFloat_CheckExact(p) &&
+ Py_REFCNT(p) != 0) {
+ char *buf = PyOS_double_to_string(
+ PyFloat_AS_DOUBLE(p), 'r',
+ 0, 0, NULL);
+ if (buf) {
+ /* XXX(twouters) cast
+ refcount to long
+ until %zd is
+ universally
+ available
+ */
+ fprintf(stderr,
+ "# <float at %p, refcnt=%ld, val=%s>\n",
+ p, (long)Py_REFCNT(p), buf);
+ PyMem_Free(buf);
+ }
+ }
+ }
+ list = list->next;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * _PyFloat_{Pack,Unpack}{4,8}. See floatobject.h.
+ */
+int
+_PyFloat_Pack4(double x, unsigned char *p, int le)
+{
+ if (float_format == unknown_format) {
+ unsigned char sign;
+ int e;
+ double f;
+ unsigned int fbits;
+ int incr = 1;
+
+ if (le) {
+ p += 3;
+ incr = -1;
+ }
+
+ if (x < 0) {
+ sign = 1;
+ x = -x;
+ }
+ else
+ sign = 0;
+
+ f = frexp(x, &e);
+
+ /* Normalize f to be in the range [1.0, 2.0) */
+ if (0.5 <= f && f < 1.0) {
+ f *= 2.0;
+ e--;
+ }
+ else if (f == 0.0)
+ e = 0;
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "frexp() result out of range");
+ return -1;
+ }
+
+ if (e >= 128)
+ goto Overflow;
+ else if (e < -126) {
+ /* Gradual underflow */
+ f = ldexp(f, 126 + e);
+ e = 0;
+ }
+ else if (!(e == 0 && f == 0.0)) {
+ e += 127;
+ f -= 1.0; /* Get rid of leading 1 */
+ }
+
+ f *= 8388608.0; /* 2**23 */
+ fbits = (unsigned int)(f + 0.5); /* Round */
+ assert(fbits <= 8388608);
+ if (fbits >> 23) {
+ /* The carry propagated out of a string of 23 1 bits. */
+ fbits = 0;
+ ++e;
+ if (e >= 255)
+ goto Overflow;
+ }
+
+ /* First byte */
+ *p = (sign << 7) | (e >> 1);
+ p += incr;
+
+ /* Second byte */
+ *p = (char) (((e & 1) << 7) | (fbits >> 16));
+ p += incr;
+
+ /* Third byte */
+ *p = (fbits >> 8) & 0xFF;
+ p += incr;
+
+ /* Fourth byte */
+ *p = fbits & 0xFF;
+
+ /* Done */
+ return 0;
+
+ }
+ else {
+ float y = (float)x;
+ const char *s = (char*)&y;
+ int i, incr = 1;
+
+ if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
+ goto Overflow;
+
+ if ((float_format == ieee_little_endian_format && !le)
+ || (float_format == ieee_big_endian_format && le)) {
+ p += 3;
+ incr = -1;
+ }
+
+ for (i = 0; i < 4; i++) {
+ *p = *s++;
+ p += incr;
+ }
+ return 0;
+ }
+ Overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "float too large to pack with f format");
+ return -1;
+}
+
+int
+_PyFloat_Pack8(double x, unsigned char *p, int le)
+{
+ if (double_format == unknown_format) {
+ unsigned char sign;
+ int e;
+ double f;
+ unsigned int fhi, flo;
+ int incr = 1;
+
+ if (le) {
+ p += 7;
+ incr = -1;
+ }
+
+ if (x < 0) {
+ sign = 1;
+ x = -x;
+ }
+ else
+ sign = 0;
+
+ f = frexp(x, &e);
+
+ /* Normalize f to be in the range [1.0, 2.0) */
+ if (0.5 <= f && f < 1.0) {
+ f *= 2.0;
+ e--;
+ }
+ else if (f == 0.0)
+ e = 0;
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "frexp() result out of range");
+ return -1;
+ }
+
+ if (e >= 1024)
+ goto Overflow;
+ else if (e < -1022) {
+ /* Gradual underflow */
+ f = ldexp(f, 1022 + e);
+ e = 0;
+ }
+ else if (!(e == 0 && f == 0.0)) {
+ e += 1023;
+ f -= 1.0; /* Get rid of leading 1 */
+ }
+
+ /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
+ f *= 268435456.0; /* 2**28 */
+ fhi = (unsigned int)f; /* Truncate */
+ assert(fhi < 268435456);
+
+ f -= (double)fhi;
+ f *= 16777216.0; /* 2**24 */
+ flo = (unsigned int)(f + 0.5); /* Round */
+ assert(flo <= 16777216);
+ if (flo >> 24) {
+ /* The carry propagated out of a string of 24 1 bits. */
+ flo = 0;
+ ++fhi;
+ if (fhi >> 28) {
+ /* And it also progagated out of the next 28 bits. */
+ fhi = 0;
+ ++e;
+ if (e >= 2047)
+ goto Overflow;
+ }
+ }
+
+ /* First byte */
+ *p = (sign << 7) | (e >> 4);
+ p += incr;
+
+ /* Second byte */
+ *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
+ p += incr;
+
+ /* Third byte */
+ *p = (fhi >> 16) & 0xFF;
+ p += incr;
+
+ /* Fourth byte */
+ *p = (fhi >> 8) & 0xFF;
+ p += incr;
+
+ /* Fifth byte */
+ *p = fhi & 0xFF;
+ p += incr;
+
+ /* Sixth byte */
+ *p = (flo >> 16) & 0xFF;
+ p += incr;
+
+ /* Seventh byte */
+ *p = (flo >> 8) & 0xFF;
+ p += incr;
+
+ /* Eighth byte */
+ *p = flo & 0xFF;
+ /* p += incr; Unneeded (for now) */
+
+ /* Done */
+ return 0;
+
+ Overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "float too large to pack with d format");
+ return -1;
+ }
+ else {
+ const char *s = (char*)&x;
+ int i, incr = 1;
+
+ if ((double_format == ieee_little_endian_format && !le)
+ || (double_format == ieee_big_endian_format && le)) {
+ p += 7;
+ incr = -1;
+ }
+
+ for (i = 0; i < 8; i++) {
+ *p = *s++;
+ p += incr;
+ }
+ return 0;
+ }
+}
+
+double
+_PyFloat_Unpack4(const unsigned char *p, int le)
+{
+ if (float_format == unknown_format) {
+ unsigned char sign;
+ int e;
+ unsigned int f;
+ double x;
+ int incr = 1;
+
+ if (le) {
+ p += 3;
+ incr = -1;
+ }
+
+ /* First byte */
+ sign = (*p >> 7) & 1;
+ e = (*p & 0x7F) << 1;
+ p += incr;
+
+ /* Second byte */
+ e |= (*p >> 7) & 1;
+ f = (*p & 0x7F) << 16;
+ p += incr;
+
+ if (e == 255) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "can't unpack IEEE 754 special value "
+ "on non-IEEE platform");
+ return -1;
+ }
+
+ /* Third byte */
+ f |= *p << 8;
+ p += incr;
+
+ /* Fourth byte */
+ f |= *p;
+
+ x = (double)f / 8388608.0;
+
+ /* XXX This sadly ignores Inf/NaN issues */
+ if (e == 0)
+ e = -126;
+ else {
+ x += 1.0;
+ e -= 127;
+ }
+ x = ldexp(x, e);
+
+ if (sign)
+ x = -x;
+
+ return x;
+ }
+ else {
+ float x;
+
+ if ((float_format == ieee_little_endian_format && !le)
+ || (float_format == ieee_big_endian_format && le)) {
+ char buf[4];
+ char *d = &buf[3];
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ *d-- = *p++;
+ }
+ memcpy(&x, buf, 4);
+ }
+ else {
+ memcpy(&x, p, 4);
+ }
+
+ return x;
+ }
+}
+
+double
+_PyFloat_Unpack8(const unsigned char *p, int le)
+{
+ if (double_format == unknown_format) {
+ unsigned char sign;
+ int e;
+ unsigned int fhi, flo;
+ double x;
+ int incr = 1;
+
+ if (le) {
+ p += 7;
+ incr = -1;
+ }
+
+ /* First byte */
+ sign = (*p >> 7) & 1;
+ e = (*p & 0x7F) << 4;
+
+ p += incr;
+
+ /* Second byte */
+ e |= (*p >> 4) & 0xF;
+ fhi = (*p & 0xF) << 24;
+ p += incr;
+
+ if (e == 2047) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "can't unpack IEEE 754 special value "
+ "on non-IEEE platform");
+ return -1.0;
+ }
+
+ /* Third byte */
+ fhi |= *p << 16;
+ p += incr;
+
+ /* Fourth byte */
+ fhi |= *p << 8;
+ p += incr;
+
+ /* Fifth byte */
+ fhi |= *p;
+ p += incr;
+
+ /* Sixth byte */
+ flo = *p << 16;
+ p += incr;
+
+ /* Seventh byte */
+ flo |= *p << 8;
+ p += incr;
+
+ /* Eighth byte */
+ flo |= *p;
+
+ x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
+ x /= 268435456.0; /* 2**28 */
+
+ if (e == 0)
+ e = -1022;
+ else {
+ x += 1.0;
+ e -= 1023;
+ }
+ x = ldexp(x, e);
+
+ if (sign)
+ x = -x;
+
+ return x;
+ }
+ else {
+ double x;
+
+ if ((double_format == ieee_little_endian_format && !le)
+ || (double_format == ieee_big_endian_format && le)) {
+ char buf[8];
+ char *d = &buf[7];
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ *d-- = *p++;
+ }
+ memcpy(&x, buf, 8);
+ }
+ else {
+ memcpy(&x, p, 8);
+ }
+
+ return x;
+ }
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/frameobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/frameobject.c
new file mode 100644
index 0000000000..2261b59af9
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/frameobject.c
@@ -0,0 +1,984 @@
+/* Frame object implementation */
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#undef MIN
+#undef MAX
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define OFF(x) offsetof(PyFrameObject, x)
+
+static PyMemberDef frame_memberlist[] = {
+ {"f_back", T_OBJECT, OFF(f_back), RO},
+ {"f_code", T_OBJECT, OFF(f_code), RO},
+ {"f_builtins", T_OBJECT, OFF(f_builtins),RO},
+ {"f_globals", T_OBJECT, OFF(f_globals), RO},
+ {"f_lasti", T_INT, OFF(f_lasti), RO},
+ {NULL} /* Sentinel */
+};
+
+#define WARN_GET_SET(NAME) \
+static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \
+ if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+ return NULL; \
+ if (f->NAME) { \
+ Py_INCREF(f->NAME); \
+ return f->NAME; \
+ } \
+ Py_RETURN_NONE; \
+} \
+static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \
+ if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+ return -1; \
+ if (f->NAME) { \
+ Py_CLEAR(f->NAME); \
+ } \
+ if (new == Py_None) \
+ new = NULL; \
+ Py_XINCREF(new); \
+ f->NAME = new; \
+ return 0; \
+}
+
+
+WARN_GET_SET(f_exc_traceback)
+WARN_GET_SET(f_exc_type)
+WARN_GET_SET(f_exc_value)
+
+
+static PyObject *
+frame_getlocals(PyFrameObject *f, void *closure)
+{
+ PyFrame_FastToLocals(f);
+ Py_INCREF(f->f_locals);
+ return f->f_locals;
+}
+
+int
+PyFrame_GetLineNumber(PyFrameObject *f)
+{
+ if (f->f_trace)
+ return f->f_lineno;
+ else
+ return PyCode_Addr2Line(f->f_code, f->f_lasti);
+}
+
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+ return PyInt_FromLong(PyFrame_GetLineNumber(f));
+}
+
+/* Setter for f_lineno - you can set f_lineno from within a trace function in
+ * order to jump to a given line of code, subject to some restrictions. Most
+ * lines are OK to jump to because they don't make any assumptions about the
+ * state of the stack (obvious because you could remove the line and the code
+ * would still work without any stack errors), but there are some constructs
+ * that limit jumping:
+ *
+ * o Lines with an 'except' statement on them can't be jumped to, because
+ * they expect an exception to be on the top of the stack.
+ * o Lines that live in a 'finally' block can't be jumped from or to, since
+ * the END_FINALLY expects to clean up the stack after the 'try' block.
+ * o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
+ * needs to be set up before their code runs, and for 'for' loops the
+ * iterator needs to be on the stack.
+ */
+static int
+frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
+{
+ int new_lineno = 0; /* The new value of f_lineno */
+ int new_lasti = 0; /* The new value of f_lasti */
+ int new_iblock = 0; /* The new value of f_iblock */
+ unsigned char *code = NULL; /* The bytecode for the frame... */
+ Py_ssize_t code_len = 0; /* ...and its length */
+ unsigned char *lnotab = NULL; /* Iterating over co_lnotab */
+ Py_ssize_t lnotab_len = 0; /* (ditto) */
+ int offset = 0; /* (ditto) */
+ int line = 0; /* (ditto) */
+ int addr = 0; /* (ditto) */
+ int min_addr = 0; /* Scanning the SETUPs and POPs */
+ int max_addr = 0; /* (ditto) */
+ int delta_iblock = 0; /* (ditto) */
+ int min_delta_iblock = 0; /* (ditto) */
+ int min_iblock = 0; /* (ditto) */
+ int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */
+ int new_lasti_setup_addr = 0; /* (ditto) */
+ int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */
+ int in_finally[CO_MAXBLOCKS]; /* (ditto) */
+ int blockstack_top = 0; /* (ditto) */
+ unsigned char setup_op = 0; /* (ditto) */
+
+ /* f_lineno must be an integer. */
+ if (!PyInt_Check(p_new_lineno)) {
+ PyErr_SetString(PyExc_ValueError,
+ "lineno must be an integer");
+ return -1;
+ }
+
+ /* You can only do this from within a trace function, not via
+ * _getframe or similar hackery. */
+ if (!f->f_trace)
+ {
+ PyErr_Format(PyExc_ValueError,
+ "f_lineno can only be set by a"
+ " line trace function");
+ return -1;
+ }
+
+ /* Fail if the line comes before the start of the code block. */
+ new_lineno = (int) PyInt_AsLong(p_new_lineno);
+ if (new_lineno < f->f_code->co_firstlineno) {
+ PyErr_Format(PyExc_ValueError,
+ "line %d comes before the current code block",
+ new_lineno);
+ return -1;
+ }
+ else if (new_lineno == f->f_code->co_firstlineno) {
+ new_lasti = 0;
+ new_lineno = f->f_code->co_firstlineno;
+ }
+ else {
+ /* Find the bytecode offset for the start of the given
+ * line, or the first code-owning line after it. */
+ char *tmp;
+ PyString_AsStringAndSize(f->f_code->co_lnotab,
+ &tmp, &lnotab_len);
+ lnotab = (unsigned char *) tmp;
+ addr = 0;
+ line = f->f_code->co_firstlineno;
+ new_lasti = -1;
+ for (offset = 0; offset < lnotab_len; offset += 2) {
+ addr += lnotab[offset];
+ line += lnotab[offset+1];
+ if (line >= new_lineno) {
+ new_lasti = addr;
+ new_lineno = line;
+ break;
+ }
+ }
+ }
+
+ /* If we didn't reach the requested line, return an error. */
+ if (new_lasti == -1) {
+ PyErr_Format(PyExc_ValueError,
+ "line %d comes after the current code block",
+ new_lineno);
+ return -1;
+ }
+
+ /* We're now ready to look at the bytecode. */
+ PyString_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);
+ min_addr = MIN(new_lasti, f->f_lasti);
+ max_addr = MAX(new_lasti, f->f_lasti);
+
+ /* You can't jump onto a line with an 'except' statement on it -
+ * they expect to have an exception on the top of the stack, which
+ * won't be true if you jump to them. They always start with code
+ * that either pops the exception using POP_TOP (plain 'except:'
+ * lines do this) or duplicates the exception on the stack using
+ * DUP_TOP (if there's an exception type specified). See compile.c,
+ * 'com_try_except' for the full details. There aren't any other
+ * cases (AFAIK) where a line's code can start with DUP_TOP or
+ * POP_TOP, but if any ever appear, they'll be subject to the same
+ * restriction (but with a different error message). */
+ if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump to 'except' line as there's no exception");
+ return -1;
+ }
+
+ /* You can't jump into or out of a 'finally' block because the 'try'
+ * block leaves something on the stack for the END_FINALLY to clean
+ * up. So we walk the bytecode, maintaining a simulated blockstack.
+ * When we reach the old or new address and it's in a 'finally' block
+ * we note the address of the corresponding SETUP_FINALLY. The jump
+ * is only legal if neither address is in a 'finally' block or
+ * they're both in the same one. 'blockstack' is a stack of the
+ * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
+ * whether we're in a 'finally' block at each blockstack level. */
+ f_lasti_setup_addr = -1;
+ new_lasti_setup_addr = -1;
+ memset(blockstack, '\0', sizeof(blockstack));
+ memset(in_finally, '\0', sizeof(in_finally));
+ blockstack_top = 0;
+ for (addr = 0; addr < code_len; addr++) {
+ unsigned char op = code[addr];
+ switch (op) {
+ case SETUP_LOOP:
+ case SETUP_EXCEPT:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ blockstack[blockstack_top++] = addr;
+ in_finally[blockstack_top-1] = 0;
+ break;
+
+ case POP_BLOCK:
+ assert(blockstack_top > 0);
+ setup_op = code[blockstack[blockstack_top-1]];
+ if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
+ in_finally[blockstack_top-1] = 1;
+ }
+ else {
+ blockstack_top--;
+ }
+ break;
+
+ case END_FINALLY:
+ /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
+ * in the bytecode but don't correspond to an actual
+ * 'finally' block. (If blockstack_top is 0, we must
+ * be seeing such an END_FINALLY.) */
+ if (blockstack_top > 0) {
+ setup_op = code[blockstack[blockstack_top-1]];
+ if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) {
+ blockstack_top--;
+ }
+ }
+ break;
+ }
+
+ /* For the addresses we're interested in, see whether they're
+ * within a 'finally' block and if so, remember the address
+ * of the SETUP_FINALLY. */
+ if (addr == new_lasti || addr == f->f_lasti) {
+ int i = 0;
+ int setup_addr = -1;
+ for (i = blockstack_top-1; i >= 0; i--) {
+ if (in_finally[i]) {
+ setup_addr = blockstack[i];
+ break;
+ }
+ }
+
+ if (setup_addr != -1) {
+ if (addr == new_lasti) {
+ new_lasti_setup_addr = setup_addr;
+ }
+
+ if (addr == f->f_lasti) {
+ f_lasti_setup_addr = setup_addr;
+ }
+ }
+ }
+
+ if (op >= HAVE_ARGUMENT) {
+ addr += 2;
+ }
+ }
+
+ /* Verify that the blockstack tracking code didn't get lost. */
+ assert(blockstack_top == 0);
+
+ /* After all that, are we jumping into / out of a 'finally' block? */
+ if (new_lasti_setup_addr != f_lasti_setup_addr) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump into or out of a 'finally' block");
+ return -1;
+ }
+
+
+ /* Police block-jumping (you can't jump into the middle of a block)
+ * and ensure that the blockstack finishes up in a sensible state (by
+ * popping any blocks we're jumping out of). We look at all the
+ * blockstack operations between the current position and the new
+ * one, and keep track of how many blocks we drop out of on the way.
+ * By also keeping track of the lowest blockstack position we see, we
+ * can tell whether the jump goes into any blocks without coming out
+ * again - in that case we raise an exception below. */
+ delta_iblock = 0;
+ for (addr = min_addr; addr < max_addr; addr++) {
+ unsigned char op = code[addr];
+ switch (op) {
+ case SETUP_LOOP:
+ case SETUP_EXCEPT:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ delta_iblock++;
+ break;
+
+ case POP_BLOCK:
+ delta_iblock--;
+ break;
+ }
+
+ min_delta_iblock = MIN(min_delta_iblock, delta_iblock);
+
+ if (op >= HAVE_ARGUMENT) {
+ addr += 2;
+ }
+ }
+
+ /* Derive the absolute iblock values from the deltas. */
+ min_iblock = f->f_iblock + min_delta_iblock;
+ if (new_lasti > f->f_lasti) {
+ /* Forwards jump. */
+ new_iblock = f->f_iblock + delta_iblock;
+ }
+ else {
+ /* Backwards jump. */
+ new_iblock = f->f_iblock - delta_iblock;
+ }
+
+ /* Are we jumping into a block? */
+ if (new_iblock > min_iblock) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump into the middle of a block");
+ return -1;
+ }
+
+ /* Pop any blocks that we're jumping out of. */
+ while (f->f_iblock > new_iblock) {
+ PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+ while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
+ PyObject *v = (*--f->f_stacktop);
+ Py_DECREF(v);
+ }
+ }
+
+ /* Finally set the new f_lineno and f_lasti and return OK. */
+ f->f_lineno = new_lineno;
+ f->f_lasti = new_lasti;
+ return 0;
+}
+
+static PyObject *
+frame_gettrace(PyFrameObject *f, void *closure)
+{
+ PyObject* trace = f->f_trace;
+
+ if (trace == NULL)
+ trace = Py_None;
+
+ Py_INCREF(trace);
+
+ return trace;
+}
+
+static int
+frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
+{
+ PyObject* old_value;
+
+ /* We rely on f_lineno being accurate when f_trace is set. */
+ f->f_lineno = PyFrame_GetLineNumber(f);
+
+ old_value = f->f_trace;
+ Py_XINCREF(v);
+ f->f_trace = v;
+ Py_XDECREF(old_value);
+
+ return 0;
+}
+
+static PyObject *
+frame_getrestricted(PyFrameObject *f, void *closure)
+{
+ return PyBool_FromLong(PyFrame_IsRestricted(f));
+}
+
+static PyGetSetDef frame_getsetlist[] = {
+ {"f_locals", (getter)frame_getlocals, NULL, NULL},
+ {"f_lineno", (getter)frame_getlineno,
+ (setter)frame_setlineno, NULL},
+ {"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL},
+ {"f_restricted",(getter)frame_getrestricted,NULL, NULL},
+ {"f_exc_traceback", (getter)frame_get_f_exc_traceback,
+ (setter)frame_set_f_exc_traceback, NULL},
+ {"f_exc_type", (getter)frame_get_f_exc_type,
+ (setter)frame_set_f_exc_type, NULL},
+ {"f_exc_value", (getter)frame_get_f_exc_value,
+ (setter)frame_set_f_exc_value, NULL},
+ {0}
+};
+
+/* Stack frames are allocated and deallocated at a considerable rate.
+ In an attempt to improve the speed of function calls, we:
+
+ 1. Hold a single "zombie" frame on each code object. This retains
+ the allocated and initialised frame object from an invocation of
+ the code object. The zombie is reanimated the next time we need a
+ frame object for that code object. Doing this saves the malloc/
+ realloc required when using a free_list frame that isn't the
+ correct size. It also saves some field initialisation.
+
+ In zombie mode, no field of PyFrameObject holds a reference, but
+ the following fields are still valid:
+
+ * ob_type, ob_size, f_code, f_valuestack;
+
+ * f_locals, f_trace,
+ f_exc_type, f_exc_value, f_exc_traceback are NULL;
+
+ * f_localsplus does not require re-allocation and
+ the local variables in f_localsplus are NULL.
+
+ 2. We also maintain a separate free list of stack frames (just like
+ integers are allocated in a special way -- see intobject.c). When
+ a stack frame is on the free list, only the following members have
+ a meaning:
+ ob_type == &Frametype
+ f_back next item on free list, or NULL
+ f_stacksize size of value stack
+ ob_size size of localsplus
+ Note that the value and block stacks are preserved -- this can save
+ another malloc() call or two (and two free() calls as well!).
+ Also note that, unlike for integers, each frame object is a
+ malloc'ed object in its own right -- it is only the actual calls to
+ malloc() that we are trying to save here, not the administration.
+ After all, while a typical program may make millions of calls, a
+ call depth of more than 20 or 30 is probably already exceptional
+ unless the program contains run-away recursion. I hope.
+
+ Later, PyFrame_MAXFREELIST was added to bound the # of frames saved on
+ free_list. Else programs creating lots of cyclic trash involving
+ frames could provoke free_list into growing without bound.
+*/
+
+static PyFrameObject *free_list = NULL;
+static int numfree = 0; /* number of frames currently in free_list */
+/* max value for numfree */
+#define PyFrame_MAXFREELIST 200
+
+static void
+frame_dealloc(PyFrameObject *f)
+{
+ PyObject **p, **valuestack;
+ PyCodeObject *co;
+
+ PyObject_GC_UnTrack(f);
+ Py_TRASHCAN_SAFE_BEGIN(f)
+ /* Kill all local variables */
+ valuestack = f->f_valuestack;
+ for (p = f->f_localsplus; p < valuestack; p++)
+ Py_CLEAR(*p);
+
+ /* Free stack */
+ if (f->f_stacktop != NULL) {
+ for (p = valuestack; p < f->f_stacktop; p++)
+ Py_XDECREF(*p);
+ }
+
+ Py_XDECREF(f->f_back);
+ Py_DECREF(f->f_builtins);
+ Py_DECREF(f->f_globals);
+ Py_CLEAR(f->f_locals);
+ Py_CLEAR(f->f_trace);
+ Py_CLEAR(f->f_exc_type);
+ Py_CLEAR(f->f_exc_value);
+ Py_CLEAR(f->f_exc_traceback);
+
+ co = f->f_code;
+ if (co->co_zombieframe == NULL)
+ co->co_zombieframe = f;
+ else if (numfree < PyFrame_MAXFREELIST) {
+ ++numfree;
+ f->f_back = free_list;
+ free_list = f;
+ }
+ else
+ PyObject_GC_Del(f);
+
+ Py_DECREF(co);
+ Py_TRASHCAN_SAFE_END(f)
+}
+
+static int
+frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
+{
+ PyObject **fastlocals, **p;
+ int i, slots;
+
+ Py_VISIT(f->f_back);
+ Py_VISIT(f->f_code);
+ Py_VISIT(f->f_builtins);
+ Py_VISIT(f->f_globals);
+ Py_VISIT(f->f_locals);
+ Py_VISIT(f->f_trace);
+ Py_VISIT(f->f_exc_type);
+ Py_VISIT(f->f_exc_value);
+ Py_VISIT(f->f_exc_traceback);
+
+ /* locals */
+ slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+ fastlocals = f->f_localsplus;
+ for (i = slots; --i >= 0; ++fastlocals)
+ Py_VISIT(*fastlocals);
+
+ /* stack */
+ if (f->f_stacktop != NULL) {
+ for (p = f->f_valuestack; p < f->f_stacktop; p++)
+ Py_VISIT(*p);
+ }
+ return 0;
+}
+
+static void
+frame_clear(PyFrameObject *f)
+{
+ PyObject **fastlocals, **p, **oldtop;
+ int i, slots;
+
+ /* Before anything else, make sure that this frame is clearly marked
+ * as being defunct! Else, e.g., a generator reachable from this
+ * frame may also point to this frame, believe itself to still be
+ * active, and try cleaning up this frame again.
+ */
+ oldtop = f->f_stacktop;
+ f->f_stacktop = NULL;
+
+ Py_CLEAR(f->f_exc_type);
+ Py_CLEAR(f->f_exc_value);
+ Py_CLEAR(f->f_exc_traceback);
+ Py_CLEAR(f->f_trace);
+
+ /* locals */
+ slots = f->f_code->co_nlocals + PyTuple_GET_SIZE(f->f_code->co_cellvars) + PyTuple_GET_SIZE(f->f_code->co_freevars);
+ fastlocals = f->f_localsplus;
+ for (i = slots; --i >= 0; ++fastlocals)
+ Py_CLEAR(*fastlocals);
+
+ /* stack */
+ if (oldtop != NULL) {
+ for (p = f->f_valuestack; p < oldtop; p++)
+ Py_CLEAR(*p);
+ }
+}
+
+static PyObject *
+frame_sizeof(PyFrameObject *f)
+{
+ Py_ssize_t res, extras, ncells, nfrees;
+
+ ncells = PyTuple_GET_SIZE(f->f_code->co_cellvars);
+ nfrees = PyTuple_GET_SIZE(f->f_code->co_freevars);
+ extras = f->f_code->co_stacksize + f->f_code->co_nlocals +
+ ncells + nfrees;
+ /* subtract one as it is already included in PyFrameObject */
+ res = sizeof(PyFrameObject) + (extras-1) * sizeof(PyObject *);
+
+ return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+"F.__sizeof__() -> size of F in memory, in bytes");
+
+static PyMethodDef frame_methods[] = {
+ {"__sizeof__", (PyCFunction)frame_sizeof, METH_NOARGS,
+ sizeof__doc__},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyFrame_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "frame",
+ sizeof(PyFrameObject),
+ sizeof(PyObject *),
+ (destructor)frame_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)frame_traverse, /* tp_traverse */
+ (inquiry)frame_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ frame_methods, /* tp_methods */
+ frame_memberlist, /* tp_members */
+ frame_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+};
+
+static PyObject *builtin_object;
+
+int _PyFrame_Init()
+{
+ builtin_object = PyString_InternFromString("__builtins__");
+ if (builtin_object == NULL)
+ return 0;
+ return 1;
+}
+
+PyFrameObject *
+PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
+ PyObject *locals)
+{
+ PyFrameObject *back = tstate->frame;
+ PyFrameObject *f;
+ PyObject *builtins;
+ Py_ssize_t i;
+
+#ifdef Py_DEBUG
+ if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
+ (locals != NULL && !PyMapping_Check(locals))) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+#endif
+ if (back == NULL || back->f_globals != globals) {
+ builtins = PyDict_GetItem(globals, builtin_object);
+ if (builtins) {
+ if (PyModule_Check(builtins)) {
+ builtins = PyModule_GetDict(builtins);
+ assert(!builtins || PyDict_Check(builtins));
+ }
+ else if (!PyDict_Check(builtins))
+ builtins = NULL;
+ }
+ if (builtins == NULL) {
+ /* No builtins! Make up a minimal one
+ Give them 'None', at least. */
+ builtins = PyDict_New();
+ if (builtins == NULL ||
+ PyDict_SetItemString(
+ builtins, "None", Py_None) < 0)
+ return NULL;
+ }
+ else
+ Py_INCREF(builtins);
+
+ }
+ else {
+ /* If we share the globals, we share the builtins.
+ Save a lookup and a call. */
+ builtins = back->f_builtins;
+ assert(builtins != NULL && PyDict_Check(builtins));
+ Py_INCREF(builtins);
+ }
+ if (code->co_zombieframe != NULL) {
+ f = code->co_zombieframe;
+ code->co_zombieframe = NULL;
+ _Py_NewReference((PyObject *)f);
+ assert(f->f_code == code);
+ }
+ else {
+ Py_ssize_t extras, ncells, nfrees;
+ ncells = PyTuple_GET_SIZE(code->co_cellvars);
+ nfrees = PyTuple_GET_SIZE(code->co_freevars);
+ extras = code->co_stacksize + code->co_nlocals + ncells +
+ nfrees;
+ if (free_list == NULL) {
+ f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type,
+ extras);
+ if (f == NULL) {
+ Py_DECREF(builtins);
+ return NULL;
+ }
+ }
+ else {
+ assert(numfree > 0);
+ --numfree;
+ f = free_list;
+ free_list = free_list->f_back;
+ if (Py_SIZE(f) < extras) {
+ f = PyObject_GC_Resize(PyFrameObject, f, extras);
+ if (f == NULL) {
+ Py_DECREF(builtins);
+ return NULL;
+ }
+ }
+ _Py_NewReference((PyObject *)f);
+ }
+
+ f->f_code = code;
+ extras = code->co_nlocals + ncells + nfrees;
+ f->f_valuestack = f->f_localsplus + extras;
+ for (i=0; i<extras; i++)
+ f->f_localsplus[i] = NULL;
+ f->f_locals = NULL;
+ f->f_trace = NULL;
+ f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
+ }
+ f->f_stacktop = f->f_valuestack;
+ f->f_builtins = builtins;
+ Py_XINCREF(back);
+ f->f_back = back;
+ Py_INCREF(code);
+ Py_INCREF(globals);
+ f->f_globals = globals;
+ /* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */
+ if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
+ (CO_NEWLOCALS | CO_OPTIMIZED))
+ ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */
+ else if (code->co_flags & CO_NEWLOCALS) {
+ locals = PyDict_New();
+ if (locals == NULL) {
+ Py_DECREF(f);
+ return NULL;
+ }
+ f->f_locals = locals;
+ }
+ else {
+ if (locals == NULL)
+ locals = globals;
+ Py_INCREF(locals);
+ f->f_locals = locals;
+ }
+ f->f_tstate = tstate;
+
+ f->f_lasti = -1;
+ f->f_lineno = code->co_firstlineno;
+ f->f_iblock = 0;
+
+ _PyObject_GC_TRACK(f);
+ return f;
+}
+
+/* Block management */
+
+void
+PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
+{
+ PyTryBlock *b;
+ if (f->f_iblock >= CO_MAXBLOCKS)
+ Py_FatalError("XXX block stack overflow");
+ b = &f->f_blockstack[f->f_iblock++];
+ b->b_type = type;
+ b->b_level = level;
+ b->b_handler = handler;
+}
+
+PyTryBlock *
+PyFrame_BlockPop(PyFrameObject *f)
+{
+ PyTryBlock *b;
+ if (f->f_iblock <= 0)
+ Py_FatalError("XXX block stack underflow");
+ b = &f->f_blockstack[--f->f_iblock];
+ return b;
+}
+
+/* Convert between "fast" version of locals and dictionary version.
+
+ map and values are input arguments. map is a tuple of strings.
+ values is an array of PyObject*. At index i, map[i] is the name of
+ the variable with value values[i]. The function copies the first
+ nmap variable from map/values into dict. If values[i] is NULL,
+ the variable is deleted from dict.
+
+ If deref is true, then the values being copied are cell variables
+ and the value is extracted from the cell variable before being put
+ in dict.
+
+ Exceptions raised while modifying the dict are silently ignored,
+ because there is no good way to report them.
+ */
+
+static void
+map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+ int deref)
+{
+ Py_ssize_t j;
+ assert(PyTuple_Check(map));
+ assert(PyDict_Check(dict));
+ assert(PyTuple_Size(map) >= nmap);
+ for (j = nmap; --j >= 0; ) {
+ PyObject *key = PyTuple_GET_ITEM(map, j);
+ PyObject *value = values[j];
+ assert(PyString_Check(key));
+ if (deref) {
+ assert(PyCell_Check(value));
+ value = PyCell_GET(value);
+ }
+ if (value == NULL) {
+ if (PyObject_DelItem(dict, key) != 0)
+ PyErr_Clear();
+ }
+ else {
+ if (PyObject_SetItem(dict, key, value) != 0)
+ PyErr_Clear();
+ }
+ }
+}
+
+/* Copy values from the "locals" dict into the fast locals.
+
+ dict is an input argument containing string keys representing
+ variables names and arbitrary PyObject* as values.
+
+ map and values are input arguments. map is a tuple of strings.
+ values is an array of PyObject*. At index i, map[i] is the name of
+ the variable with value values[i]. The function copies the first
+ nmap variable from map/values into dict. If values[i] is NULL,
+ the variable is deleted from dict.
+
+ If deref is true, then the values being copied are cell variables
+ and the value is extracted from the cell variable before being put
+ in dict. If clear is true, then variables in map but not in dict
+ are set to NULL in map; if clear is false, variables missing in
+ dict are ignored.
+
+ Exceptions raised while modifying the dict are silently ignored,
+ because there is no good way to report them.
+*/
+
+static void
+dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
+ int deref, int clear)
+{
+ Py_ssize_t j;
+ assert(PyTuple_Check(map));
+ assert(PyDict_Check(dict));
+ assert(PyTuple_Size(map) >= nmap);
+ for (j = nmap; --j >= 0; ) {
+ PyObject *key = PyTuple_GET_ITEM(map, j);
+ PyObject *value = PyObject_GetItem(dict, key);
+ assert(PyString_Check(key));
+ /* We only care about NULLs if clear is true. */
+ if (value == NULL) {
+ PyErr_Clear();
+ if (!clear)
+ continue;
+ }
+ if (deref) {
+ assert(PyCell_Check(values[j]));
+ if (PyCell_GET(values[j]) != value) {
+ if (PyCell_Set(values[j], value) < 0)
+ PyErr_Clear();
+ }
+ } else if (values[j] != value) {
+ Py_XINCREF(value);
+ Py_XDECREF(values[j]);
+ values[j] = value;
+ }
+ Py_XDECREF(value);
+ }
+}
+
+void
+PyFrame_FastToLocals(PyFrameObject *f)
+{
+ /* Merge fast locals into f->f_locals */
+ PyObject *locals, *map;
+ PyObject **fast;
+ PyObject *error_type, *error_value, *error_traceback;
+ PyCodeObject *co;
+ Py_ssize_t j;
+ int ncells, nfreevars;
+ if (f == NULL)
+ return;
+ locals = f->f_locals;
+ if (locals == NULL) {
+ locals = f->f_locals = PyDict_New();
+ if (locals == NULL) {
+ PyErr_Clear(); /* Can't report it :-( */
+ return;
+ }
+ }
+ co = f->f_code;
+ map = co->co_varnames;
+ if (!PyTuple_Check(map))
+ return;
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ fast = f->f_localsplus;
+ j = PyTuple_GET_SIZE(map);
+ if (j > co->co_nlocals)
+ j = co->co_nlocals;
+ if (co->co_nlocals)
+ map_to_dict(map, j, locals, fast, 0);
+ ncells = PyTuple_GET_SIZE(co->co_cellvars);
+ nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+ if (ncells || nfreevars) {
+ map_to_dict(co->co_cellvars, ncells,
+ locals, fast + co->co_nlocals, 1);
+ /* If the namespace is unoptimized, then one of the
+ following cases applies:
+ 1. It does not contain free variables, because it
+ uses import * or is a top-level namespace.
+ 2. It is a class namespace.
+ We don't want to accidentally copy free variables
+ into the locals dict used by the class.
+ */
+ if (co->co_flags & CO_OPTIMIZED) {
+ map_to_dict(co->co_freevars, nfreevars,
+ locals, fast + co->co_nlocals + ncells, 1);
+ }
+ }
+ PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+void
+PyFrame_LocalsToFast(PyFrameObject *f, int clear)
+{
+ /* Merge f->f_locals into fast locals */
+ PyObject *locals, *map;
+ PyObject **fast;
+ PyObject *error_type, *error_value, *error_traceback;
+ PyCodeObject *co;
+ Py_ssize_t j;
+ int ncells, nfreevars;
+ if (f == NULL)
+ return;
+ locals = f->f_locals;
+ co = f->f_code;
+ map = co->co_varnames;
+ if (locals == NULL)
+ return;
+ if (!PyTuple_Check(map))
+ return;
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ fast = f->f_localsplus;
+ j = PyTuple_GET_SIZE(map);
+ if (j > co->co_nlocals)
+ j = co->co_nlocals;
+ if (co->co_nlocals)
+ dict_to_map(co->co_varnames, j, locals, fast, 0, clear);
+ ncells = PyTuple_GET_SIZE(co->co_cellvars);
+ nfreevars = PyTuple_GET_SIZE(co->co_freevars);
+ if (ncells || nfreevars) {
+ dict_to_map(co->co_cellvars, ncells,
+ locals, fast + co->co_nlocals, 1, clear);
+ /* Same test as in PyFrame_FastToLocals() above. */
+ if (co->co_flags & CO_OPTIMIZED) {
+ dict_to_map(co->co_freevars, nfreevars,
+ locals, fast + co->co_nlocals + ncells, 1,
+ clear);
+ }
+ }
+ PyErr_Restore(error_type, error_value, error_traceback);
+}
+
+/* Clear out the free list */
+int
+PyFrame_ClearFreeList(void)
+{
+ int freelist_size = numfree;
+
+ while (free_list != NULL) {
+ PyFrameObject *f = free_list;
+ free_list = free_list->f_back;
+ PyObject_GC_Del(f);
+ --numfree;
+ }
+ assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyFrame_Fini(void)
+{
+ (void)PyFrame_ClearFreeList();
+ Py_XDECREF(builtin_object);
+ builtin_object = NULL;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/funcobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/funcobject.c
new file mode 100644
index 0000000000..571ab60184
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/funcobject.c
@@ -0,0 +1,895 @@
+
+/* Function object implementation */
+
+#include "Python.h"
+#include "code.h"
+#include "eval.h"
+#include "structmember.h"
+
+PyObject *
+PyFunction_New(PyObject *code, PyObject *globals)
+{
+ PyFunctionObject *op = PyObject_GC_New(PyFunctionObject,
+ &PyFunction_Type);
+ static PyObject *__name__ = 0;
+ if (op != NULL) {
+ PyObject *doc;
+ PyObject *consts;
+ PyObject *module;
+ op->func_weakreflist = NULL;
+ Py_INCREF(code);
+ op->func_code = code;
+ Py_INCREF(globals);
+ op->func_globals = globals;
+ op->func_name = ((PyCodeObject *)code)->co_name;
+ Py_INCREF(op->func_name);
+ op->func_defaults = NULL; /* No default arguments */
+ op->func_closure = NULL;
+ consts = ((PyCodeObject *)code)->co_consts;
+ if (PyTuple_Size(consts) >= 1) {
+ doc = PyTuple_GetItem(consts, 0);
+ if (!PyString_Check(doc) && !PyUnicode_Check(doc))
+ doc = Py_None;
+ }
+ else
+ doc = Py_None;
+ Py_INCREF(doc);
+ op->func_doc = doc;
+ op->func_dict = NULL;
+ op->func_module = NULL;
+
+ /* __module__: If module name is in globals, use it.
+ Otherwise, use None.
+ */
+ if (!__name__) {
+ __name__ = PyString_InternFromString("__name__");
+ if (!__name__) {
+ Py_DECREF(op);
+ return NULL;
+ }
+ }
+ module = PyDict_GetItem(globals, __name__);
+ if (module) {
+ Py_INCREF(module);
+ op->func_module = module;
+ }
+ }
+ else
+ return NULL;
+ _PyObject_GC_TRACK(op);
+ return (PyObject *)op;
+}
+
+PyObject *
+PyFunction_GetCode(PyObject *op)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyFunctionObject *) op) -> func_code;
+}
+
+PyObject *
+PyFunction_GetGlobals(PyObject *op)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyFunctionObject *) op) -> func_globals;
+}
+
+PyObject *
+PyFunction_GetModule(PyObject *op)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyFunctionObject *) op) -> func_module;
+}
+
+PyObject *
+PyFunction_GetDefaults(PyObject *op)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyFunctionObject *) op) -> func_defaults;
+}
+
+int
+PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (defaults == Py_None)
+ defaults = NULL;
+ else if (defaults && PyTuple_Check(defaults)) {
+ Py_INCREF(defaults);
+ }
+ else {
+ PyErr_SetString(PyExc_SystemError, "non-tuple default args");
+ return -1;
+ }
+ Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
+ ((PyFunctionObject *) op) -> func_defaults = defaults;
+ return 0;
+}
+
+PyObject *
+PyFunction_GetClosure(PyObject *op)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyFunctionObject *) op) -> func_closure;
+}
+
+int
+PyFunction_SetClosure(PyObject *op, PyObject *closure)
+{
+ if (!PyFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (closure == Py_None)
+ closure = NULL;
+ else if (PyTuple_Check(closure)) {
+ Py_INCREF(closure);
+ }
+ else {
+ PyErr_Format(PyExc_SystemError,
+ "expected tuple for closure, got '%.100s'",
+ closure->ob_type->tp_name);
+ return -1;
+ }
+ Py_XDECREF(((PyFunctionObject *) op) -> func_closure);
+ ((PyFunctionObject *) op) -> func_closure = closure;
+ return 0;
+}
+
+/* Methods */
+
+#define OFF(x) offsetof(PyFunctionObject, x)
+
+static PyMemberDef func_memberlist[] = {
+ {"func_closure", T_OBJECT, OFF(func_closure),
+ RESTRICTED|READONLY},
+ {"__closure__", T_OBJECT, OFF(func_closure),
+ RESTRICTED|READONLY},
+ {"func_doc", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},
+ {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED},
+ {"func_globals", T_OBJECT, OFF(func_globals),
+ RESTRICTED|READONLY},
+ {"__globals__", T_OBJECT, OFF(func_globals),
+ RESTRICTED|READONLY},
+ {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED},
+ {NULL} /* Sentinel */
+};
+
+static int
+restricted(void)
+{
+ if (!PyEval_GetRestricted())
+ return 0;
+ PyErr_SetString(PyExc_RuntimeError,
+ "function attributes not accessible in restricted mode");
+ return 1;
+}
+
+static PyObject *
+func_get_dict(PyFunctionObject *op)
+{
+ if (restricted())
+ return NULL;
+ if (op->func_dict == NULL) {
+ op->func_dict = PyDict_New();
+ if (op->func_dict == NULL)
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+
+static int
+func_set_dict(PyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+
+ if (restricted())
+ return -1;
+ /* It is illegal to del f.func_dict */
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ /* Can only set func_dict to a dictionary */
+ if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyObject *
+func_get_code(PyFunctionObject *op)
+{
+ if (restricted())
+ return NULL;
+ Py_INCREF(op->func_code);
+ return op->func_code;
+}
+
+static int
+func_set_code(PyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ Py_ssize_t nfree, nclosure;
+
+ if (restricted())
+ return -1;
+ /* Not legal to del f.func_code or to set it to anything
+ * other than a code object. */
+ if (value == NULL || !PyCode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__code__ must be set to a code object");
+ return -1;
+ }
+ nfree = PyCode_GetNumFree((PyCodeObject *)value);
+ nclosure = (op->func_closure == NULL ? 0 :
+ PyTuple_GET_SIZE(op->func_closure));
+ if (nclosure != nfree) {
+ PyErr_Format(PyExc_ValueError,
+ "%s() requires a code object with %zd free vars,"
+ " not %zd",
+ PyString_AsString(op->func_name),
+ nclosure, nfree);
+ return -1;
+ }
+ tmp = op->func_code;
+ Py_INCREF(value);
+ op->func_code = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyObject *
+func_get_name(PyFunctionObject *op)
+{
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+
+static int
+func_set_name(PyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+
+ if (restricted())
+ return -1;
+ /* Not legal to del f.func_name or to set it to anything
+ * other than a string object. */
+ if (value == NULL || !PyString_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_DECREF(tmp);
+ return 0;
+}
+
+static PyObject *
+func_get_defaults(PyFunctionObject *op)
+{
+ if (restricted())
+ return NULL;
+ if (op->func_defaults == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_INCREF(op->func_defaults);
+ return op->func_defaults;
+}
+
+static int
+func_set_defaults(PyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+
+ if (restricted())
+ return -1;
+ /* Legal to del f.func_defaults.
+ * Can only set func_defaults to NULL or a tuple. */
+ if (value == Py_None)
+ value = NULL;
+ if (value != NULL && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ tmp = op->func_defaults;
+ Py_XINCREF(value);
+ op->func_defaults = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyGetSetDef func_getsetlist[] = {
+ {"func_code", (getter)func_get_code, (setter)func_set_code},
+ {"__code__", (getter)func_get_code, (setter)func_set_code},
+ {"func_defaults", (getter)func_get_defaults,
+ (setter)func_set_defaults},
+ {"__defaults__", (getter)func_get_defaults,
+ (setter)func_set_defaults},
+ {"func_dict", (getter)func_get_dict, (setter)func_set_dict},
+ {"__dict__", (getter)func_get_dict, (setter)func_set_dict},
+ {"func_name", (getter)func_get_name, (setter)func_set_name},
+ {"__name__", (getter)func_get_name, (setter)func_set_name},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(func_doc,
+"function(code, globals[, name[, argdefs[, closure]]])\n\
+\n\
+Create a function object from a code object and a dictionary.\n\
+The optional name string overrides the name from the code object.\n\
+The optional argdefs tuple specifies the default argument values.\n\
+The optional closure tuple supplies the bindings for free variables.");
+
+/* func_new() maintains the following invariants for closures. The
+ closure must correspond to the free variables of the code object.
+
+ if len(code.co_freevars) == 0:
+ closure = NULL
+ else:
+ len(closure) == len(code.co_freevars)
+ for every elt in closure, type(elt) == cell
+*/
+
+static PyObject *
+func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
+{
+ PyCodeObject *code;
+ PyObject *globals;
+ PyObject *name = Py_None;
+ PyObject *defaults = Py_None;
+ PyObject *closure = Py_None;
+ PyFunctionObject *newfunc;
+ Py_ssize_t nfree, nclosure;
+ static char *kwlist[] = {"code", "globals", "name",
+ "argdefs", "closure", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!|OOO:function",
+ kwlist,
+ &PyCode_Type, &code,
+ &PyDict_Type, &globals,
+ &name, &defaults, &closure))
+ return NULL;
+ if (name != Py_None && !PyString_Check(name)) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 3 (name) must be None or string");
+ return NULL;
+ }
+ if (defaults != Py_None && !PyTuple_Check(defaults)) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 4 (defaults) must be None or tuple");
+ return NULL;
+ }
+ nfree = PyTuple_GET_SIZE(code->co_freevars);
+ if (!PyTuple_Check(closure)) {
+ if (nfree && closure == Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 5 (closure) must be tuple");
+ return NULL;
+ }
+ else if (closure != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 5 (closure) must be None or tuple");
+ return NULL;
+ }
+ }
+
+ /* check that the closure is well-formed */
+ nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
+ if (nfree != nclosure)
+ return PyErr_Format(PyExc_ValueError,
+ "%s requires closure of length %zd, not %zd",
+ PyString_AS_STRING(code->co_name),
+ nfree, nclosure);
+ if (nclosure) {
+ Py_ssize_t i;
+ for (i = 0; i < nclosure; i++) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ if (!PyCell_Check(o)) {
+ return PyErr_Format(PyExc_TypeError,
+ "arg 5 (closure) expected cell, found %s",
+ o->ob_type->tp_name);
+ }
+ }
+ }
+
+ newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
+ globals);
+ if (newfunc == NULL)
+ return NULL;
+
+ if (name != Py_None) {
+ Py_INCREF(name);
+ Py_DECREF(newfunc->func_name);
+ newfunc->func_name = name;
+ }
+ if (defaults != Py_None) {
+ Py_INCREF(defaults);
+ newfunc->func_defaults = defaults;
+ }
+ if (closure != Py_None) {
+ Py_INCREF(closure);
+ newfunc->func_closure = closure;
+ }
+
+ return (PyObject *)newfunc;
+}
+
+static void
+func_dealloc(PyFunctionObject *op)
+{
+ _PyObject_GC_UNTRACK(op);
+ if (op->func_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) op);
+ Py_DECREF(op->func_code);
+ Py_DECREF(op->func_globals);
+ Py_XDECREF(op->func_module);
+ Py_DECREF(op->func_name);
+ Py_XDECREF(op->func_defaults);
+ Py_XDECREF(op->func_doc);
+ Py_XDECREF(op->func_dict);
+ Py_XDECREF(op->func_closure);
+ PyObject_GC_Del(op);
+}
+
+static PyObject*
+func_repr(PyFunctionObject *op)
+{
+ return PyString_FromFormat("<function %s at %p>",
+ PyString_AsString(op->func_name),
+ op);
+}
+
+static int
+func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
+{
+ Py_VISIT(f->func_code);
+ Py_VISIT(f->func_globals);
+ Py_VISIT(f->func_module);
+ Py_VISIT(f->func_defaults);
+ Py_VISIT(f->func_doc);
+ Py_VISIT(f->func_name);
+ Py_VISIT(f->func_dict);
+ Py_VISIT(f->func_closure);
+ return 0;
+}
+
+static PyObject *
+function_call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ PyObject *result;
+ PyObject *argdefs;
+ PyObject *kwtuple = NULL;
+ PyObject **d, **k;
+ Py_ssize_t nk, nd;
+
+ argdefs = PyFunction_GET_DEFAULTS(func);
+ if (argdefs != NULL && PyTuple_Check(argdefs)) {
+ d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
+ nd = PyTuple_GET_SIZE(argdefs);
+ }
+ else {
+ d = NULL;
+ nd = 0;
+ }
+
+ if (kw != NULL && PyDict_Check(kw)) {
+ Py_ssize_t pos, i;
+ nk = PyDict_Size(kw);
+ kwtuple = PyTuple_New(2*nk);
+ if (kwtuple == NULL)
+ return NULL;
+ k = &PyTuple_GET_ITEM(kwtuple, 0);
+ pos = i = 0;
+ while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) {
+ Py_INCREF(k[i]);
+ Py_INCREF(k[i+1]);
+ i += 2;
+ }
+ nk = i/2;
+ }
+ else {
+ k = NULL;
+ nk = 0;
+ }
+
+ result = PyEval_EvalCodeEx(
+ (PyCodeObject *)PyFunction_GET_CODE(func),
+ PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
+ &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
+ k, nk, d, nd,
+ PyFunction_GET_CLOSURE(func));
+
+ Py_XDECREF(kwtuple);
+
+ return result;
+}
+
+/* Bind a function to an object */
+static PyObject *
+func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ if (obj == Py_None)
+ obj = NULL;
+ return PyMethod_New(func, obj, type);
+}
+
+PyTypeObject PyFunction_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "function",
+ sizeof(PyFunctionObject),
+ 0,
+ (destructor)func_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)func_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ function_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ func_doc, /* tp_doc */
+ (traverseproc)func_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ func_memberlist, /* tp_members */
+ func_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ func_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ func_new, /* tp_new */
+};
+
+
+/* Class method object */
+
+/* A class method receives the class as implicit first argument,
+ just like an instance method receives the instance.
+ To declare a class method, use this idiom:
+
+ class C:
+ def f(cls, arg1, arg2, ...): ...
+ f = classmethod(f)
+
+ It can be called either on the class (e.g. C.f()) or on an instance
+ (e.g. C().f()); the instance is ignored except for its class.
+ If a class method is called for a derived class, the derived class
+ object is passed as the implied first argument.
+
+ Class methods are different than C++ or Java static methods.
+ If you want those, see static methods below.
+*/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *cm_callable;
+} classmethod;
+
+static void
+cm_dealloc(classmethod *cm)
+{
+ _PyObject_GC_UNTRACK((PyObject *)cm);
+ Py_XDECREF(cm->cm_callable);
+ Py_TYPE(cm)->tp_free((PyObject *)cm);
+}
+
+static int
+cm_traverse(classmethod *cm, visitproc visit, void *arg)
+{
+ Py_VISIT(cm->cm_callable);
+ return 0;
+}
+
+static int
+cm_clear(classmethod *cm)
+{
+ Py_CLEAR(cm->cm_callable);
+ return 0;
+}
+
+
+static PyObject *
+cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ classmethod *cm = (classmethod *)self;
+
+ if (cm->cm_callable == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "uninitialized classmethod object");
+ return NULL;
+ }
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return PyMethod_New(cm->cm_callable,
+ type, (PyObject *)(Py_TYPE(type)));
+}
+
+static int
+cm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ classmethod *cm = (classmethod *)self;
+ PyObject *callable;
+
+ if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable))
+ return -1;
+ if (!_PyArg_NoKeywords("classmethod", kwds))
+ return -1;
+ Py_INCREF(callable);
+ cm->cm_callable = callable;
+ return 0;
+}
+
+static PyMemberDef cm_memberlist[] = {
+ {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(classmethod_doc,
+"classmethod(function) -> method\n\
+\n\
+Convert a function to be a class method.\n\
+\n\
+A class method receives the class as implicit first argument,\n\
+just like an instance method receives the instance.\n\
+To declare a class method, use this idiom:\n\
+\n\
+ class C:\n\
+ def f(cls, arg1, arg2, ...): ...\n\
+ f = classmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()). The instance is ignored except for its class.\n\
+If a class method is called for a derived class, the derived class\n\
+object is passed as the implied first argument.\n\
+\n\
+Class methods are different than C++ or Java static methods.\n\
+If you want those, see the staticmethod builtin.");
+
+PyTypeObject PyClassMethod_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "classmethod",
+ sizeof(classmethod),
+ 0,
+ (destructor)cm_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ classmethod_doc, /* tp_doc */
+ (traverseproc)cm_traverse, /* tp_traverse */
+ (inquiry)cm_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ cm_memberlist, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ cm_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ cm_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+PyObject *
+PyClassMethod_New(PyObject *callable)
+{
+ classmethod *cm = (classmethod *)
+ PyType_GenericAlloc(&PyClassMethod_Type, 0);
+ if (cm != NULL) {
+ Py_INCREF(callable);
+ cm->cm_callable = callable;
+ }
+ return (PyObject *)cm;
+}
+
+
+/* Static method object */
+
+/* A static method does not receive an implicit first argument.
+ To declare a static method, use this idiom:
+
+ class C:
+ def f(arg1, arg2, ...): ...
+ f = staticmethod(f)
+
+ It can be called either on the class (e.g. C.f()) or on an instance
+ (e.g. C().f()); the instance is ignored except for its class.
+
+ Static methods in Python are similar to those found in Java or C++.
+ For a more advanced concept, see class methods above.
+*/
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *sm_callable;
+} staticmethod;
+
+static void
+sm_dealloc(staticmethod *sm)
+{
+ _PyObject_GC_UNTRACK((PyObject *)sm);
+ Py_XDECREF(sm->sm_callable);
+ Py_TYPE(sm)->tp_free((PyObject *)sm);
+}
+
+static int
+sm_traverse(staticmethod *sm, visitproc visit, void *arg)
+{
+ Py_VISIT(sm->sm_callable);
+ return 0;
+}
+
+static int
+sm_clear(staticmethod *sm)
+{
+ Py_CLEAR(sm->sm_callable);
+ return 0;
+}
+
+static PyObject *
+sm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ staticmethod *sm = (staticmethod *)self;
+
+ if (sm->sm_callable == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "uninitialized staticmethod object");
+ return NULL;
+ }
+ Py_INCREF(sm->sm_callable);
+ return sm->sm_callable;
+}
+
+static int
+sm_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ staticmethod *sm = (staticmethod *)self;
+ PyObject *callable;
+
+ if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable))
+ return -1;
+ if (!_PyArg_NoKeywords("staticmethod", kwds))
+ return -1;
+ Py_INCREF(callable);
+ sm->sm_callable = callable;
+ return 0;
+}
+
+static PyMemberDef sm_memberlist[] = {
+ {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(staticmethod_doc,
+"staticmethod(function) -> method\n\
+\n\
+Convert a function to be a static method.\n\
+\n\
+A static method does not receive an implicit first argument.\n\
+To declare a static method, use this idiom:\n\
+\n\
+ class C:\n\
+ def f(arg1, arg2, ...): ...\n\
+ f = staticmethod(f)\n\
+\n\
+It can be called either on the class (e.g. C.f()) or on an instance\n\
+(e.g. C().f()). The instance is ignored except for its class.\n\
+\n\
+Static methods in Python are similar to those found in Java or C++.\n\
+For a more advanced concept, see the classmethod builtin.");
+
+PyTypeObject PyStaticMethod_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "staticmethod",
+ sizeof(staticmethod),
+ 0,
+ (destructor)sm_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ staticmethod_doc, /* tp_doc */
+ (traverseproc)sm_traverse, /* tp_traverse */
+ (inquiry)sm_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ sm_memberlist, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ sm_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ sm_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+PyObject *
+PyStaticMethod_New(PyObject *callable)
+{
+ staticmethod *sm = (staticmethod *)
+ PyType_GenericAlloc(&PyStaticMethod_Type, 0);
+ if (sm != NULL) {
+ Py_INCREF(callable);
+ sm->sm_callable = callable;
+ }
+ return (PyObject *)sm;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/genobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/genobject.c
new file mode 100644
index 0000000000..57272ce253
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/genobject.c
@@ -0,0 +1,417 @@
+/* Generator object implementation */
+
+#include "Python.h"
+#include "frameobject.h"
+#include "genobject.h"
+#include "ceval.h"
+#include "structmember.h"
+#include "opcode.h"
+
+static int
+gen_traverse(PyGenObject *gen, visitproc visit, void *arg)
+{
+ Py_VISIT((PyObject *)gen->gi_frame);
+ Py_VISIT(gen->gi_code);
+ return 0;
+}
+
+static void
+gen_dealloc(PyGenObject *gen)
+{
+ PyObject *self = (PyObject *) gen;
+
+ _PyObject_GC_UNTRACK(gen);
+
+ if (gen->gi_weakreflist != NULL)
+ PyObject_ClearWeakRefs(self);
+
+ _PyObject_GC_TRACK(self);
+
+ if (gen->gi_frame != NULL && gen->gi_frame->f_stacktop != NULL) {
+ /* Generator is paused, so we need to close */
+ Py_TYPE(gen)->tp_del(self);
+ if (self->ob_refcnt > 0)
+ return; /* resurrected. :( */
+ }
+
+ _PyObject_GC_UNTRACK(self);
+ Py_CLEAR(gen->gi_frame);
+ Py_CLEAR(gen->gi_code);
+ PyObject_GC_Del(gen);
+}
+
+
+static PyObject *
+gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ PyFrameObject *f = gen->gi_frame;
+ PyObject *result;
+
+ if (gen->gi_running) {
+ PyErr_SetString(PyExc_ValueError,
+ "generator already executing");
+ return NULL;
+ }
+ if (f==NULL || f->f_stacktop == NULL) {
+ /* Only set exception if called from send() */
+ if (arg && !exc)
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
+
+ if (f->f_lasti == -1) {
+ if (arg && arg != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't send non-None value to a "
+ "just-started generator");
+ return NULL;
+ }
+ } else {
+ /* Push arg onto the frame's value stack */
+ result = arg ? arg : Py_None;
+ Py_INCREF(result);
+ *(f->f_stacktop++) = result;
+ }
+
+ /* Generators always return to their most recent caller, not
+ * necessarily their creator. */
+ f->f_tstate = tstate;
+ Py_XINCREF(tstate->frame);
+ assert(f->f_back == NULL);
+ f->f_back = tstate->frame;
+
+ gen->gi_running = 1;
+ result = PyEval_EvalFrameEx(f, exc);
+ gen->gi_running = 0;
+
+ /* Don't keep the reference to f_back any longer than necessary. It
+ * may keep a chain of frames alive or it could create a reference
+ * cycle. */
+ assert(f->f_back == tstate->frame);
+ Py_CLEAR(f->f_back);
+ /* Clear the borrowed reference to the thread state */
+ f->f_tstate = NULL;
+
+ /* If the generator just returned (as opposed to yielding), signal
+ * that the generator is exhausted. */
+ if (result == Py_None && f->f_stacktop == NULL) {
+ Py_DECREF(result);
+ result = NULL;
+ /* Set exception if not called by gen_iternext() */
+ if (arg)
+ PyErr_SetNone(PyExc_StopIteration);
+ }
+
+ if (!result || f->f_stacktop == NULL) {
+ /* generator can't be rerun, so release the frame */
+ Py_DECREF(f);
+ gen->gi_frame = NULL;
+ }
+
+ return result;
+}
+
+PyDoc_STRVAR(send_doc,
+"send(arg) -> send 'arg' into generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_send(PyGenObject *gen, PyObject *arg)
+{
+ return gen_send_ex(gen, arg, 0);
+}
+
+PyDoc_STRVAR(close_doc,
+"close() -> raise GeneratorExit inside generator.");
+
+static PyObject *
+gen_close(PyGenObject *gen, PyObject *args)
+{
+ PyObject *retval;
+ PyErr_SetNone(PyExc_GeneratorExit);
+ retval = gen_send_ex(gen, Py_None, 1);
+ if (retval) {
+ Py_DECREF(retval);
+ PyErr_SetString(PyExc_RuntimeError,
+ "generator ignored GeneratorExit");
+ return NULL;
+ }
+ if (PyErr_ExceptionMatches(PyExc_StopIteration)
+ || PyErr_ExceptionMatches(PyExc_GeneratorExit))
+ {
+ PyErr_Clear(); /* ignore these errors */
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return NULL;
+}
+
+static void
+gen_del(PyObject *self)
+{
+ PyObject *res;
+ PyObject *error_type, *error_value, *error_traceback;
+ PyGenObject *gen = (PyGenObject *)self;
+
+ if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL)
+ /* Generator isn't paused, so no need to close */
+ return;
+
+ /* Temporarily resurrect the object. */
+ assert(self->ob_refcnt == 0);
+ self->ob_refcnt = 1;
+
+ /* Save the current exception, if any. */
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+ res = gen_close(gen, NULL);
+
+ if (res == NULL)
+ PyErr_WriteUnraisable(self);
+ else
+ Py_DECREF(res);
+
+ /* Restore the saved exception. */
+ PyErr_Restore(error_type, error_value, error_traceback);
+
+ /* Undo the temporary resurrection; can't use DECREF here, it would
+ * cause a recursive call.
+ */
+ assert(self->ob_refcnt > 0);
+ if (--self->ob_refcnt == 0)
+ return; /* this is the normal path out */
+
+ /* close() resurrected it! Make it look like the original Py_DECREF
+ * never happened.
+ */
+ {
+ Py_ssize_t refcnt = self->ob_refcnt;
+ _Py_NewReference(self);
+ self->ob_refcnt = refcnt;
+ }
+ assert(PyType_IS_GC(self->ob_type) &&
+ _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+
+ /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+ * we need to undo that. */
+ _Py_DEC_REFTOTAL;
+ /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+ * chain, so no more to do there.
+ * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+ * _Py_NewReference bumped tp_allocs: both of those need to be
+ * undone.
+ */
+#ifdef COUNT_ALLOCS
+ --self->ob_type->tp_frees;
+ --self->ob_type->tp_allocs;
+#endif
+}
+
+
+
+PyDoc_STRVAR(throw_doc,
+"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
+return next yielded value or raise StopIteration.");
+
+static PyObject *
+gen_throw(PyGenObject *gen, PyObject *args)
+{
+ PyObject *typ;
+ PyObject *tb = NULL;
+ PyObject *val = NULL;
+
+ if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb))
+ return NULL;
+
+ /* First, check the traceback argument, replacing None with
+ NULL. */
+ if (tb == Py_None)
+ tb = NULL;
+ else if (tb != NULL && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "throw() third argument must be a traceback object");
+ return NULL;
+ }
+
+ Py_INCREF(typ);
+ Py_XINCREF(val);
+ Py_XINCREF(tb);
+
+ if (PyExceptionClass_Check(typ)) {
+ PyErr_NormalizeException(&typ, &val, &tb);
+ }
+
+ else if (PyExceptionInstance_Check(typ)) {
+ /* Raising an instance. The value should be a dummy. */
+ if (val && val != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto failed_throw;
+ }
+ else {
+ /* Normalize to raise <class>, <instance> */
+ Py_XDECREF(val);
+ val = typ;
+ typ = PyExceptionInstance_Class(typ);
+ Py_INCREF(typ);
+ }
+ }
+ else {
+ /* Not something you can raise. throw() fails. */
+ PyErr_Format(PyExc_TypeError,
+ "exceptions must be classes, or instances, not %s",
+ typ->ob_type->tp_name);
+ goto failed_throw;
+ }
+
+ PyErr_Restore(typ, val, tb);
+ return gen_send_ex(gen, Py_None, 1);
+
+failed_throw:
+ /* Didn't use our arguments, so restore their original refcounts */
+ Py_DECREF(typ);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
+ return NULL;
+}
+
+
+static PyObject *
+gen_iternext(PyGenObject *gen)
+{
+ return gen_send_ex(gen, NULL, 0);
+}
+
+
+static PyObject *
+gen_repr(PyGenObject *gen)
+{
+ char *code_name;
+ code_name = PyString_AsString(((PyCodeObject *)gen->gi_code)->co_name);
+ if (code_name == NULL)
+ return NULL;
+ return PyString_FromFormat("<generator object %.200s at %p>",
+ code_name, gen);
+}
+
+
+static PyObject *
+gen_get_name(PyGenObject *gen)
+{
+ PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name;
+ Py_INCREF(name);
+ return name;
+}
+
+
+PyDoc_STRVAR(gen__name__doc__,
+"Return the name of the generator's associated code object.");
+
+static PyGetSetDef gen_getsetlist[] = {
+ {"__name__", (getter)gen_get_name, NULL, gen__name__doc__},
+ {NULL}
+};
+
+
+static PyMemberDef gen_memberlist[] = {
+ {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
+ {"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
+ {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), RO},
+ {NULL} /* Sentinel */
+};
+
+static PyMethodDef gen_methods[] = {
+ {"send",(PyCFunction)gen_send, METH_O, send_doc},
+ {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
+ {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
+ {NULL, NULL} /* Sentinel */
+};
+
+PyTypeObject PyGen_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "generator", /* tp_name */
+ sizeof(PyGenObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)gen_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)gen_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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)gen_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyGenObject, gi_weakreflist), /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)gen_iternext, /* tp_iternext */
+ gen_methods, /* tp_methods */
+ gen_memberlist, /* tp_members */
+ gen_getsetlist, /* 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 */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+ gen_del, /* tp_del */
+};
+
+PyObject *
+PyGen_New(PyFrameObject *f)
+{
+ PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type);
+ if (gen == NULL) {
+ Py_DECREF(f);
+ return NULL;
+ }
+ gen->gi_frame = f;
+ Py_INCREF(f->f_code);
+ gen->gi_code = (PyObject *)(f->f_code);
+ gen->gi_running = 0;
+ gen->gi_weakreflist = NULL;
+ _PyObject_GC_TRACK(gen);
+ return (PyObject *)gen;
+}
+
+int
+PyGen_NeedsFinalizing(PyGenObject *gen)
+{
+ int i;
+ PyFrameObject *f = gen->gi_frame;
+
+ if (f == NULL || f->f_stacktop == NULL || f->f_iblock <= 0)
+ return 0; /* no frame or empty blockstack == no finalization */
+
+ /* Any block type besides a loop requires cleanup. */
+ i = f->f_iblock;
+ while (--i >= 0) {
+ if (f->f_blockstack[i].b_type != SETUP_LOOP)
+ return 1;
+ }
+
+ /* No blocks except loops, it's safe to skip finalization. */
+ return 0;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/intobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/intobject.c
new file mode 100644
index 0000000000..93732b0993
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/intobject.c
@@ -0,0 +1,1581 @@
+
+/* Integer object implementation */
+
+#include "Python.h"
+#include <ctype.h>
+#include <float.h>
+
+static PyObject *int_int(PyIntObject *v);
+
+long
+PyInt_GetMax(void)
+{
+ return LONG_MAX; /* To initialize sys.maxint */
+}
+
+/* Integers are quite normal objects, to make object handling uniform.
+ (Using odd pointers to represent integers would save much space
+ but require extra checks for this special case throughout the code.)
+ Since a typical Python program spends much of its time allocating
+ and deallocating integers, these operations should be very fast.
+ Therefore we use a dedicated allocation scheme with a much lower
+ overhead (in space and time) than straight malloc(): a simple
+ dedicated free list, filled when necessary with memory from malloc().
+
+ block_list is a singly-linked list of all PyIntBlocks ever allocated,
+ linked via their next members. PyIntBlocks are never returned to the
+ system before shutdown (PyInt_Fini).
+
+ free_list is a singly-linked list of available PyIntObjects, linked
+ via abuse of their ob_type members.
+*/
+
+#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
+#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
+#define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))
+
+struct _intblock {
+ struct _intblock *next;
+ PyIntObject objects[N_INTOBJECTS];
+};
+
+typedef struct _intblock PyIntBlock;
+
+static PyIntBlock *block_list = NULL;
+static PyIntObject *free_list = NULL;
+
+static PyIntObject *
+fill_free_list(void)
+{
+ PyIntObject *p, *q;
+ /* Python's object allocator isn't appropriate for large blocks. */
+ p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
+ if (p == NULL)
+ return (PyIntObject *) PyErr_NoMemory();
+ ((PyIntBlock *)p)->next = block_list;
+ block_list = (PyIntBlock *)p;
+ /* Link the int objects together, from rear to front, then return
+ the address of the last int object in the block. */
+ p = &((PyIntBlock *)p)->objects[0];
+ q = p + N_INTOBJECTS;
+ while (--q > p)
+ Py_TYPE(q) = (struct _typeobject *)(q-1);
+ Py_TYPE(q) = NULL;
+ return p + N_INTOBJECTS - 1;
+}
+
+#ifndef NSMALLPOSINTS
+#define NSMALLPOSINTS 257
+#endif
+#ifndef NSMALLNEGINTS
+#define NSMALLNEGINTS 5
+#endif
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+/* References to small integers are saved in this array so that they
+ can be shared.
+ The integers that are saved are those in the range
+ -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
+*/
+static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
+#endif
+#ifdef COUNT_ALLOCS
+Py_ssize_t quick_int_allocs;
+Py_ssize_t quick_neg_int_allocs;
+#endif
+
+PyObject *
+PyInt_FromLong(long ival)
+{
+ register PyIntObject *v;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
+ v = small_ints[ival + NSMALLNEGINTS];
+ Py_INCREF(v);
+#ifdef COUNT_ALLOCS
+ if (ival >= 0)
+ quick_int_allocs++;
+ else
+ quick_neg_int_allocs++;
+#endif
+ return (PyObject *) v;
+ }
+#endif
+ if (free_list == NULL) {
+ if ((free_list = fill_free_list()) == NULL)
+ return NULL;
+ }
+ /* Inline PyObject_New */
+ v = free_list;
+ free_list = (PyIntObject *)Py_TYPE(v);
+ PyObject_INIT(v, &PyInt_Type);
+ v->ob_ival = ival;
+ return (PyObject *) v;
+}
+
+PyObject *
+PyInt_FromSize_t(size_t ival)
+{
+ if (ival <= LONG_MAX)
+ return PyInt_FromLong((long)ival);
+ return _PyLong_FromSize_t(ival);
+}
+
+PyObject *
+PyInt_FromSsize_t(Py_ssize_t ival)
+{
+ if (ival >= LONG_MIN && ival <= LONG_MAX)
+ return PyInt_FromLong((long)ival);
+ return _PyLong_FromSsize_t(ival);
+}
+
+static void
+int_dealloc(PyIntObject *v)
+{
+ if (PyInt_CheckExact(v)) {
+ Py_TYPE(v) = (struct _typeobject *)free_list;
+ free_list = v;
+ }
+ else
+ Py_TYPE(v)->tp_free((PyObject *)v);
+}
+
+static void
+int_free(PyIntObject *v)
+{
+ Py_TYPE(v) = (struct _typeobject *)free_list;
+ free_list = v;
+}
+
+long
+PyInt_AsLong(register PyObject *op)
+{
+ PyNumberMethods *nb;
+ PyIntObject *io;
+ long val;
+
+ if (op && PyInt_Check(op))
+ return PyInt_AS_LONG((PyIntObject*) op);
+
+ if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+ nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return -1;
+ }
+
+ io = (PyIntObject*) (*nb->nb_int) (op);
+ if (io == NULL)
+ return -1;
+ if (!PyInt_Check(io)) {
+ if (PyLong_Check(io)) {
+ /* got a long? => retry int conversion */
+ val = PyLong_AsLong((PyObject *)io);
+ Py_DECREF(io);
+ if ((val == -1) && PyErr_Occurred())
+ return -1;
+ return val;
+ }
+ else
+ {
+ Py_DECREF(io);
+ PyErr_SetString(PyExc_TypeError,
+ "__int__ method should return an integer");
+ return -1;
+ }
+ }
+
+ val = PyInt_AS_LONG(io);
+ Py_DECREF(io);
+
+ return val;
+}
+
+int
+_PyInt_AsInt(PyObject *obj)
+{
+ long result = PyInt_AsLong(obj);
+ if (result == -1 && PyErr_Occurred())
+ return -1;
+ if (result > INT_MAX || result < INT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C int");
+ return -1;
+ }
+ return (int)result;
+}
+
+Py_ssize_t
+PyInt_AsSsize_t(register PyObject *op)
+{
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+ PyNumberMethods *nb;
+ PyObject *io;
+ Py_ssize_t val;
+#endif
+
+ if (op == NULL) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return -1;
+ }
+
+ if (PyInt_Check(op))
+ return PyInt_AS_LONG((PyIntObject*) op);
+ if (PyLong_Check(op))
+ return _PyLong_AsSsize_t(op);
+#if SIZEOF_SIZE_T == SIZEOF_LONG
+ return PyInt_AsLong(op);
+#else
+
+ if ((nb = Py_TYPE(op)->tp_as_number) == NULL ||
+ (nb->nb_int == NULL && nb->nb_long == 0)) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return -1;
+ }
+
+ if (nb->nb_long != 0)
+ io = (*nb->nb_long)(op);
+ else
+ io = (*nb->nb_int)(op);
+ if (io == NULL)
+ return -1;
+ if (!PyInt_Check(io)) {
+ if (PyLong_Check(io)) {
+ /* got a long? => retry int conversion */
+ val = _PyLong_AsSsize_t(io);
+ Py_DECREF(io);
+ if ((val == -1) && PyErr_Occurred())
+ return -1;
+ return val;
+ }
+ else
+ {
+ Py_DECREF(io);
+ PyErr_SetString(PyExc_TypeError,
+ "__int__ method should return an integer");
+ return -1;
+ }
+ }
+
+ val = PyInt_AS_LONG(io);
+ Py_DECREF(io);
+
+ return val;
+#endif
+}
+
+unsigned long
+PyInt_AsUnsignedLongMask(register PyObject *op)
+{
+ PyNumberMethods *nb;
+ PyIntObject *io;
+ unsigned long val;
+
+ if (op && PyInt_Check(op))
+ return PyInt_AS_LONG((PyIntObject*) op);
+ if (op && PyLong_Check(op))
+ return PyLong_AsUnsignedLongMask(op);
+
+ if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+ nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return (unsigned long)-1;
+ }
+
+ io = (PyIntObject*) (*nb->nb_int) (op);
+ if (io == NULL)
+ return (unsigned long)-1;
+ if (!PyInt_Check(io)) {
+ if (PyLong_Check(io)) {
+ val = PyLong_AsUnsignedLongMask((PyObject *)io);
+ Py_DECREF(io);
+ if (PyErr_Occurred())
+ return (unsigned long)-1;
+ return val;
+ }
+ else
+ {
+ Py_DECREF(io);
+ PyErr_SetString(PyExc_TypeError,
+ "__int__ method should return an integer");
+ return (unsigned long)-1;
+ }
+ }
+
+ val = PyInt_AS_LONG(io);
+ Py_DECREF(io);
+
+ return val;
+}
+
+#ifdef HAVE_LONG_LONG
+unsigned PY_LONG_LONG
+PyInt_AsUnsignedLongLongMask(register PyObject *op)
+{
+ PyNumberMethods *nb;
+ PyIntObject *io;
+ unsigned PY_LONG_LONG val;
+
+ if (op && PyInt_Check(op))
+ return PyInt_AS_LONG((PyIntObject*) op);
+ if (op && PyLong_Check(op))
+ return PyLong_AsUnsignedLongLongMask(op);
+
+ if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
+ nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return (unsigned PY_LONG_LONG)-1;
+ }
+
+ io = (PyIntObject*) (*nb->nb_int) (op);
+ if (io == NULL)
+ return (unsigned PY_LONG_LONG)-1;
+ if (!PyInt_Check(io)) {
+ if (PyLong_Check(io)) {
+ val = PyLong_AsUnsignedLongLongMask((PyObject *)io);
+ Py_DECREF(io);
+ if (PyErr_Occurred())
+ return (unsigned PY_LONG_LONG)-1;
+ return val;
+ }
+ else
+ {
+ Py_DECREF(io);
+ PyErr_SetString(PyExc_TypeError,
+ "__int__ method should return an integer");
+ return (unsigned PY_LONG_LONG)-1;
+ }
+ }
+
+ val = PyInt_AS_LONG(io);
+ Py_DECREF(io);
+
+ return val;
+}
+#endif
+
+PyObject *
+PyInt_FromString(char *s, char **pend, int base)
+{
+ char *end;
+ long x;
+ Py_ssize_t slen;
+ PyObject *sobj, *srepr;
+
+ if ((base != 0 && base < 2) || base > 36) {
+ PyErr_SetString(PyExc_ValueError,
+ "int() base must be >= 2 and <= 36");
+ return NULL;
+ }
+
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ errno = 0;
+ if (base == 0 && s[0] == '0') {
+ x = (long) PyOS_strtoul(s, &end, base);
+ if (x < 0)
+ return PyLong_FromString(s, pend, base);
+ }
+ else
+ x = PyOS_strtol(s, &end, base);
+ if (end == s || !isalnum(Py_CHARMASK(end[-1])))
+ goto bad;
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ bad:
+ slen = strlen(s) < 200 ? strlen(s) : 200;
+ sobj = PyString_FromStringAndSize(s, slen);
+ if (sobj == NULL)
+ return NULL;
+ srepr = PyObject_Repr(sobj);
+ Py_DECREF(sobj);
+ if (srepr == NULL)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "invalid literal for int() with base %d: %s",
+ base, PyString_AS_STRING(srepr));
+ Py_DECREF(srepr);
+ return NULL;
+ }
+ else if (errno != 0)
+ return PyLong_FromString(s, pend, base);
+ if (pend)
+ *pend = end;
+ return PyInt_FromLong(x);
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
+{
+ PyObject *result;
+ char *buffer = (char *)PyMem_MALLOC(length+1);
+
+ if (buffer == NULL)
+ return PyErr_NoMemory();
+
+ if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
+ PyMem_FREE(buffer);
+ return NULL;
+ }
+ result = PyInt_FromString(buffer, NULL, base);
+ PyMem_FREE(buffer);
+ return result;
+}
+#endif
+
+/* Methods */
+
+/* Integers are seen as the "smallest" of all numeric types and thus
+ don't have any knowledge about conversion of other types to
+ integers. */
+
+#define CONVERT_TO_LONG(obj, lng) \
+ if (PyInt_Check(obj)) { \
+ lng = PyInt_AS_LONG(obj); \
+ } \
+ else { \
+ Py_INCREF(Py_NotImplemented); \
+ return Py_NotImplemented; \
+ }
+
+/* ARGSUSED */
+static int
+int_print(PyIntObject *v, FILE *fp, int flags)
+ /* flags -- not used but required by interface */
+{
+ long int_val = v->ob_ival;
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "%ld", int_val);
+ Py_END_ALLOW_THREADS
+ return 0;
+}
+
+static int
+int_compare(PyIntObject *v, PyIntObject *w)
+{
+ register long i = v->ob_ival;
+ register long j = w->ob_ival;
+ return (i < j) ? -1 : (i > j) ? 1 : 0;
+}
+
+static long
+int_hash(PyIntObject *v)
+{
+ /* XXX If this is changed, you also need to change the way
+ Python's long, float and complex types are hashed. */
+ long x = v -> ob_ival;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+static PyObject *
+int_add(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b, x;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ /* casts in the line below avoid undefined behaviour on overflow */
+ x = (long)((unsigned long)a + b);
+ if ((x^a) >= 0 || (x^b) >= 0)
+ return PyInt_FromLong(x);
+ return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
+}
+
+static PyObject *
+int_sub(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b, x;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ /* casts in the line below avoid undefined behaviour on overflow */
+ x = (long)((unsigned long)a - b);
+ if ((x^a) >= 0 || (x^~b) >= 0)
+ return PyInt_FromLong(x);
+ return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
+ (PyObject *)w);
+}
+
+/*
+Integer overflow checking for * is painful: Python tried a couple ways, but
+they didn't work on all platforms, or failed in endcases (a product of
+-sys.maxint-1 has been a particular pain).
+
+Here's another way:
+
+The native long product x*y is either exactly right or *way* off, being
+just the last n bits of the true product, where n is the number of bits
+in a long (the delivered product is the true product plus i*2**n for
+some integer i).
+
+The native double product (double)x * (double)y is subject to three
+rounding errors: on a sizeof(long)==8 box, each cast to double can lose
+info, and even on a sizeof(long)==4 box, the multiplication can lose info.
+But, unlike the native long product, it's not in *range* trouble: even
+if sizeof(long)==32 (256-bit longs), the product easily fits in the
+dynamic range of a double. So the leading 50 (or so) bits of the double
+product are correct.
+
+We check these two ways against each other, and declare victory if they're
+approximately the same. Else, because the native long product is the only
+one that can lose catastrophic amounts of information, it's the native long
+product that must have overflowed.
+*/
+
+static PyObject *
+int_mul(PyObject *v, PyObject *w)
+{
+ long a, b;
+ long longprod; /* a*b in native long arithmetic */
+ double doubled_longprod; /* (double)longprod */
+ double doubleprod; /* (double)a * (double)b */
+
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ /* casts in the next line avoid undefined behaviour on overflow */
+ longprod = (long)((unsigned long)a * b);
+ doubleprod = (double)a * (double)b;
+ doubled_longprod = (double)longprod;
+
+ /* Fast path for normal case: small multiplicands, and no info
+ is lost in either method. */
+ if (doubled_longprod == doubleprod)
+ return PyInt_FromLong(longprod);
+
+ /* Somebody somewhere lost info. Close enough, or way off? Note
+ that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+ The difference either is or isn't significant compared to the
+ true value (of which doubleprod is a good approximation).
+ */
+ {
+ const double diff = doubled_longprod - doubleprod;
+ const double absdiff = diff >= 0.0 ? diff : -diff;
+ const double absprod = doubleprod >= 0.0 ? doubleprod :
+ -doubleprod;
+ /* absdiff/absprod <= 1/32 iff
+ 32 * absdiff <= absprod -- 5 good bits is "close enough" */
+ if (32.0 * absdiff <= absprod)
+ return PyInt_FromLong(longprod);
+ else
+ return PyLong_Type.tp_as_number->nb_multiply(v, w);
+ }
+}
+
+/* Integer overflow checking for unary negation: on a 2's-complement
+ * box, -x overflows iff x is the most negative long. In this case we
+ * get -x == x. However, -x is undefined (by C) if x /is/ the most
+ * negative long (it's a signed overflow case), and some compilers care.
+ * So we cast x to unsigned long first. However, then other compilers
+ * warn about applying unary minus to an unsigned operand. Hence the
+ * weird "0-".
+ */
+#define UNARY_NEG_WOULD_OVERFLOW(x) \
+ ((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))
+
+/* Return type of i_divmod */
+enum divmod_result {
+ DIVMOD_OK, /* Correct result */
+ DIVMOD_OVERFLOW, /* Overflow, try again using longs */
+ DIVMOD_ERROR /* Exception raised */
+};
+
+static enum divmod_result
+i_divmod(register long x, register long y,
+ long *p_xdivy, long *p_xmody)
+{
+ long xdivy, xmody;
+
+ if (y == 0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "integer division or modulo by zero");
+ return DIVMOD_ERROR;
+ }
+ /* (-sys.maxint-1)/-1 is the only overflow case. */
+ if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
+ return DIVMOD_OVERFLOW;
+ xdivy = x / y;
+ /* xdiv*y can overflow on platforms where x/y gives floor(x/y)
+ * for x and y with differing signs. (This is unusual
+ * behaviour, and C99 prohibits it, but it's allowed by C89;
+ * for an example of overflow, take x = LONG_MIN, y = 5 or x =
+ * LONG_MAX, y = -5.) However, x - xdivy*y is always
+ * representable as a long, since it lies strictly between
+ * -abs(y) and abs(y). We add casts to avoid intermediate
+ * overflow.
+ */
+ xmody = (long)(x - (unsigned long)xdivy * y);
+ /* If the signs of x and y differ, and the remainder is non-0,
+ * C89 doesn't define whether xdivy is now the floor or the
+ * ceiling of the infinitely precise quotient. We want the floor,
+ * and we have it iff the remainder's sign matches y's.
+ */
+ if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
+ xmody += y;
+ --xdivy;
+ assert(xmody && ((y ^ xmody) >= 0));
+ }
+ *p_xdivy = xdivy;
+ *p_xmody = xmody;
+ return DIVMOD_OK;
+}
+
+static PyObject *
+int_div(PyIntObject *x, PyIntObject *y)
+{
+ long xi, yi;
+ long d, m;
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ switch (i_divmod(xi, yi, &d, &m)) {
+ case DIVMOD_OK:
+ return PyInt_FromLong(d);
+ case DIVMOD_OVERFLOW:
+ return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+ (PyObject *)y);
+ default:
+ return NULL;
+ }
+}
+
+static PyObject *
+int_classic_div(PyIntObject *x, PyIntObject *y)
+{
+ long xi, yi;
+ long d, m;
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ if (Py_DivisionWarningFlag &&
+ PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0)
+ return NULL;
+ switch (i_divmod(xi, yi, &d, &m)) {
+ case DIVMOD_OK:
+ return PyInt_FromLong(d);
+ case DIVMOD_OVERFLOW:
+ return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
+ (PyObject *)y);
+ default:
+ return NULL;
+ }
+}
+
+static PyObject *
+int_true_divide(PyIntObject *x, PyIntObject *y)
+{
+ long xi, yi;
+ /* If they aren't both ints, give someone else a chance. In
+ particular, this lets int/long get handled by longs, which
+ underflows to 0 gracefully if the long is too big to convert
+ to float. */
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ if (yi == 0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "division by zero");
+ return NULL;
+ }
+ if (xi == 0)
+ return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0);
+
+#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
+#if DBL_MANT_DIG < WIDTH_OF_ULONG
+ if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG ||
+ (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG)
+ /* Large x or y. Use long integer arithmetic. */
+ return PyLong_Type.tp_as_number->nb_true_divide(
+ (PyObject *)x, (PyObject *)y);
+ else
+#endif
+ /* Both ints can be exactly represented as doubles. Do a
+ floating-point division. */
+ return PyFloat_FromDouble((double)xi / (double)yi);
+}
+
+static PyObject *
+int_mod(PyIntObject *x, PyIntObject *y)
+{
+ long xi, yi;
+ long d, m;
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ switch (i_divmod(xi, yi, &d, &m)) {
+ case DIVMOD_OK:
+ return PyInt_FromLong(m);
+ case DIVMOD_OVERFLOW:
+ return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
+ (PyObject *)y);
+ default:
+ return NULL;
+ }
+}
+
+static PyObject *
+int_divmod(PyIntObject *x, PyIntObject *y)
+{
+ long xi, yi;
+ long d, m;
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ switch (i_divmod(xi, yi, &d, &m)) {
+ case DIVMOD_OK:
+ return Py_BuildValue("(ll)", d, m);
+ case DIVMOD_OVERFLOW:
+ return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
+ (PyObject *)y);
+ default:
+ return NULL;
+ }
+}
+
+static PyObject *
+int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
+{
+ register long iv, iw, iz=0, ix, temp, prev;
+ CONVERT_TO_LONG(v, iv);
+ CONVERT_TO_LONG(w, iw);
+ if (iw < 0) {
+ if ((PyObject *)z != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+ "cannot be negative when 3rd argument specified");
+ return NULL;
+ }
+ /* Return a float. This works because we know that
+ this calls float_pow() which converts its
+ arguments to double. */
+ return PyFloat_Type.tp_as_number->nb_power(
+ (PyObject *)v, (PyObject *)w, (PyObject *)z);
+ }
+ if ((PyObject *)z != Py_None) {
+ CONVERT_TO_LONG(z, iz);
+ if (iz == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "pow() 3rd argument cannot be 0");
+ return NULL;
+ }
+ }
+ /*
+ * XXX: The original exponentiation code stopped looping
+ * when temp hit zero; this code will continue onwards
+ * unnecessarily, but at least it won't cause any errors.
+ * Hopefully the speed improvement from the fast exponentiation
+ * will compensate for the slight inefficiency.
+ * XXX: Better handling of overflows is desperately needed.
+ */
+ temp = iv;
+ ix = 1;
+ while (iw > 0) {
+ prev = ix; /* Save value for overflow check */
+ if (iw & 1) {
+ /*
+ * The (unsigned long) cast below ensures that the multiplication
+ * is interpreted as an unsigned operation rather than a signed one
+ * (C99 6.3.1.8p1), thus avoiding the perils of undefined behaviour
+ * from signed arithmetic overflow (C99 6.5p5). See issue #12973.
+ */
+ ix = (unsigned long)ix * temp;
+ if (temp == 0)
+ break; /* Avoid ix / 0 */
+ if (ix / temp != prev) {
+ return PyLong_Type.tp_as_number->nb_power(
+ (PyObject *)v,
+ (PyObject *)w,
+ (PyObject *)z);
+ }
+ }
+ iw >>= 1; /* Shift exponent down by 1 bit */
+ if (iw==0) break;
+ prev = temp;
+ temp = (unsigned long)temp * temp; /* Square the value of temp */
+ if (prev != 0 && temp / prev != prev) {
+ return PyLong_Type.tp_as_number->nb_power(
+ (PyObject *)v, (PyObject *)w, (PyObject *)z);
+ }
+ if (iz) {
+ /* If we did a multiplication, perform a modulo */
+ ix = ix % iz;
+ temp = temp % iz;
+ }
+ }
+ if (iz) {
+ long div, mod;
+ switch (i_divmod(ix, iz, &div, &mod)) {
+ case DIVMOD_OK:
+ ix = mod;
+ break;
+ case DIVMOD_OVERFLOW:
+ return PyLong_Type.tp_as_number->nb_power(
+ (PyObject *)v, (PyObject *)w, (PyObject *)z);
+ default:
+ return NULL;
+ }
+ }
+ return PyInt_FromLong(ix);
+}
+
+static PyObject *
+int_neg(PyIntObject *v)
+{
+ register long a;
+ a = v->ob_ival;
+ /* check for overflow */
+ if (UNARY_NEG_WOULD_OVERFLOW(a)) {
+ PyObject *o = PyLong_FromLong(a);
+ if (o != NULL) {
+ PyObject *result = PyNumber_Negative(o);
+ Py_DECREF(o);
+ return result;
+ }
+ return NULL;
+ }
+ return PyInt_FromLong(-a);
+}
+
+static PyObject *
+int_abs(PyIntObject *v)
+{
+ if (v->ob_ival >= 0)
+ return int_int(v);
+ else
+ return int_neg(v);
+}
+
+static int
+int_nonzero(PyIntObject *v)
+{
+ return v->ob_ival != 0;
+}
+
+static PyObject *
+int_invert(PyIntObject *v)
+{
+ return PyInt_FromLong(~v->ob_ival);
+}
+
+static PyObject *
+int_lshift(PyIntObject *v, PyIntObject *w)
+{
+ long a, b, c;
+ PyObject *vv, *ww, *result;
+
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ if (b < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative shift count");
+ return NULL;
+ }
+ if (a == 0 || b == 0)
+ return int_int(v);
+ if (b >= LONG_BIT) {
+ vv = PyLong_FromLong(PyInt_AS_LONG(v));
+ if (vv == NULL)
+ return NULL;
+ ww = PyLong_FromLong(PyInt_AS_LONG(w));
+ if (ww == NULL) {
+ Py_DECREF(vv);
+ return NULL;
+ }
+ result = PyNumber_Lshift(vv, ww);
+ Py_DECREF(vv);
+ Py_DECREF(ww);
+ return result;
+ }
+ c = a << b;
+ if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
+ vv = PyLong_FromLong(PyInt_AS_LONG(v));
+ if (vv == NULL)
+ return NULL;
+ ww = PyLong_FromLong(PyInt_AS_LONG(w));
+ if (ww == NULL) {
+ Py_DECREF(vv);
+ return NULL;
+ }
+ result = PyNumber_Lshift(vv, ww);
+ Py_DECREF(vv);
+ Py_DECREF(ww);
+ return result;
+ }
+ return PyInt_FromLong(c);
+}
+
+static PyObject *
+int_rshift(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ if (b < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative shift count");
+ return NULL;
+ }
+ if (a == 0 || b == 0)
+ return int_int(v);
+ if (b >= LONG_BIT) {
+ if (a < 0)
+ a = -1;
+ else
+ a = 0;
+ }
+ else {
+ a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
+ }
+ return PyInt_FromLong(a);
+}
+
+static PyObject *
+int_and(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ return PyInt_FromLong(a & b);
+}
+
+static PyObject *
+int_xor(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ return PyInt_FromLong(a ^ b);
+}
+
+static PyObject *
+int_or(PyIntObject *v, PyIntObject *w)
+{
+ register long a, b;
+ CONVERT_TO_LONG(v, a);
+ CONVERT_TO_LONG(w, b);
+ return PyInt_FromLong(a | b);
+}
+
+static int
+int_coerce(PyObject **pv, PyObject **pw)
+{
+ if (PyInt_Check(*pw)) {
+ Py_INCREF(*pv);
+ Py_INCREF(*pw);
+ return 0;
+ }
+ return 1; /* Can't do it */
+}
+
+static PyObject *
+int_int(PyIntObject *v)
+{
+ if (PyInt_CheckExact(v))
+ Py_INCREF(v);
+ else
+ v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
+ return (PyObject *)v;
+}
+
+static PyObject *
+int_long(PyIntObject *v)
+{
+ return PyLong_FromLong((v -> ob_ival));
+}
+
+static const unsigned char BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_ulong(unsigned long d)
+{
+ int d_bits = 0;
+ while (d >= 32) {
+ d_bits += 6;
+ d >>= 6;
+ }
+ d_bits += (int)BitLengthTable[d];
+ return d_bits;
+}
+
+#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG
+/* Every Python int can be exactly represented as a float. */
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+ return PyFloat_FromDouble((double)(v -> ob_ival));
+}
+
+#else
+/* Here not all Python ints are exactly representable as floats, so we may
+ have to round. We do this manually, since the C standards don't specify
+ whether converting an integer to a float rounds up or down */
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+ unsigned long abs_ival, lsb;
+ int round_up;
+
+ if (v->ob_ival < 0)
+ abs_ival = 0U-(unsigned long)v->ob_ival;
+ else
+ abs_ival = (unsigned long)v->ob_ival;
+ if (abs_ival < (1L << DBL_MANT_DIG))
+ /* small integer; no need to round */
+ return PyFloat_FromDouble((double)v->ob_ival);
+
+ /* Round abs_ival to MANT_DIG significant bits, using the
+ round-half-to-even rule. abs_ival & lsb picks out the 'rounding'
+ bit: the first bit after the most significant MANT_DIG bits of
+ abs_ival. We round up if this bit is set, provided that either:
+
+ (1) abs_ival isn't exactly halfway between two floats, in which
+ case at least one of the bits following the rounding bit must be
+ set; i.e., abs_ival & lsb-1 != 0, or:
+
+ (2) the resulting rounded value has least significant bit 0; or
+ in other words the bit above the rounding bit is set (this is the
+ 'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0
+
+ The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */
+
+ lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1);
+ round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1));
+ abs_ival &= -2*lsb;
+ if (round_up)
+ abs_ival += 2*lsb;
+ return PyFloat_FromDouble(v->ob_ival < 0 ?
+ -(double)abs_ival :
+ (double)abs_ival);
+}
+
+#endif
+
+static PyObject *
+int_oct(PyIntObject *v)
+{
+ return _PyInt_Format(v, 8, 0);
+}
+
+static PyObject *
+int_hex(PyIntObject *v)
+{
+ return _PyInt_Format(v, 16, 0);
+}
+
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *x = NULL;
+ int base = -909;
+ static char *kwlist[] = {"x", "base", 0};
+
+ if (type != &PyInt_Type)
+ return int_subtype_new(type, args, kwds); /* Wimp out */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
+ &x, &base))
+ return NULL;
+ if (x == NULL) {
+ if (base != -909) {
+ PyErr_SetString(PyExc_TypeError,
+ "int() missing string argument");
+ return NULL;
+ }
+ return PyInt_FromLong(0L);
+ }
+ if (base == -909)
+ return PyNumber_Int(x);
+ if (PyString_Check(x)) {
+ /* Since PyInt_FromString doesn't have a length parameter,
+ * check here for possible NULs in the string. */
+ char *string = PyString_AS_STRING(x);
+ if (strlen(string) != PyString_Size(x)) {
+ /* create a repr() of the input string,
+ * just like PyInt_FromString does */
+ PyObject *srepr;
+ srepr = PyObject_Repr(x);
+ if (srepr == NULL)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "invalid literal for int() with base %d: %s",
+ base, PyString_AS_STRING(srepr));
+ Py_DECREF(srepr);
+ return NULL;
+ }
+ return PyInt_FromString(string, NULL, base);
+ }
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(x))
+ return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
+ PyUnicode_GET_SIZE(x),
+ base);
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "int() can't convert non-string with explicit base");
+ return NULL;
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of int:
+ first create a regular int from whatever arguments we got,
+ then allocate a subtype instance and initialize its ob_ival
+ from the regular int. The regular int is then thrown away.
+*/
+static PyObject *
+int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *tmp, *newobj;
+ long ival;
+
+ assert(PyType_IsSubtype(type, &PyInt_Type));
+ tmp = int_new(&PyInt_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ if (!PyInt_Check(tmp)) {
+ ival = PyLong_AsLong(tmp);
+ if (ival == -1 && PyErr_Occurred()) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ } else {
+ ival = ((PyIntObject *)tmp)->ob_ival;
+ }
+
+ newobj = type->tp_alloc(type, 0);
+ if (newobj == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ ((PyIntObject *)newobj)->ob_ival = ival;
+ Py_DECREF(tmp);
+ return newobj;
+}
+
+static PyObject *
+int_getnewargs(PyIntObject *v)
+{
+ return Py_BuildValue("(l)", v->ob_ival);
+}
+
+static PyObject *
+int_get0(PyIntObject *v, void *context) {
+ return PyInt_FromLong(0L);
+}
+
+static PyObject *
+int_get1(PyIntObject *v, void *context) {
+ return PyInt_FromLong(1L);
+}
+
+/* Convert an integer to a decimal string. On many platforms, this
+ will be significantly faster than the general arbitrary-base
+ conversion machinery in _PyInt_Format, thanks to optimization
+ opportunities offered by division by a compile-time constant. */
+static PyObject *
+int_to_decimal_string(PyIntObject *v) {
+ char buf[sizeof(long)*CHAR_BIT/3+6], *p, *bufend;
+ long n = v->ob_ival;
+ unsigned long absn;
+ p = bufend = buf + sizeof(buf);
+ absn = n < 0 ? 0UL - n : n;
+ do {
+ *--p = '0' + (char)(absn % 10);
+ absn /= 10;
+ } while (absn);
+ if (n < 0)
+ *--p = '-';
+ return PyString_FromStringAndSize(p, bufend - p);
+}
+
+/* Convert an integer to the given base. Returns a string.
+ If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'.
+ If newstyle is zero, then use the pre-2.6 behavior of octal having
+ a leading "0" */
+PyAPI_FUNC(PyObject*)
+_PyInt_Format(PyIntObject *v, int base, int newstyle)
+{
+ /* There are no doubt many, many ways to optimize this, using code
+ similar to _PyLong_Format */
+ long n = v->ob_ival;
+ int negative = n < 0;
+ int is_zero = n == 0;
+
+ /* For the reasoning behind this size, see
+ http://c-faq.com/misc/hexio.html. Then, add a few bytes for
+ the possible sign and prefix "0[box]" */
+ char buf[sizeof(n)*CHAR_BIT+6];
+
+ /* Start by pointing to the end of the buffer. We fill in from
+ the back forward. */
+ char* p = &buf[sizeof(buf)];
+
+ assert(base >= 2 && base <= 36);
+
+ /* Special case base 10, for speed */
+ if (base == 10)
+ return int_to_decimal_string(v);
+
+ do {
+ /* I'd use i_divmod, except it doesn't produce the results
+ I want when n is negative. So just duplicate the salient
+ part here. */
+ long div = n / base;
+ long mod = n - div * base;
+
+ /* convert abs(mod) to the right character in [0-9, a-z] */
+ char cdigit = (char)(mod < 0 ? -mod : mod);
+ cdigit += (cdigit < 10) ? '0' : 'a'-10;
+ *--p = cdigit;
+
+ n = div;
+ } while(n);
+
+ if (base == 2) {
+ *--p = 'b';
+ *--p = '0';
+ }
+ else if (base == 8) {
+ if (newstyle) {
+ *--p = 'o';
+ *--p = '0';
+ }
+ else
+ if (!is_zero)
+ *--p = '0';
+ }
+ else if (base == 16) {
+ *--p = 'x';
+ *--p = '0';
+ }
+ else {
+ *--p = '#';
+ *--p = '0' + base%10;
+ if (base > 10)
+ *--p = '0' + base/10;
+ }
+ if (negative)
+ *--p = '-';
+
+ return PyString_FromStringAndSize(p, &buf[sizeof(buf)] - p);
+}
+
+static PyObject *
+int__format__(PyObject *self, PyObject *args)
+{
+ PyObject *format_spec;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+ if (PyBytes_Check(format_spec))
+ return _PyInt_FormatAdvanced(self,
+ PyBytes_AS_STRING(format_spec),
+ PyBytes_GET_SIZE(format_spec));
+ if (PyUnicode_Check(format_spec)) {
+ /* Convert format_spec to a str */
+ PyObject *result;
+ PyObject *str_spec = PyObject_Str(format_spec);
+
+ if (str_spec == NULL)
+ return NULL;
+
+ result = _PyInt_FormatAdvanced(self,
+ PyBytes_AS_STRING(str_spec),
+ PyBytes_GET_SIZE(str_spec));
+
+ Py_DECREF(str_spec);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+ return NULL;
+}
+
+static PyObject *
+int_bit_length(PyIntObject *v)
+{
+ unsigned long n;
+
+ if (v->ob_ival < 0)
+ /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */
+ n = 0U-(unsigned long)v->ob_ival;
+ else
+ n = (unsigned long)v->ob_ival;
+
+ return PyInt_FromLong(bits_in_ulong(n));
+}
+
+PyDoc_STRVAR(int_bit_length_doc,
+"int.bit_length() -> int\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37)\n\
+'0b100101'\n\
+>>> (37).bit_length()\n\
+6");
+
+#if 0
+static PyObject *
+int_is_finite(PyObject *v)
+{
+ Py_RETURN_TRUE;
+}
+#endif
+
+static PyMethodDef int_methods[] = {
+ {"conjugate", (PyCFunction)int_int, METH_NOARGS,
+ "Returns self, the complex conjugate of any int."},
+ {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS,
+ int_bit_length_doc},
+#if 0
+ {"is_finite", (PyCFunction)int_is_finite, METH_NOARGS,
+ "Returns always True."},
+#endif
+ {"__trunc__", (PyCFunction)int_int, METH_NOARGS,
+ "Truncating an Integral returns itself."},
+ {"__getnewargs__", (PyCFunction)int_getnewargs, METH_NOARGS},
+ {"__format__", (PyCFunction)int__format__, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyGetSetDef int_getset[] = {
+ {"real",
+ (getter)int_int, (setter)NULL,
+ "the real part of a complex number",
+ NULL},
+ {"imag",
+ (getter)int_get0, (setter)NULL,
+ "the imaginary part of a complex number",
+ NULL},
+ {"numerator",
+ (getter)int_int, (setter)NULL,
+ "the numerator of a rational number in lowest terms",
+ NULL},
+ {"denominator",
+ (getter)int_get1, (setter)NULL,
+ "the denominator of a rational number in lowest terms",
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(int_doc,
+"int(x=0) -> int or long\n\
+int(x, base=10) -> int or long\n\
+\n\
+Convert a number or string to an integer, or return 0 if no arguments\n\
+are given. If x is floating point, the conversion truncates towards zero.\n\
+If x is outside the integer range, the function returns a long instead.\n\
+\n\
+If x is not a number or if base is given, then x must be a string or\n\
+Unicode object representing an integer literal in the given base. The\n\
+literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
+The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to\n\
+interpret the base from the string as an integer literal.\n\
+>>> int('0b100', base=0)\n\
+4");
+
+static PyNumberMethods int_as_number = {
+ (binaryfunc)int_add, /*nb_add*/
+ (binaryfunc)int_sub, /*nb_subtract*/
+ (binaryfunc)int_mul, /*nb_multiply*/
+ (binaryfunc)int_classic_div, /*nb_divide*/
+ (binaryfunc)int_mod, /*nb_remainder*/
+ (binaryfunc)int_divmod, /*nb_divmod*/
+ (ternaryfunc)int_pow, /*nb_power*/
+ (unaryfunc)int_neg, /*nb_negative*/
+ (unaryfunc)int_int, /*nb_positive*/
+ (unaryfunc)int_abs, /*nb_absolute*/
+ (inquiry)int_nonzero, /*nb_nonzero*/
+ (unaryfunc)int_invert, /*nb_invert*/
+ (binaryfunc)int_lshift, /*nb_lshift*/
+ (binaryfunc)int_rshift, /*nb_rshift*/
+ (binaryfunc)int_and, /*nb_and*/
+ (binaryfunc)int_xor, /*nb_xor*/
+ (binaryfunc)int_or, /*nb_or*/
+ int_coerce, /*nb_coerce*/
+ (unaryfunc)int_int, /*nb_int*/
+ (unaryfunc)int_long, /*nb_long*/
+ (unaryfunc)int_float, /*nb_float*/
+ (unaryfunc)int_oct, /*nb_oct*/
+ (unaryfunc)int_hex, /*nb_hex*/
+ 0, /*nb_inplace_add*/
+ 0, /*nb_inplace_subtract*/
+ 0, /*nb_inplace_multiply*/
+ 0, /*nb_inplace_divide*/
+ 0, /*nb_inplace_remainder*/
+ 0, /*nb_inplace_power*/
+ 0, /*nb_inplace_lshift*/
+ 0, /*nb_inplace_rshift*/
+ 0, /*nb_inplace_and*/
+ 0, /*nb_inplace_xor*/
+ 0, /*nb_inplace_or*/
+ (binaryfunc)int_div, /* nb_floor_divide */
+ (binaryfunc)int_true_divide, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+ (unaryfunc)int_int, /* nb_index */
+};
+
+PyTypeObject PyInt_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "int",
+ sizeof(PyIntObject),
+ 0,
+ (destructor)int_dealloc, /* tp_dealloc */
+ (printfunc)int_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)int_compare, /* tp_compare */
+ (reprfunc)int_to_decimal_string, /* tp_repr */
+ &int_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)int_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)int_to_decimal_string, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS, /* tp_flags */
+ int_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ int_methods, /* tp_methods */
+ 0, /* tp_members */
+ int_getset, /* 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 */
+ int_new, /* tp_new */
+ (freefunc)int_free, /* tp_free */
+};
+
+int
+_PyInt_Init(void)
+{
+ PyIntObject *v;
+ int ival;
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
+ if (!free_list && (free_list = fill_free_list()) == NULL)
+ return 0;
+ /* PyObject_New is inlined */
+ v = free_list;
+ free_list = (PyIntObject *)Py_TYPE(v);
+ PyObject_INIT(v, &PyInt_Type);
+ v->ob_ival = ival;
+ small_ints[ival + NSMALLNEGINTS] = v;
+ }
+#endif
+ return 1;
+}
+
+int
+PyInt_ClearFreeList(void)
+{
+ PyIntObject *p;
+ PyIntBlock *list, *next;
+ int i;
+ int u; /* remaining unfreed ints per block */
+ int freelist_size = 0;
+
+ list = block_list;
+ block_list = NULL;
+ free_list = NULL;
+ while (list != NULL) {
+ u = 0;
+ for (i = 0, p = &list->objects[0];
+ i < N_INTOBJECTS;
+ i++, p++) {
+ if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+ u++;
+ }
+ next = list->next;
+ if (u) {
+ list->next = block_list;
+ block_list = list;
+ for (i = 0, p = &list->objects[0];
+ i < N_INTOBJECTS;
+ i++, p++) {
+ if (!PyInt_CheckExact(p) ||
+ p->ob_refcnt == 0) {
+ Py_TYPE(p) = (struct _typeobject *)
+ free_list;
+ free_list = p;
+ }
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ else if (-NSMALLNEGINTS <= p->ob_ival &&
+ p->ob_ival < NSMALLPOSINTS &&
+ small_ints[p->ob_ival +
+ NSMALLNEGINTS] == NULL) {
+ Py_INCREF(p);
+ small_ints[p->ob_ival +
+ NSMALLNEGINTS] = p;
+ }
+#endif
+ }
+ }
+ else {
+ PyMem_FREE(list);
+ }
+ freelist_size += u;
+ list = next;
+ }
+
+ return freelist_size;
+}
+
+void
+PyInt_Fini(void)
+{
+ PyIntObject *p;
+ PyIntBlock *list;
+ int i;
+ int u; /* total unfreed ints per block */
+
+#if NSMALLNEGINTS + NSMALLPOSINTS > 0
+ PyIntObject **q;
+
+ i = NSMALLNEGINTS + NSMALLPOSINTS;
+ q = small_ints;
+ while (--i >= 0) {
+ Py_XDECREF(*q);
+ *q++ = NULL;
+ }
+#endif
+ u = PyInt_ClearFreeList();
+ if (!Py_VerboseFlag)
+ return;
+ fprintf(stderr, "# cleanup ints");
+ if (!u) {
+ fprintf(stderr, "\n");
+ }
+ else {
+ fprintf(stderr,
+ ": %d unfreed int%s\n",
+ u, u == 1 ? "" : "s");
+ }
+ if (Py_VerboseFlag > 1) {
+ list = block_list;
+ while (list != NULL) {
+ for (i = 0, p = &list->objects[0];
+ i < N_INTOBJECTS;
+ i++, p++) {
+ if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
+ /* XXX(twouters) cast refcount to
+ long until %zd is universally
+ available
+ */
+ fprintf(stderr,
+ "# <int at %p, refcnt=%ld, val=%ld>\n",
+ p, (long)p->ob_refcnt,
+ p->ob_ival);
+ }
+ list = list->next;
+ }
+ }
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/iterobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/iterobject.c
new file mode 100644
index 0000000000..529b5939cd
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/iterobject.c
@@ -0,0 +1,230 @@
+/* Iterator objects */
+
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ long it_index;
+ PyObject *it_seq; /* Set to NULL when iterator is exhausted */
+} seqiterobject;
+
+PyObject *
+PySeqIter_New(PyObject *seq)
+{
+ seqiterobject *it;
+
+ if (!PySequence_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
+ if (it == NULL)
+ return NULL;
+ it->it_index = 0;
+ Py_INCREF(seq);
+ it->it_seq = seq;
+ _PyObject_GC_TRACK(it);
+ return (PyObject *)it;
+}
+
+static void
+iter_dealloc(seqiterobject *it)
+{
+ _PyObject_GC_UNTRACK(it);
+ Py_XDECREF(it->it_seq);
+ PyObject_GC_Del(it);
+}
+
+static int
+iter_traverse(seqiterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_seq);
+ return 0;
+}
+
+static PyObject *
+iter_iternext(PyObject *iterator)
+{
+ seqiterobject *it;
+ PyObject *seq;
+ PyObject *result;
+
+ assert(PySeqIter_Check(iterator));
+ it = (seqiterobject *)iterator;
+ seq = it->it_seq;
+ if (seq == NULL)
+ return NULL;
+
+ result = PySequence_GetItem(seq, it->it_index);
+ if (result != NULL) {
+ it->it_index++;
+ return result;
+ }
+ if (PyErr_ExceptionMatches(PyExc_IndexError) ||
+ PyErr_ExceptionMatches(PyExc_StopIteration))
+ {
+ PyErr_Clear();
+ Py_DECREF(seq);
+ it->it_seq = NULL;
+ }
+ return NULL;
+}
+
+static PyObject *
+iter_len(seqiterobject *it)
+{
+ Py_ssize_t seqsize, len;
+
+ if (it->it_seq) {
+ seqsize = PySequence_Size(it->it_seq);
+ if (seqsize == -1)
+ return NULL;
+ len = seqsize - it->it_index;
+ if (len >= 0)
+ return PyInt_FromSsize_t(len);
+ }
+ return PyInt_FromLong(0);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef seqiter_methods[] = {
+ {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PySeqIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "iterator", /* tp_name */
+ sizeof(seqiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)iter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)iter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ iter_iternext, /* tp_iternext */
+ seqiter_methods, /* tp_methods */
+ 0, /* tp_members */
+};
+
+/* -------------------------------------- */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *it_callable; /* Set to NULL when iterator is exhausted */
+ PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
+} calliterobject;
+
+PyObject *
+PyCallIter_New(PyObject *callable, PyObject *sentinel)
+{
+ calliterobject *it;
+ it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
+ if (it == NULL)
+ return NULL;
+ Py_INCREF(callable);
+ it->it_callable = callable;
+ Py_INCREF(sentinel);
+ it->it_sentinel = sentinel;
+ _PyObject_GC_TRACK(it);
+ return (PyObject *)it;
+}
+static void
+calliter_dealloc(calliterobject *it)
+{
+ _PyObject_GC_UNTRACK(it);
+ Py_XDECREF(it->it_callable);
+ Py_XDECREF(it->it_sentinel);
+ PyObject_GC_Del(it);
+}
+
+static int
+calliter_traverse(calliterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_callable);
+ Py_VISIT(it->it_sentinel);
+ return 0;
+}
+
+static PyObject *
+calliter_iternext(calliterobject *it)
+{
+ if (it->it_callable != NULL) {
+ PyObject *args = PyTuple_New(0);
+ PyObject *result;
+ if (args == NULL)
+ return NULL;
+ result = PyObject_Call(it->it_callable, args, NULL);
+ Py_DECREF(args);
+ if (result != NULL) {
+ int ok;
+ ok = PyObject_RichCompareBool(result,
+ it->it_sentinel,
+ Py_EQ);
+ if (ok == 0)
+ return result; /* Common case, fast path */
+ Py_DECREF(result);
+ if (ok > 0) {
+ Py_CLEAR(it->it_callable);
+ Py_CLEAR(it->it_sentinel);
+ }
+ }
+ else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+ PyErr_Clear();
+ Py_CLEAR(it->it_callable);
+ Py_CLEAR(it->it_sentinel);
+ }
+ }
+ return NULL;
+}
+
+PyTypeObject PyCallIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "callable-iterator", /* tp_name */
+ sizeof(calliterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)calliter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)calliter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)calliter_iternext, /* tp_iternext */
+ 0, /* tp_methods */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c
new file mode 100644
index 0000000000..221bce20d5
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/listobject.c
@@ -0,0 +1,3045 @@
+/* List object implementation */
+
+#include "Python.h"
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else
+#include <sys/types.h> /* For size_t */
+#endif
+
+/* Ensure ob_item has room for at least newsize elements, and set
+ * ob_size to newsize. If newsize > ob_size on entry, the content
+ * of the new slots at exit is undefined heap trash; it's the caller's
+ * responsibility to overwrite them with sane values.
+ * The number of allocated elements may grow, shrink, or stay the same.
+ * Failure is impossible if newsize <= self.allocated on entry, although
+ * that partly relies on an assumption that the system realloc() never
+ * fails when passed a number of bytes <= the number of bytes last
+ * allocated (the C standard doesn't guarantee this, but it's hard to
+ * imagine a realloc implementation where it wouldn't be true).
+ * Note that self->ob_item may change, and even if newsize is less
+ * than ob_size on entry.
+ */
+static int
+list_resize(PyListObject *self, Py_ssize_t newsize)
+{
+ PyObject **items;
+ size_t new_allocated;
+ Py_ssize_t allocated = self->allocated;
+
+ /* Bypass realloc() when a previous overallocation is large enough
+ to accommodate the newsize. If the newsize falls lower than half
+ the allocated size, then proceed with the realloc() to shrink the list.
+ */
+ if (allocated >= newsize && newsize >= (allocated >> 1)) {
+ assert(self->ob_item != NULL || newsize == 0);
+ Py_SIZE(self) = newsize;
+ return 0;
+ }
+
+ /* This over-allocates proportional to the list size, making room
+ * for additional growth. The over-allocation is mild, but is
+ * enough to give linear-time amortized behavior over a long
+ * sequence of appends() in the presence of a poorly-performing
+ * system realloc().
+ * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
+ */
+ new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
+
+ /* check for integer overflow */
+ if (new_allocated > PY_SIZE_MAX - newsize) {
+ PyErr_NoMemory();
+ return -1;
+ } else {
+ new_allocated += newsize;
+ }
+
+ if (newsize == 0)
+ new_allocated = 0;
+ items = self->ob_item;
+ if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *)))
+ PyMem_RESIZE(items, PyObject *, new_allocated);
+ else
+ items = NULL;
+ if (items == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->ob_item = items;
+ Py_SIZE(self) = newsize;
+ self->allocated = new_allocated;
+ return 0;
+}
+
+/* Debug statistic to compare allocations with reuse through the free list */
+#undef SHOW_ALLOC_COUNT
+#ifdef SHOW_ALLOC_COUNT
+static size_t count_alloc = 0;
+static size_t count_reuse = 0;
+
+static void
+show_alloc(void)
+{
+ fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n",
+ count_alloc);
+ fprintf(stderr, "List reuse through freelist: %" PY_FORMAT_SIZE_T
+ "d\n", count_reuse);
+ fprintf(stderr, "%.2f%% reuse rate\n\n",
+ (100.0*count_reuse/(count_alloc+count_reuse)));
+}
+#endif
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#ifndef PyList_MAXFREELIST
+#define PyList_MAXFREELIST 80
+#endif
+static PyListObject *free_list[PyList_MAXFREELIST];
+static int numfree = 0;
+
+void
+PyList_Fini(void)
+{
+ PyListObject *op;
+
+ while (numfree) {
+ op = free_list[--numfree];
+ assert(PyList_CheckExact(op));
+ PyObject_GC_Del(op);
+ }
+}
+
+PyObject *
+PyList_New(Py_ssize_t size)
+{
+ PyListObject *op;
+ size_t nbytes;
+#ifdef SHOW_ALLOC_COUNT
+ static int initialized = 0;
+ if (!initialized) {
+ Py_AtExit(show_alloc);
+ initialized = 1;
+ }
+#endif
+
+ if (size < 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ /* Check for overflow without an actual overflow,
+ * which can cause compiler to optimise out */
+ if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *))
+ return PyErr_NoMemory();
+ nbytes = size * sizeof(PyObject *);
+ if (numfree) {
+ numfree--;
+ op = free_list[numfree];
+ _Py_NewReference((PyObject *)op);
+#ifdef SHOW_ALLOC_COUNT
+ count_reuse++;
+#endif
+ } else {
+ op = PyObject_GC_New(PyListObject, &PyList_Type);
+ if (op == NULL)
+ return NULL;
+#ifdef SHOW_ALLOC_COUNT
+ count_alloc++;
+#endif
+ }
+ if (size <= 0)
+ op->ob_item = NULL;
+ else {
+ op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);
+ if (op->ob_item == NULL) {
+ Py_DECREF(op);
+ return PyErr_NoMemory();
+ }
+ memset(op->ob_item, 0, nbytes);
+ }
+ Py_SIZE(op) = size;
+ op->allocated = size;
+ _PyObject_GC_TRACK(op);
+ return (PyObject *) op;
+}
+
+Py_ssize_t
+PyList_Size(PyObject *op)
+{
+ if (!PyList_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ else
+ return Py_SIZE(op);
+}
+
+static PyObject *indexerr = NULL;
+
+PyObject *
+PyList_GetItem(PyObject *op, Py_ssize_t i)
+{
+ if (!PyList_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (i < 0 || i >= Py_SIZE(op)) {
+ if (indexerr == NULL) {
+ indexerr = PyString_FromString(
+ "list index out of range");
+ if (indexerr == NULL)
+ return NULL;
+ }
+ PyErr_SetObject(PyExc_IndexError, indexerr);
+ return NULL;
+ }
+ return ((PyListObject *)op) -> ob_item[i];
+}
+
+int
+PyList_SetItem(register PyObject *op, register Py_ssize_t i,
+ register PyObject *newitem)
+{
+ register PyObject *olditem;
+ register PyObject **p;
+ if (!PyList_Check(op)) {
+ Py_XDECREF(newitem);
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (i < 0 || i >= Py_SIZE(op)) {
+ Py_XDECREF(newitem);
+ PyErr_SetString(PyExc_IndexError,
+ "list assignment index out of range");
+ return -1;
+ }
+ p = ((PyListObject *)op) -> ob_item + i;
+ olditem = *p;
+ *p = newitem;
+ Py_XDECREF(olditem);
+ return 0;
+}
+
+static int
+ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
+{
+ Py_ssize_t i, n = Py_SIZE(self);
+ PyObject **items;
+ if (v == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (n == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot add more objects to list");
+ return -1;
+ }
+
+ if (list_resize(self, n+1) == -1)
+ return -1;
+
+ if (where < 0) {
+ where += n;
+ if (where < 0)
+ where = 0;
+ }
+ if (where > n)
+ where = n;
+ items = self->ob_item;
+ for (i = n; --i >= where; )
+ items[i+1] = items[i];
+ Py_INCREF(v);
+ items[where] = v;
+ return 0;
+}
+
+int
+PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
+{
+ if (!PyList_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return ins1((PyListObject *)op, where, newitem);
+}
+
+static int
+app1(PyListObject *self, PyObject *v)
+{
+ Py_ssize_t n = PyList_GET_SIZE(self);
+
+ assert (v != NULL);
+ if (n == PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot add more objects to list");
+ return -1;
+ }
+
+ if (list_resize(self, n+1) == -1)
+ return -1;
+
+ Py_INCREF(v);
+ PyList_SET_ITEM(self, n, v);
+ return 0;
+}
+
+int
+PyList_Append(PyObject *op, PyObject *newitem)
+{
+ if (PyList_Check(op) && (newitem != NULL))
+ return app1((PyListObject *)op, newitem);
+ PyErr_BadInternalCall();
+ return -1;
+}
+
+/* Methods */
+
+static void
+list_dealloc(PyListObject *op)
+{
+ Py_ssize_t i;
+ PyObject_GC_UnTrack(op);
+ Py_TRASHCAN_SAFE_BEGIN(op)
+ if (op->ob_item != NULL) {
+ /* Do it backwards, for Christian Tismer.
+ There's a simple test case where somehow this reduces
+ thrashing when a *very* large list is created and
+ immediately deleted. */
+ i = Py_SIZE(op);
+ while (--i >= 0) {
+ Py_XDECREF(op->ob_item[i]);
+ }
+ PyMem_FREE(op->ob_item);
+ }
+ if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
+ free_list[numfree++] = op;
+ else
+ Py_TYPE(op)->tp_free((PyObject *)op);
+ Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+list_print(PyListObject *op, FILE *fp, int flags)
+{
+ int rc;
+ Py_ssize_t i;
+ PyObject *item;
+
+ rc = Py_ReprEnter((PyObject*)op);
+ if (rc != 0) {
+ if (rc < 0)
+ return rc;
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "[...]");
+ Py_END_ALLOW_THREADS
+ return 0;
+ }
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "[");
+ Py_END_ALLOW_THREADS
+ for (i = 0; i < Py_SIZE(op); i++) {
+ item = op->ob_item[i];
+ Py_INCREF(item);
+ if (i > 0) {
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, ", ");
+ Py_END_ALLOW_THREADS
+ }
+ if (PyObject_Print(item, fp, 0) != 0) {
+ Py_DECREF(item);
+ Py_ReprLeave((PyObject *)op);
+ return -1;
+ }
+ Py_DECREF(item);
+ }
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "]");
+ Py_END_ALLOW_THREADS
+ Py_ReprLeave((PyObject *)op);
+ return 0;
+}
+
+static PyObject *
+list_repr(PyListObject *v)
+{
+ Py_ssize_t i;
+ PyObject *s, *temp;
+ PyObject *pieces = NULL, *result = NULL;
+
+ i = Py_ReprEnter((PyObject*)v);
+ if (i != 0) {
+ return i > 0 ? PyString_FromString("[...]") : NULL;
+ }
+
+ if (Py_SIZE(v) == 0) {
+ result = PyString_FromString("[]");
+ goto Done;
+ }
+
+ pieces = PyList_New(0);
+ if (pieces == NULL)
+ goto Done;
+
+ /* Do repr() on each element. Note that this may mutate the list,
+ so must refetch the list size on each iteration. */
+ for (i = 0; i < Py_SIZE(v); ++i) {
+ int status;
+ if (Py_EnterRecursiveCall(" while getting the repr of a list"))
+ goto Done;
+ s = PyObject_Repr(v->ob_item[i]);
+ Py_LeaveRecursiveCall();
+ if (s == NULL)
+ goto Done;
+ status = PyList_Append(pieces, s);
+ Py_DECREF(s); /* append created a new ref */
+ if (status < 0)
+ goto Done;
+ }
+
+ /* Add "[]" decorations to the first and last items. */
+ assert(PyList_GET_SIZE(pieces) > 0);
+ s = PyString_FromString("[");
+ if (s == NULL)
+ goto Done;
+ temp = PyList_GET_ITEM(pieces, 0);
+ PyString_ConcatAndDel(&s, temp);
+ PyList_SET_ITEM(pieces, 0, s);
+ if (s == NULL)
+ goto Done;
+
+ s = PyString_FromString("]");
+ if (s == NULL)
+ goto Done;
+ temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
+ PyString_ConcatAndDel(&temp, s);
+ PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
+ if (temp == NULL)
+ goto Done;
+
+ /* Paste them all together with ", " between. */
+ s = PyString_FromString(", ");
+ if (s == NULL)
+ goto Done;
+ result = _PyString_Join(s, pieces);
+ Py_DECREF(s);
+
+Done:
+ Py_XDECREF(pieces);
+ Py_ReprLeave((PyObject *)v);
+ return result;
+}
+
+static Py_ssize_t
+list_length(PyListObject *a)
+{
+ return Py_SIZE(a);
+}
+
+static int
+list_contains(PyListObject *a, PyObject *el)
+{
+ Py_ssize_t i;
+ int cmp;
+
+ for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
+ cmp = PyObject_RichCompareBool(el, PyList_GET_ITEM(a, i),
+ Py_EQ);
+ return cmp;
+}
+
+static PyObject *
+list_item(PyListObject *a, Py_ssize_t i)
+{
+ if (i < 0 || i >= Py_SIZE(a)) {
+ if (indexerr == NULL) {
+ indexerr = PyString_FromString(
+ "list index out of range");
+ if (indexerr == NULL)
+ return NULL;
+ }
+ PyErr_SetObject(PyExc_IndexError, indexerr);
+ return NULL;
+ }
+ Py_INCREF(a->ob_item[i]);
+ return a->ob_item[i];
+}
+
+static PyObject *
+list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ PyListObject *np;
+ PyObject **src, **dest;
+ Py_ssize_t i, len;
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > Py_SIZE(a))
+ ilow = Py_SIZE(a);
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > Py_SIZE(a))
+ ihigh = Py_SIZE(a);
+ len = ihigh - ilow;
+ np = (PyListObject *) PyList_New(len);
+ if (np == NULL)
+ return NULL;
+
+ src = a->ob_item + ilow;
+ dest = np->ob_item;
+ for (i = 0; i < len; i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ return (PyObject *)np;
+}
+
+PyObject *
+PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
+{
+ if (!PyList_Check(a)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return list_slice((PyListObject *)a, ilow, ihigh);
+}
+
+static PyObject *
+list_concat(PyListObject *a, PyObject *bb)
+{
+ Py_ssize_t size;
+ Py_ssize_t i;
+ PyObject **src, **dest;
+ PyListObject *np;
+ if (!PyList_Check(bb)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only concatenate list (not \"%.200s\") to list",
+ bb->ob_type->tp_name);
+ return NULL;
+ }
+#define b ((PyListObject *)bb)
+ size = Py_SIZE(a) + Py_SIZE(b);
+ if (size < 0)
+ return PyErr_NoMemory();
+ np = (PyListObject *) PyList_New(size);
+ if (np == NULL) {
+ return NULL;
+ }
+ src = a->ob_item;
+ dest = np->ob_item;
+ for (i = 0; i < Py_SIZE(a); i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ src = b->ob_item;
+ dest = np->ob_item + Py_SIZE(a);
+ for (i = 0; i < Py_SIZE(b); i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+list_repeat(PyListObject *a, Py_ssize_t n)
+{
+ Py_ssize_t i, j;
+ Py_ssize_t size;
+ PyListObject *np;
+ PyObject **p, **items;
+ PyObject *elem;
+ if (n < 0)
+ n = 0;
+ if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n)
+ return PyErr_NoMemory();
+ size = Py_SIZE(a) * n;
+ if (size == 0)
+ return PyList_New(0);
+ np = (PyListObject *) PyList_New(size);
+ if (np == NULL)
+ return NULL;
+
+ items = np->ob_item;
+ if (Py_SIZE(a) == 1) {
+ elem = a->ob_item[0];
+ for (i = 0; i < n; i++) {
+ items[i] = elem;
+ Py_INCREF(elem);
+ }
+ return (PyObject *) np;
+ }
+ p = np->ob_item;
+ items = a->ob_item;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < Py_SIZE(a); j++) {
+ *p = items[j];
+ Py_INCREF(*p);
+ p++;
+ }
+ }
+ return (PyObject *) np;
+}
+
+static int
+list_clear(PyListObject *a)
+{
+ Py_ssize_t i;
+ PyObject **item = a->ob_item;
+ if (item != NULL) {
+ /* Because XDECREF can recursively invoke operations on
+ this list, we make it empty first. */
+ i = Py_SIZE(a);
+ Py_SIZE(a) = 0;
+ a->ob_item = NULL;
+ a->allocated = 0;
+ while (--i >= 0) {
+ Py_XDECREF(item[i]);
+ }
+ PyMem_FREE(item);
+ }
+ /* Never fails; the return value can be ignored.
+ Note that there is no guarantee that the list is actually empty
+ at this point, because XDECREF may have populated it again! */
+ return 0;
+}
+
+/* a[ilow:ihigh] = v if v != NULL.
+ * del a[ilow:ihigh] if v == NULL.
+ *
+ * Special speed gimmick: when v is NULL and ihigh - ilow <= 8, it's
+ * guaranteed the call cannot fail.
+ */
+static int
+list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+ /* Because [X]DECREF can recursively invoke list operations on
+ this list, we must postpone all [X]DECREF activity until
+ after the list is back in its canonical shape. Therefore
+ we must allocate an additional array, 'recycle', into which
+ we temporarily copy the items that are deleted from the
+ list. :-( */
+ PyObject *recycle_on_stack[8];
+ PyObject **recycle = recycle_on_stack; /* will allocate more if needed */
+ PyObject **item;
+ PyObject **vitem = NULL;
+ PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
+ Py_ssize_t n; /* # of elements in replacement list */
+ Py_ssize_t norig; /* # of elements in list getting replaced */
+ Py_ssize_t d; /* Change in size */
+ Py_ssize_t k;
+ size_t s;
+ int result = -1; /* guilty until proved innocent */
+#define b ((PyListObject *)v)
+ if (v == NULL)
+ n = 0;
+ else {
+ if (a == b) {
+ /* Special case "a[i:j] = a" -- copy b first */
+ v = list_slice(b, 0, Py_SIZE(b));
+ if (v == NULL)
+ return result;
+ result = list_ass_slice(a, ilow, ihigh, v);
+ Py_DECREF(v);
+ return result;
+ }
+ v_as_SF = PySequence_Fast(v, "can only assign an iterable");
+ if(v_as_SF == NULL)
+ goto Error;
+ n = PySequence_Fast_GET_SIZE(v_as_SF);
+ vitem = PySequence_Fast_ITEMS(v_as_SF);
+ }
+ if (ilow < 0)
+ ilow = 0;
+ else if (ilow > Py_SIZE(a))
+ ilow = Py_SIZE(a);
+
+ if (ihigh < ilow)
+ ihigh = ilow;
+ else if (ihigh > Py_SIZE(a))
+ ihigh = Py_SIZE(a);
+
+ norig = ihigh - ilow;
+ assert(norig >= 0);
+ d = n - norig;
+ if (Py_SIZE(a) + d == 0) {
+ Py_XDECREF(v_as_SF);
+ return list_clear(a);
+ }
+ item = a->ob_item;
+ /* recycle the items that we are about to remove */
+ s = norig * sizeof(PyObject *);
+ if (s > sizeof(recycle_on_stack)) {
+ recycle = (PyObject **)PyMem_MALLOC(s);
+ if (recycle == NULL) {
+ PyErr_NoMemory();
+ goto Error;
+ }
+ }
+ memcpy(recycle, &item[ilow], s);
+
+ if (d < 0) { /* Delete -d items */
+ memmove(&item[ihigh+d], &item[ihigh],
+ (Py_SIZE(a) - ihigh)*sizeof(PyObject *));
+ list_resize(a, Py_SIZE(a) + d);
+ item = a->ob_item;
+ }
+ else if (d > 0) { /* Insert d items */
+ k = Py_SIZE(a);
+ if (list_resize(a, k+d) < 0)
+ goto Error;
+ item = a->ob_item;
+ memmove(&item[ihigh+d], &item[ihigh],
+ (k - ihigh)*sizeof(PyObject *));
+ }
+ for (k = 0; k < n; k++, ilow++) {
+ PyObject *w = vitem[k];
+ Py_XINCREF(w);
+ item[ilow] = w;
+ }
+ for (k = norig - 1; k >= 0; --k)
+ Py_XDECREF(recycle[k]);
+ result = 0;
+ Error:
+ if (recycle != recycle_on_stack)
+ PyMem_FREE(recycle);
+ Py_XDECREF(v_as_SF);
+ return result;
+#undef b
+}
+
+int
+PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
+{
+ if (!PyList_Check(a)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
+}
+
+static PyObject *
+list_inplace_repeat(PyListObject *self, Py_ssize_t n)
+{
+ PyObject **items;
+ Py_ssize_t size, i, j, p;
+
+
+ size = PyList_GET_SIZE(self);
+ if (size == 0 || n == 1) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+
+ if (n < 1) {
+ (void)list_clear(self);
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+
+ if (size > PY_SSIZE_T_MAX / n) {
+ return PyErr_NoMemory();
+ }
+
+ if (list_resize(self, size*n) == -1)
+ return NULL;
+
+ p = size;
+ items = self->ob_item;
+ for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */
+ for (j = 0; j < size; j++) {
+ PyObject *o = items[j];
+ Py_INCREF(o);
+ items[p++] = o;
+ }
+ }
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static int
+list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
+{
+ PyObject *old_value;
+ if (i < 0 || i >= Py_SIZE(a)) {
+ PyErr_SetString(PyExc_IndexError,
+ "list assignment index out of range");
+ return -1;
+ }
+ if (v == NULL)
+ return list_ass_slice(a, i, i+1, v);
+ Py_INCREF(v);
+ old_value = a->ob_item[i];
+ a->ob_item[i] = v;
+ Py_DECREF(old_value);
+ return 0;
+}
+
+static PyObject *
+listinsert(PyListObject *self, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *v;
+ if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
+ return NULL;
+ if (ins1(self, i, v) == 0)
+ Py_RETURN_NONE;
+ return NULL;
+}
+
+static PyObject *
+listappend(PyListObject *self, PyObject *v)
+{
+ if (app1(self, v) == 0)
+ Py_RETURN_NONE;
+ return NULL;
+}
+
+static PyObject *
+listextend(PyListObject *self, PyObject *b)
+{
+ PyObject *it; /* iter(v) */
+ Py_ssize_t m; /* size of self */
+ Py_ssize_t n; /* guess for size of b */
+ Py_ssize_t mn; /* m + n */
+ Py_ssize_t i;
+ PyObject *(*iternext)(PyObject *);
+
+ /* Special cases:
+ 1) lists and tuples which can use PySequence_Fast ops
+ 2) extending self to self requires making a copy first
+ */
+ if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
+ PyObject **src, **dest;
+ b = PySequence_Fast(b, "argument must be iterable");
+ if (!b)
+ return NULL;
+ n = PySequence_Fast_GET_SIZE(b);
+ if (n == 0) {
+ /* short circuit when b is empty */
+ Py_DECREF(b);
+ Py_RETURN_NONE;
+ }
+ m = Py_SIZE(self);
+ if (list_resize(self, m + n) == -1) {
+ Py_DECREF(b);
+ return NULL;
+ }
+ /* note that we may still have self == b here for the
+ * situation a.extend(a), but the following code works
+ * in that case too. Just make sure to resize self
+ * before calling PySequence_Fast_ITEMS.
+ */
+ /* populate the end of self with b's items */
+ src = PySequence_Fast_ITEMS(b);
+ dest = self->ob_item + m;
+ for (i = 0; i < n; i++) {
+ PyObject *o = src[i];
+ Py_INCREF(o);
+ dest[i] = o;
+ }
+ Py_DECREF(b);
+ Py_RETURN_NONE;
+ }
+
+ it = PyObject_GetIter(b);
+ if (it == NULL)
+ return NULL;
+ iternext = *it->ob_type->tp_iternext;
+
+ /* Guess a result list size. */
+ n = _PyObject_LengthHint(b, 8);
+ if (n == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ m = Py_SIZE(self);
+ mn = m + n;
+ if (mn >= m) {
+ /* Make room. */
+ if (list_resize(self, mn) == -1)
+ goto error;
+ /* Make the list sane again. */
+ Py_SIZE(self) = m;
+ }
+ /* Else m + n overflowed; on the chance that n lied, and there really
+ * is enough room, ignore it. If n was telling the truth, we'll
+ * eventually run out of memory during the loop.
+ */
+
+ /* Run iterator to exhaustion. */
+ for (;;) {
+ PyObject *item = iternext(it);
+ if (item == NULL) {
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ else
+ goto error;
+ }
+ break;
+ }
+ if (Py_SIZE(self) < self->allocated) {
+ /* steals ref */
+ PyList_SET_ITEM(self, Py_SIZE(self), item);
+ ++Py_SIZE(self);
+ }
+ else {
+ int status = app1(self, item);
+ Py_DECREF(item); /* append creates a new ref */
+ if (status < 0)
+ goto error;
+ }
+ }
+
+ /* Cut back result list if initial guess was too large. */
+ if (Py_SIZE(self) < self->allocated)
+ list_resize(self, Py_SIZE(self)); /* shrinking can't fail */
+
+ Py_DECREF(it);
+ Py_RETURN_NONE;
+
+ error:
+ Py_DECREF(it);
+ return NULL;
+}
+
+PyObject *
+_PyList_Extend(PyListObject *self, PyObject *b)
+{
+ return listextend(self, b);
+}
+
+static PyObject *
+list_inplace_concat(PyListObject *self, PyObject *other)
+{
+ PyObject *result;
+
+ result = listextend(self, other);
+ if (result == NULL)
+ return result;
+ Py_DECREF(result);
+ Py_INCREF(self);
+ return (PyObject *)self;
+}
+
+static PyObject *
+listpop(PyListObject *self, PyObject *args)
+{
+ Py_ssize_t i = -1;
+ PyObject *v;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "|n:pop", &i))
+ return NULL;
+
+ if (Py_SIZE(self) == 0) {
+ /* Special-case most common failure cause */
+ PyErr_SetString(PyExc_IndexError, "pop from empty list");
+ return NULL;
+ }
+ if (i < 0)
+ i += Py_SIZE(self);
+ if (i < 0 || i >= Py_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError, "pop index out of range");
+ return NULL;
+ }
+ v = self->ob_item[i];
+ if (i == Py_SIZE(self) - 1) {
+ status = list_resize(self, Py_SIZE(self) - 1);
+ assert(status >= 0);
+ return v; /* and v now owns the reference the list had */
+ }
+ Py_INCREF(v);
+ status = list_ass_slice(self, i, i+1, (PyObject *)NULL);
+ assert(status >= 0);
+ /* Use status, so that in a release build compilers don't
+ * complain about the unused name.
+ */
+ (void) status;
+
+ return v;
+}
+
+/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
+static void
+reverse_slice(PyObject **lo, PyObject **hi)
+{
+ assert(lo && hi);
+
+ --hi;
+ while (lo < hi) {
+ PyObject *t = *lo;
+ *lo = *hi;
+ *hi = t;
+ ++lo;
+ --hi;
+ }
+}
+
+/* Lots of code for an adaptive, stable, natural mergesort. There are many
+ * pieces to this algorithm; read listsort.txt for overviews and details.
+ */
+
+/* Comparison function. Takes care of calling a user-supplied
+ * comparison function (any callable Python object), which must not be
+ * NULL (use the ISLT macro if you don't know, or call PyObject_RichCompareBool
+ * with Py_LT if you know it's NULL).
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+static int
+islt(PyObject *x, PyObject *y, PyObject *compare)
+{
+ PyObject *res;
+ PyObject *args;
+ Py_ssize_t i;
+
+ assert(compare != NULL);
+ /* Call the user's comparison function and translate the 3-way
+ * result into true or false (or error).
+ */
+ args = PyTuple_New(2);
+ if (args == NULL)
+ return -1;
+ Py_INCREF(x);
+ Py_INCREF(y);
+ PyTuple_SET_ITEM(args, 0, x);
+ PyTuple_SET_ITEM(args, 1, y);
+ res = PyObject_Call(compare, args, NULL);
+ Py_DECREF(args);
+ if (res == NULL)
+ return -1;
+ if (!PyInt_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "comparison function must return int, not %.200s",
+ res->ob_type->tp_name);
+ Py_DECREF(res);
+ return -1;
+ }
+ i = PyInt_AsLong(res);
+ Py_DECREF(res);
+ return i < 0;
+}
+
+/* If COMPARE is NULL, calls PyObject_RichCompareBool with Py_LT, else calls
+ * islt. This avoids a layer of function call in the usual case, and
+ * sorting does many comparisons.
+ * Returns -1 on error, 1 if x < y, 0 if x >= y.
+ */
+#define ISLT(X, Y, COMPARE) ((COMPARE) == NULL ? \
+ PyObject_RichCompareBool(X, Y, Py_LT) : \
+ islt(X, Y, COMPARE))
+
+/* Compare X to Y via "<". Goto "fail" if the comparison raises an
+ error. Else "k" is set to true iff X<Y, and an "if (k)" block is
+ started. It makes more sense in context <wink>. X and Y are PyObject*s.
+*/
+#define IFLT(X, Y) if ((k = ISLT(X, Y, compare)) < 0) goto fail; \
+ if (k)
+
+/* binarysort is the best method for sorting small arrays: it does
+ few compares, but can do data movement quadratic in the number of
+ elements.
+ [lo, hi) is a contiguous slice of a list, and is sorted via
+ binary insertion. This sort is stable.
+ On entry, must have lo <= start <= hi, and that [lo, start) is already
+ sorted (pass start == lo if you don't know!).
+ If islt() complains return -1, else 0.
+ Even in case of error, the output slice will be some permutation of
+ the input (nothing is lost or duplicated).
+*/
+static int
+binarysort(PyObject **lo, PyObject **hi, PyObject **start, PyObject *compare)
+ /* compare -- comparison function object, or NULL for default */
+{
+ register Py_ssize_t k;
+ register PyObject **l, **p, **r;
+ register PyObject *pivot;
+
+ assert(lo <= start && start <= hi);
+ /* assert [lo, start) is sorted */
+ if (lo == start)
+ ++start;
+ for (; start < hi; ++start) {
+ /* set l to where *start belongs */
+ l = lo;
+ r = start;
+ pivot = *r;
+ /* Invariants:
+ * pivot >= all in [lo, l).
+ * pivot < all in [r, start).
+ * The second is vacuously true at the start.
+ */
+ assert(l < r);
+ do {
+ p = l + ((r - l) >> 1);
+ IFLT(pivot, *p)
+ r = p;
+ else
+ l = p+1;
+ } while (l < r);
+ assert(l == r);
+ /* The invariants still hold, so pivot >= all in [lo, l) and
+ pivot < all in [l, start), so pivot belongs at l. Note
+ that if there are elements equal to pivot, l points to the
+ first slot after them -- that's why this sort is stable.
+ Slide over to make room.
+ Caution: using memmove is much slower under MSVC 5;
+ we're not usually moving many slots. */
+ for (p = start; p > l; --p)
+ *p = *(p-1);
+ *l = pivot;
+ }
+ return 0;
+
+ fail:
+ return -1;
+}
+
+/*
+Return the length of the run beginning at lo, in the slice [lo, hi). lo < hi
+is required on entry. "A run" is the longest ascending sequence, with
+
+ lo[0] <= lo[1] <= lo[2] <= ...
+
+or the longest descending sequence, with
+
+ lo[0] > lo[1] > lo[2] > ...
+
+Boolean *descending is set to 0 in the former case, or to 1 in the latter.
+For its intended use in a stable mergesort, the strictness of the defn of
+"descending" is needed so that the caller can safely reverse a descending
+sequence without violating stability (strict > ensures there are no equal
+elements to get out of order).
+
+Returns -1 in case of error.
+*/
+static Py_ssize_t
+count_run(PyObject **lo, PyObject **hi, PyObject *compare, int *descending)
+{
+ Py_ssize_t k;
+ Py_ssize_t n;
+
+ assert(lo < hi);
+ *descending = 0;
+ ++lo;
+ if (lo == hi)
+ return 1;
+
+ n = 2;
+ IFLT(*lo, *(lo-1)) {
+ *descending = 1;
+ for (lo = lo+1; lo < hi; ++lo, ++n) {
+ IFLT(*lo, *(lo-1))
+ ;
+ else
+ break;
+ }
+ }
+ else {
+ for (lo = lo+1; lo < hi; ++lo, ++n) {
+ IFLT(*lo, *(lo-1))
+ break;
+ }
+ }
+
+ return n;
+fail:
+ return -1;
+}
+
+/*
+Locate the proper position of key in a sorted vector; if the vector contains
+an element equal to key, return the position immediately to the left of
+the leftmost equal element. [gallop_right() does the same except returns
+the position to the right of the rightmost equal element (if any).]
+
+"a" is a sorted vector with n elements, starting at a[0]. n must be > 0.
+
+"hint" is an index at which to begin the search, 0 <= hint < n. The closer
+hint is to the final result, the faster this runs.
+
+The return value is the int k in 0..n such that
+
+ a[k-1] < key <= a[k]
+
+pretending that *(a-1) is minus infinity and a[n] is plus infinity. IOW,
+key belongs at index k; or, IOW, the first k elements of a should precede
+key, and the last n-k should follow key.
+
+Returns -1 on error. See listsort.txt for info on the method.
+*/
+static Py_ssize_t
+gallop_left(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+ Py_ssize_t ofs;
+ Py_ssize_t lastofs;
+ Py_ssize_t k;
+
+ assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+ a += hint;
+ lastofs = 0;
+ ofs = 1;
+ IFLT(*a, key) {
+ /* a[hint] < key -- gallop right, until
+ * a[hint + lastofs] < key <= a[hint + ofs]
+ */
+ const Py_ssize_t maxofs = n - hint; /* &a[n-1] is highest */
+ while (ofs < maxofs) {
+ IFLT(a[ofs], key) {
+ lastofs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) /* int overflow */
+ ofs = maxofs;
+ }
+ else /* key <= a[hint + ofs] */
+ break;
+ }
+ if (ofs > maxofs)
+ ofs = maxofs;
+ /* Translate back to offsets relative to &a[0]. */
+ lastofs += hint;
+ ofs += hint;
+ }
+ else {
+ /* key <= a[hint] -- gallop left, until
+ * a[hint - ofs] < key <= a[hint - lastofs]
+ */
+ const Py_ssize_t maxofs = hint + 1; /* &a[0] is lowest */
+ while (ofs < maxofs) {
+ IFLT(*(a-ofs), key)
+ break;
+ /* key <= a[hint - ofs] */
+ lastofs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) /* int overflow */
+ ofs = maxofs;
+ }
+ if (ofs > maxofs)
+ ofs = maxofs;
+ /* Translate back to positive offsets relative to &a[0]. */
+ k = lastofs;
+ lastofs = hint - ofs;
+ ofs = hint - k;
+ }
+ a -= hint;
+
+ assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+ /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
+ * right of lastofs but no farther right than ofs. Do a binary
+ * search, with invariant a[lastofs-1] < key <= a[ofs].
+ */
+ ++lastofs;
+ while (lastofs < ofs) {
+ Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+ IFLT(a[m], key)
+ lastofs = m+1; /* a[m] < key */
+ else
+ ofs = m; /* key <= a[m] */
+ }
+ assert(lastofs == ofs); /* so a[ofs-1] < key <= a[ofs] */
+ return ofs;
+
+fail:
+ return -1;
+}
+
+/*
+Exactly like gallop_left(), except that if key already exists in a[0:n],
+finds the position immediately to the right of the rightmost equal value.
+
+The return value is the int k in 0..n such that
+
+ a[k-1] <= key < a[k]
+
+or -1 if error.
+
+The code duplication is massive, but this is enough different given that
+we're sticking to "<" comparisons that it's much harder to follow if
+written as one routine with yet another "left or right?" flag.
+*/
+static Py_ssize_t
+gallop_right(PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_t hint, PyObject *compare)
+{
+ Py_ssize_t ofs;
+ Py_ssize_t lastofs;
+ Py_ssize_t k;
+
+ assert(key && a && n > 0 && hint >= 0 && hint < n);
+
+ a += hint;
+ lastofs = 0;
+ ofs = 1;
+ IFLT(key, *a) {
+ /* key < a[hint] -- gallop left, until
+ * a[hint - ofs] <= key < a[hint - lastofs]
+ */
+ const Py_ssize_t maxofs = hint + 1; /* &a[0] is lowest */
+ while (ofs < maxofs) {
+ IFLT(key, *(a-ofs)) {
+ lastofs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) /* int overflow */
+ ofs = maxofs;
+ }
+ else /* a[hint - ofs] <= key */
+ break;
+ }
+ if (ofs > maxofs)
+ ofs = maxofs;
+ /* Translate back to positive offsets relative to &a[0]. */
+ k = lastofs;
+ lastofs = hint - ofs;
+ ofs = hint - k;
+ }
+ else {
+ /* a[hint] <= key -- gallop right, until
+ * a[hint + lastofs] <= key < a[hint + ofs]
+ */
+ const Py_ssize_t maxofs = n - hint; /* &a[n-1] is highest */
+ while (ofs < maxofs) {
+ IFLT(key, a[ofs])
+ break;
+ /* a[hint + ofs] <= key */
+ lastofs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) /* int overflow */
+ ofs = maxofs;
+ }
+ if (ofs > maxofs)
+ ofs = maxofs;
+ /* Translate back to offsets relative to &a[0]. */
+ lastofs += hint;
+ ofs += hint;
+ }
+ a -= hint;
+
+ assert(-1 <= lastofs && lastofs < ofs && ofs <= n);
+ /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
+ * right of lastofs but no farther right than ofs. Do a binary
+ * search, with invariant a[lastofs-1] <= key < a[ofs].
+ */
+ ++lastofs;
+ while (lastofs < ofs) {
+ Py_ssize_t m = lastofs + ((ofs - lastofs) >> 1);
+
+ IFLT(key, a[m])
+ ofs = m; /* key < a[m] */
+ else
+ lastofs = m+1; /* a[m] <= key */
+ }
+ assert(lastofs == ofs); /* so a[ofs-1] <= key < a[ofs] */
+ return ofs;
+
+fail:
+ return -1;
+}
+
+/* The maximum number of entries in a MergeState's pending-runs stack.
+ * This is enough to sort arrays of size up to about
+ * 32 * phi ** MAX_MERGE_PENDING
+ * where phi ~= 1.618. 85 is ridiculouslylarge enough, good for an array
+ * with 2**64 elements.
+ */
+#define MAX_MERGE_PENDING 85
+
+/* When we get into galloping mode, we stay there until both runs win less
+ * often than MIN_GALLOP consecutive times. See listsort.txt for more info.
+ */
+#define MIN_GALLOP 7
+
+/* Avoid malloc for small temp arrays. */
+#define MERGESTATE_TEMP_SIZE 256
+
+/* One MergeState exists on the stack per invocation of mergesort. It's just
+ * a convenient way to pass state around among the helper functions.
+ */
+struct s_slice {
+ PyObject **base;
+ Py_ssize_t len;
+};
+
+typedef struct s_MergeState {
+ /* The user-supplied comparison function. or NULL if none given. */
+ PyObject *compare;
+
+ /* This controls when we get *into* galloping mode. It's initialized
+ * to MIN_GALLOP. merge_lo and merge_hi tend to nudge it higher for
+ * random data, and lower for highly structured data.
+ */
+ Py_ssize_t min_gallop;
+
+ /* 'a' is temp storage to help with merges. It contains room for
+ * alloced entries.
+ */
+ PyObject **a; /* may point to temparray below */
+ Py_ssize_t alloced;
+
+ /* A stack of n pending runs yet to be merged. Run #i starts at
+ * address base[i] and extends for len[i] elements. It's always
+ * true (so long as the indices are in bounds) that
+ *
+ * pending[i].base + pending[i].len == pending[i+1].base
+ *
+ * so we could cut the storage for this, but it's a minor amount,
+ * and keeping all the info explicit simplifies the code.
+ */
+ int n;
+ struct s_slice pending[MAX_MERGE_PENDING];
+
+ /* 'a' points to this when possible, rather than muck with malloc. */
+ PyObject *temparray[MERGESTATE_TEMP_SIZE];
+} MergeState;
+
+/* Conceptually a MergeState's constructor. */
+static void
+merge_init(MergeState *ms, PyObject *compare)
+{
+ assert(ms != NULL);
+ ms->compare = compare;
+ ms->a = ms->temparray;
+ ms->alloced = MERGESTATE_TEMP_SIZE;
+ ms->n = 0;
+ ms->min_gallop = MIN_GALLOP;
+}
+
+/* Free all the temp memory owned by the MergeState. This must be called
+ * when you're done with a MergeState, and may be called before then if
+ * you want to free the temp memory early.
+ */
+static void
+merge_freemem(MergeState *ms)
+{
+ assert(ms != NULL);
+ if (ms->a != ms->temparray)
+ PyMem_Free(ms->a);
+ ms->a = ms->temparray;
+ ms->alloced = MERGESTATE_TEMP_SIZE;
+}
+
+/* Ensure enough temp memory for 'need' array slots is available.
+ * Returns 0 on success and -1 if the memory can't be gotten.
+ */
+static int
+merge_getmem(MergeState *ms, Py_ssize_t need)
+{
+ assert(ms != NULL);
+ if (need <= ms->alloced)
+ return 0;
+ /* Don't realloc! That can cost cycles to copy the old data, but
+ * we don't care what's in the block.
+ */
+ merge_freemem(ms);
+ if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
+ if (ms->a) {
+ ms->alloced = need;
+ return 0;
+ }
+ PyErr_NoMemory();
+ merge_freemem(ms); /* reset to sane state */
+ return -1;
+}
+#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 : \
+ merge_getmem(MS, NEED))
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na <= nb. See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
+ PyObject **pb, Py_ssize_t nb)
+{
+ Py_ssize_t k;
+ PyObject *compare;
+ PyObject **dest;
+ int result = -1; /* guilty until proved innocent */
+ Py_ssize_t min_gallop;
+
+ assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+ if (MERGE_GETMEM(ms, na) < 0)
+ return -1;
+ memcpy(ms->a, pa, na * sizeof(PyObject*));
+ dest = pa;
+ pa = ms->a;
+
+ *dest++ = *pb++;
+ --nb;
+ if (nb == 0)
+ goto Succeed;
+ if (na == 1)
+ goto CopyB;
+
+ min_gallop = ms->min_gallop;
+ compare = ms->compare;
+ for (;;) {
+ Py_ssize_t acount = 0; /* # of times A won in a row */
+ Py_ssize_t bcount = 0; /* # of times B won in a row */
+
+ /* Do the straightforward thing until (if ever) one run
+ * appears to win consistently.
+ */
+ for (;;) {
+ assert(na > 1 && nb > 0);
+ k = ISLT(*pb, *pa, compare);
+ if (k) {
+ if (k < 0)
+ goto Fail;
+ *dest++ = *pb++;
+ ++bcount;
+ acount = 0;
+ --nb;
+ if (nb == 0)
+ goto Succeed;
+ if (bcount >= min_gallop)
+ break;
+ }
+ else {
+ *dest++ = *pa++;
+ ++acount;
+ bcount = 0;
+ --na;
+ if (na == 1)
+ goto CopyB;
+ if (acount >= min_gallop)
+ break;
+ }
+ }
+
+ /* One run is winning so consistently that galloping may
+ * be a huge win. So try that, and continue galloping until
+ * (if ever) neither run appears to be winning consistently
+ * anymore.
+ */
+ ++min_gallop;
+ do {
+ assert(na > 1 && nb > 0);
+ min_gallop -= min_gallop > 1;
+ ms->min_gallop = min_gallop;
+ k = gallop_right(*pb, pa, na, 0, compare);
+ acount = k;
+ if (k) {
+ if (k < 0)
+ goto Fail;
+ memcpy(dest, pa, k * sizeof(PyObject *));
+ dest += k;
+ pa += k;
+ na -= k;
+ if (na == 1)
+ goto CopyB;
+ /* na==0 is impossible now if the comparison
+ * function is consistent, but we can't assume
+ * that it is.
+ */
+ if (na == 0)
+ goto Succeed;
+ }
+ *dest++ = *pb++;
+ --nb;
+ if (nb == 0)
+ goto Succeed;
+
+ k = gallop_left(*pa, pb, nb, 0, compare);
+ bcount = k;
+ if (k) {
+ if (k < 0)
+ goto Fail;
+ memmove(dest, pb, k * sizeof(PyObject *));
+ dest += k;
+ pb += k;
+ nb -= k;
+ if (nb == 0)
+ goto Succeed;
+ }
+ *dest++ = *pa++;
+ --na;
+ if (na == 1)
+ goto CopyB;
+ } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+ ++min_gallop; /* penalize it for leaving galloping mode */
+ ms->min_gallop = min_gallop;
+ }
+Succeed:
+ result = 0;
+Fail:
+ if (na)
+ memcpy(dest, pa, na * sizeof(PyObject*));
+ return result;
+CopyB:
+ assert(na == 1 && nb > 0);
+ /* The last element of pa belongs at the end of the merge. */
+ memmove(dest, pb, nb * sizeof(PyObject *));
+ dest[nb] = *pa;
+ return 0;
+}
+
+/* Merge the na elements starting at pa with the nb elements starting at pb
+ * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
+ * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
+ * merge, and should have na >= nb. See listsort.txt for more info.
+ * Return 0 if successful, -1 if error.
+ */
+static Py_ssize_t
+merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb)
+{
+ Py_ssize_t k;
+ PyObject *compare;
+ PyObject **dest;
+ int result = -1; /* guilty until proved innocent */
+ PyObject **basea;
+ PyObject **baseb;
+ Py_ssize_t min_gallop;
+
+ assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+ if (MERGE_GETMEM(ms, nb) < 0)
+ return -1;
+ dest = pb + nb - 1;
+ memcpy(ms->a, pb, nb * sizeof(PyObject*));
+ basea = pa;
+ baseb = ms->a;
+ pb = ms->a + nb - 1;
+ pa += na - 1;
+
+ *dest-- = *pa--;
+ --na;
+ if (na == 0)
+ goto Succeed;
+ if (nb == 1)
+ goto CopyA;
+
+ min_gallop = ms->min_gallop;
+ compare = ms->compare;
+ for (;;) {
+ Py_ssize_t acount = 0; /* # of times A won in a row */
+ Py_ssize_t bcount = 0; /* # of times B won in a row */
+
+ /* Do the straightforward thing until (if ever) one run
+ * appears to win consistently.
+ */
+ for (;;) {
+ assert(na > 0 && nb > 1);
+ k = ISLT(*pb, *pa, compare);
+ if (k) {
+ if (k < 0)
+ goto Fail;
+ *dest-- = *pa--;
+ ++acount;
+ bcount = 0;
+ --na;
+ if (na == 0)
+ goto Succeed;
+ if (acount >= min_gallop)
+ break;
+ }
+ else {
+ *dest-- = *pb--;
+ ++bcount;
+ acount = 0;
+ --nb;
+ if (nb == 1)
+ goto CopyA;
+ if (bcount >= min_gallop)
+ break;
+ }
+ }
+
+ /* One run is winning so consistently that galloping may
+ * be a huge win. So try that, and continue galloping until
+ * (if ever) neither run appears to be winning consistently
+ * anymore.
+ */
+ ++min_gallop;
+ do {
+ assert(na > 0 && nb > 1);
+ min_gallop -= min_gallop > 1;
+ ms->min_gallop = min_gallop;
+ k = gallop_right(*pb, basea, na, na-1, compare);
+ if (k < 0)
+ goto Fail;
+ k = na - k;
+ acount = k;
+ if (k) {
+ dest -= k;
+ pa -= k;
+ memmove(dest+1, pa+1, k * sizeof(PyObject *));
+ na -= k;
+ if (na == 0)
+ goto Succeed;
+ }
+ *dest-- = *pb--;
+ --nb;
+ if (nb == 1)
+ goto CopyA;
+
+ k = gallop_left(*pa, baseb, nb, nb-1, compare);
+ if (k < 0)
+ goto Fail;
+ k = nb - k;
+ bcount = k;
+ if (k) {
+ dest -= k;
+ pb -= k;
+ memcpy(dest+1, pb+1, k * sizeof(PyObject *));
+ nb -= k;
+ if (nb == 1)
+ goto CopyA;
+ /* nb==0 is impossible now if the comparison
+ * function is consistent, but we can't assume
+ * that it is.
+ */
+ if (nb == 0)
+ goto Succeed;
+ }
+ *dest-- = *pa--;
+ --na;
+ if (na == 0)
+ goto Succeed;
+ } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
+ ++min_gallop; /* penalize it for leaving galloping mode */
+ ms->min_gallop = min_gallop;
+ }
+Succeed:
+ result = 0;
+Fail:
+ if (nb)
+ memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*));
+ return result;
+CopyA:
+ assert(nb == 1 && na > 0);
+ /* The first element of pb belongs at the front of the merge. */
+ dest -= na;
+ pa -= na;
+ memmove(dest+1, pa+1, na * sizeof(PyObject *));
+ *dest = *pb;
+ return 0;
+}
+
+/* Merge the two runs at stack indices i and i+1.
+ * Returns 0 on success, -1 on error.
+ */
+static Py_ssize_t
+merge_at(MergeState *ms, Py_ssize_t i)
+{
+ PyObject **pa, **pb;
+ Py_ssize_t na, nb;
+ Py_ssize_t k;
+ PyObject *compare;
+
+ assert(ms != NULL);
+ assert(ms->n >= 2);
+ assert(i >= 0);
+ assert(i == ms->n - 2 || i == ms->n - 3);
+
+ pa = ms->pending[i].base;
+ na = ms->pending[i].len;
+ pb = ms->pending[i+1].base;
+ nb = ms->pending[i+1].len;
+ assert(na > 0 && nb > 0);
+ assert(pa + na == pb);
+
+ /* Record the length of the combined runs; if i is the 3rd-last
+ * run now, also slide over the last run (which isn't involved
+ * in this merge). The current run i+1 goes away in any case.
+ */
+ ms->pending[i].len = na + nb;
+ if (i == ms->n - 3)
+ ms->pending[i+1] = ms->pending[i+2];
+ --ms->n;
+
+ /* Where does b start in a? Elements in a before that can be
+ * ignored (already in place).
+ */
+ compare = ms->compare;
+ k = gallop_right(*pb, pa, na, 0, compare);
+ if (k < 0)
+ return -1;
+ pa += k;
+ na -= k;
+ if (na == 0)
+ return 0;
+
+ /* Where does a end in b? Elements in b after that can be
+ * ignored (already in place).
+ */
+ nb = gallop_left(pa[na-1], pb, nb, nb-1, compare);
+ if (nb <= 0)
+ return nb;
+
+ /* Merge what remains of the runs, using a temp array with
+ * min(na, nb) elements.
+ */
+ if (na <= nb)
+ return merge_lo(ms, pa, na, pb, nb);
+ else
+ return merge_hi(ms, pa, na, pb, nb);
+}
+
+/* Examine the stack of runs waiting to be merged, merging adjacent runs
+ * until the stack invariants are re-established:
+ *
+ * 1. len[-3] > len[-2] + len[-1]
+ * 2. len[-2] > len[-1]
+ *
+ * See listsort.txt for more info.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_collapse(MergeState *ms)
+{
+ struct s_slice *p = ms->pending;
+
+ assert(ms);
+ while (ms->n > 1) {
+ Py_ssize_t n = ms->n - 2;
+ if ((n > 0 && p[n-1].len <= p[n].len + p[n+1].len) ||
+ (n > 1 && p[n-2].len <= p[n-1].len + p[n].len)) {
+ if (p[n-1].len < p[n+1].len)
+ --n;
+ if (merge_at(ms, n) < 0)
+ return -1;
+ }
+ else if (p[n].len <= p[n+1].len) {
+ if (merge_at(ms, n) < 0)
+ return -1;
+ }
+ else
+ break;
+ }
+ return 0;
+}
+
+/* Regardless of invariants, merge all runs on the stack until only one
+ * remains. This is used at the end of the mergesort.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int
+merge_force_collapse(MergeState *ms)
+{
+ struct s_slice *p = ms->pending;
+
+ assert(ms);
+ while (ms->n > 1) {
+ Py_ssize_t n = ms->n - 2;
+ if (n > 0 && p[n-1].len < p[n+1].len)
+ --n;
+ if (merge_at(ms, n) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/* Compute a good value for the minimum run length; natural runs shorter
+ * than this are boosted artificially via binary insertion.
+ *
+ * If n < 64, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return 32.
+ * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
+ * strictly less than, an exact power of 2.
+ *
+ * See listsort.txt for more info.
+ */
+static Py_ssize_t
+merge_compute_minrun(Py_ssize_t n)
+{
+ Py_ssize_t r = 0; /* becomes 1 if any 1 bits are shifted off */
+
+ assert(n >= 0);
+ while (n >= 64) {
+ r |= n & 1;
+ n >>= 1;
+ }
+ return n + r;
+}
+
+/* Special wrapper to support stable sorting using the decorate-sort-undecorate
+ pattern. Holds a key which is used for comparisons and the original record
+ which is returned during the undecorate phase. By exposing only the key
+ during comparisons, the underlying sort stability characteristics are left
+ unchanged. Also, if a custom comparison function is used, it will only see
+ the key instead of a full record. */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *key;
+ PyObject *value;
+} sortwrapperobject;
+
+PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key.");
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int);
+static void
+sortwrapper_dealloc(sortwrapperobject *);
+
+static PyTypeObject sortwrapper_type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "sortwrapper", /* tp_name */
+ sizeof(sortwrapperobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)sortwrapper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 |
+ Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */
+ sortwrapper_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)sortwrapper_richcompare, /* tp_richcompare */
+};
+
+
+static PyObject *
+sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op)
+{
+ if (!PyObject_TypeCheck(b, &sortwrapper_type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a sortwrapperobject");
+ return NULL;
+ }
+ return PyObject_RichCompare(a->key, b->key, op);
+}
+
+static void
+sortwrapper_dealloc(sortwrapperobject *so)
+{
+ Py_XDECREF(so->key);
+ Py_XDECREF(so->value);
+ PyObject_Del(so);
+}
+
+/* Returns a new reference to a sortwrapper.
+ Consumes the references to the two underlying objects. */
+
+static PyObject *
+build_sortwrapper(PyObject *key, PyObject *value)
+{
+ sortwrapperobject *so;
+
+ so = PyObject_New(sortwrapperobject, &sortwrapper_type);
+ if (so == NULL)
+ return NULL;
+ so->key = key;
+ so->value = value;
+ return (PyObject *)so;
+}
+
+/* Returns a new reference to the value underlying the wrapper. */
+static PyObject *
+sortwrapper_getvalue(PyObject *so)
+{
+ PyObject *value;
+
+ if (!PyObject_TypeCheck(so, &sortwrapper_type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a sortwrapperobject");
+ return NULL;
+ }
+ value = ((sortwrapperobject *)so)->value;
+ Py_INCREF(value);
+ return value;
+}
+
+/* Wrapper for user specified cmp functions in combination with a
+ specified key function. Makes sure the cmp function is presented
+ with the actual key instead of the sortwrapper */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *func;
+} cmpwrapperobject;
+
+static void
+cmpwrapper_dealloc(cmpwrapperobject *co)
+{
+ Py_XDECREF(co->func);
+ PyObject_Del(co);
+}
+
+static PyObject *
+cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds)
+{
+ PyObject *x, *y, *xx, *yy;
+
+ if (!PyArg_UnpackTuple(args, "", 2, 2, &x, &y))
+ return NULL;
+ if (!PyObject_TypeCheck(x, &sortwrapper_type) ||
+ !PyObject_TypeCheck(y, &sortwrapper_type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected a sortwrapperobject");
+ return NULL;
+ }
+ xx = ((sortwrapperobject *)x)->key;
+ yy = ((sortwrapperobject *)y)->key;
+ return PyObject_CallFunctionObjArgs(co->func, xx, yy, NULL);
+}
+
+PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");
+
+static PyTypeObject cmpwrapper_type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "cmpwrapper", /* tp_name */
+ sizeof(cmpwrapperobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)cmpwrapper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ (ternaryfunc)cmpwrapper_call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ cmpwrapper_doc, /* tp_doc */
+};
+
+static PyObject *
+build_cmpwrapper(PyObject *cmpfunc)
+{
+ cmpwrapperobject *co;
+
+ co = PyObject_New(cmpwrapperobject, &cmpwrapper_type);
+ if (co == NULL)
+ return NULL;
+ Py_INCREF(cmpfunc);
+ co->func = cmpfunc;
+ return (PyObject *)co;
+}
+
+/* An adaptive, stable, natural mergesort. See listsort.txt.
+ * Returns Py_None on success, NULL on error. Even in case of error, the
+ * list will be some permutation of its input state (nothing is lost or
+ * duplicated).
+ */
+static PyObject *
+listsort(PyListObject *self, PyObject *args, PyObject *kwds)
+{
+ MergeState ms;
+ PyObject **lo, **hi;
+ Py_ssize_t nremaining;
+ Py_ssize_t minrun;
+ Py_ssize_t saved_ob_size, saved_allocated;
+ PyObject **saved_ob_item;
+ PyObject **final_ob_item;
+ PyObject *compare = NULL;
+ PyObject *result = NULL; /* guilty until proved innocent */
+ int reverse = 0;
+ PyObject *keyfunc = NULL;
+ Py_ssize_t i;
+ PyObject *key, *value, *kvpair;
+ static char *kwlist[] = {"cmp", "key", "reverse", 0};
+
+ assert(self != NULL);
+ assert (PyList_Check(self));
+ if (args != NULL) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",
+ kwlist, &compare, &keyfunc, &reverse))
+ return NULL;
+ }
+ if (compare == Py_None)
+ compare = NULL;
+ if (compare != NULL &&
+ PyErr_WarnPy3k("the cmp argument is not supported in 3.x", 1) < 0)
+ return NULL;
+ if (keyfunc == Py_None)
+ keyfunc = NULL;
+ if (compare != NULL && keyfunc != NULL) {
+ compare = build_cmpwrapper(compare);
+ if (compare == NULL)
+ return NULL;
+ } else
+ Py_XINCREF(compare);
+
+ /* The list is temporarily made empty, so that mutations performed
+ * by comparison functions can't affect the slice of memory we're
+ * sorting (allowing mutations during sorting is a core-dump
+ * factory, since ob_item may change).
+ */
+ saved_ob_size = Py_SIZE(self);
+ saved_ob_item = self->ob_item;
+ saved_allocated = self->allocated;
+ Py_SIZE(self) = 0;
+ self->ob_item = NULL;
+ self->allocated = -1; /* any operation will reset it to >= 0 */
+
+ if (keyfunc != NULL) {
+ for (i=0 ; i < saved_ob_size ; i++) {
+ value = saved_ob_item[i];
+ key = PyObject_CallFunctionObjArgs(keyfunc, value,
+ NULL);
+ if (key == NULL) {
+ for (i=i-1 ; i>=0 ; i--) {
+ kvpair = saved_ob_item[i];
+ value = sortwrapper_getvalue(kvpair);
+ saved_ob_item[i] = value;
+ Py_DECREF(kvpair);
+ }
+ goto dsu_fail;
+ }
+ kvpair = build_sortwrapper(key, value);
+ if (kvpair == NULL)
+ goto dsu_fail;
+ saved_ob_item[i] = kvpair;
+ }
+ }
+
+ /* Reverse sort stability achieved by initially reversing the list,
+ applying a stable forward sort, then reversing the final result. */
+ if (reverse && saved_ob_size > 1)
+ reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+ merge_init(&ms, compare);
+
+ nremaining = saved_ob_size;
+ if (nremaining < 2)
+ goto succeed;
+
+ /* March over the array once, left to right, finding natural runs,
+ * and extending short natural runs to minrun elements.
+ */
+ lo = saved_ob_item;
+ hi = lo + nremaining;
+ minrun = merge_compute_minrun(nremaining);
+ do {
+ int descending;
+ Py_ssize_t n;
+
+ /* Identify next run. */
+ n = count_run(lo, hi, compare, &descending);
+ if (n < 0)
+ goto fail;
+ if (descending)
+ reverse_slice(lo, lo + n);
+ /* If short, extend to min(minrun, nremaining). */
+ if (n < minrun) {
+ const Py_ssize_t force = nremaining <= minrun ?
+ nremaining : minrun;
+ if (binarysort(lo, lo + force, lo + n, compare) < 0)
+ goto fail;
+ n = force;
+ }
+ /* Push run onto pending-runs stack, and maybe merge. */
+ assert(ms.n < MAX_MERGE_PENDING);
+ ms.pending[ms.n].base = lo;
+ ms.pending[ms.n].len = n;
+ ++ms.n;
+ if (merge_collapse(&ms) < 0)
+ goto fail;
+ /* Advance to find next run. */
+ lo += n;
+ nremaining -= n;
+ } while (nremaining);
+ assert(lo == hi);
+
+ if (merge_force_collapse(&ms) < 0)
+ goto fail;
+ assert(ms.n == 1);
+ assert(ms.pending[0].base == saved_ob_item);
+ assert(ms.pending[0].len == saved_ob_size);
+
+succeed:
+ result = Py_None;
+fail:
+ if (keyfunc != NULL) {
+ for (i=0 ; i < saved_ob_size ; i++) {
+ kvpair = saved_ob_item[i];
+ value = sortwrapper_getvalue(kvpair);
+ saved_ob_item[i] = value;
+ Py_DECREF(kvpair);
+ }
+ }
+
+ if (self->allocated != -1 && result != NULL) {
+ /* The user mucked with the list during the sort,
+ * and we don't already have another error to report.
+ */
+ PyErr_SetString(PyExc_ValueError, "list modified during sort");
+ result = NULL;
+ }
+
+ if (reverse && saved_ob_size > 1)
+ reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+
+ merge_freemem(&ms);
+
+dsu_fail:
+ final_ob_item = self->ob_item;
+ i = Py_SIZE(self);
+ Py_SIZE(self) = saved_ob_size;
+ self->ob_item = saved_ob_item;
+ self->allocated = saved_allocated;
+ if (final_ob_item != NULL) {
+ /* we cannot use list_clear() for this because it does not
+ guarantee that the list is really empty when it returns */
+ while (--i >= 0) {
+ Py_XDECREF(final_ob_item[i]);
+ }
+ PyMem_FREE(final_ob_item);
+ }
+ Py_XDECREF(compare);
+ Py_XINCREF(result);
+ return result;
+}
+#undef IFLT
+#undef ISLT
+
+int
+PyList_Sort(PyObject *v)
+{
+ if (v == NULL || !PyList_Check(v)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ v = listsort((PyListObject *)v, (PyObject *)NULL, (PyObject *)NULL);
+ if (v == NULL)
+ return -1;
+ Py_DECREF(v);
+ return 0;
+}
+
+static PyObject *
+listreverse(PyListObject *self)
+{
+ if (Py_SIZE(self) > 1)
+ reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
+ Py_RETURN_NONE;
+}
+
+int
+PyList_Reverse(PyObject *v)
+{
+ PyListObject *self = (PyListObject *)v;
+
+ if (v == NULL || !PyList_Check(v)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (Py_SIZE(self) > 1)
+ reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
+ return 0;
+}
+
+PyObject *
+PyList_AsTuple(PyObject *v)
+{
+ PyObject *w;
+ PyObject **p, **q;
+ Py_ssize_t n;
+ if (v == NULL || !PyList_Check(v)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ n = Py_SIZE(v);
+ w = PyTuple_New(n);
+ if (w == NULL)
+ return NULL;
+ p = ((PyTupleObject *)w)->ob_item;
+ q = ((PyListObject *)v)->ob_item;
+ while (--n >= 0) {
+ Py_INCREF(*q);
+ *p = *q;
+ p++;
+ q++;
+ }
+ return w;
+}
+
+static PyObject *
+listindex(PyListObject *self, PyObject *args)
+{
+ Py_ssize_t i, start=0, stop=Py_SIZE(self);
+ PyObject *v, *format_tuple, *err_string;
+ static PyObject *err_format = NULL;
+
+ if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+ _PyEval_SliceIndex, &start,
+ _PyEval_SliceIndex, &stop))
+ return NULL;
+ if (start < 0) {
+ start += Py_SIZE(self);
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0) {
+ stop += Py_SIZE(self);
+ if (stop < 0)
+ stop = 0;
+ }
+ for (i = start; i < stop && i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ return PyInt_FromSsize_t(i);
+ else if (cmp < 0)
+ return NULL;
+ }
+ if (err_format == NULL) {
+ err_format = PyString_FromString("%r is not in list");
+ if (err_format == NULL)
+ return NULL;
+ }
+ format_tuple = PyTuple_Pack(1, v);
+ if (format_tuple == NULL)
+ return NULL;
+ err_string = PyString_Format(err_format, format_tuple);
+ Py_DECREF(format_tuple);
+ if (err_string == NULL)
+ return NULL;
+ PyErr_SetObject(PyExc_ValueError, err_string);
+ Py_DECREF(err_string);
+ return NULL;
+}
+
+static PyObject *
+listcount(PyListObject *self, PyObject *v)
+{
+ Py_ssize_t count = 0;
+ Py_ssize_t i;
+
+ for (i = 0; i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ count++;
+ else if (cmp < 0)
+ return NULL;
+ }
+ return PyInt_FromSsize_t(count);
+}
+
+static PyObject *
+listremove(PyListObject *self, PyObject *v)
+{
+ Py_ssize_t i;
+
+ for (i = 0; i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0) {
+ if (list_ass_slice(self, i, i+1,
+ (PyObject *)NULL) == 0)
+ Py_RETURN_NONE;
+ return NULL;
+ }
+ else if (cmp < 0)
+ return NULL;
+ }
+ PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
+ return NULL;
+}
+
+static int
+list_traverse(PyListObject *o, visitproc visit, void *arg)
+{
+ Py_ssize_t i;
+
+ for (i = Py_SIZE(o); --i >= 0; )
+ Py_VISIT(o->ob_item[i]);
+ return 0;
+}
+
+static PyObject *
+list_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyListObject *vl, *wl;
+ Py_ssize_t i;
+
+ if (!PyList_Check(v) || !PyList_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ vl = (PyListObject *)v;
+ wl = (PyListObject *)w;
+
+ if (Py_SIZE(vl) != Py_SIZE(wl) && (op == Py_EQ || op == Py_NE)) {
+ /* Shortcut: if the lengths differ, the lists differ */
+ PyObject *res;
+ if (op == Py_EQ)
+ res = Py_False;
+ else
+ res = Py_True;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* Search for the first index where items are different */
+ for (i = 0; i < Py_SIZE(vl) && i < Py_SIZE(wl); i++) {
+ int k = PyObject_RichCompareBool(vl->ob_item[i],
+ wl->ob_item[i], Py_EQ);
+ if (k < 0)
+ return NULL;
+ if (!k)
+ break;
+ }
+
+ if (i >= Py_SIZE(vl) || i >= Py_SIZE(wl)) {
+ /* No more items to compare -- compare sizes */
+ Py_ssize_t vs = Py_SIZE(vl);
+ Py_ssize_t ws = Py_SIZE(wl);
+ int cmp;
+ PyObject *res;
+ switch (op) {
+ case Py_LT: cmp = vs < ws; break;
+ case Py_LE: cmp = vs <= ws; break;
+ case Py_EQ: cmp = vs == ws; break;
+ case Py_NE: cmp = vs != ws; break;
+ case Py_GT: cmp = vs > ws; break;
+ case Py_GE: cmp = vs >= ws; break;
+ default: return NULL; /* cannot happen */
+ }
+ if (cmp)
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* We have an item that differs -- shortcuts for EQ/NE */
+ if (op == Py_EQ) {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ if (op == Py_NE) {
+ Py_INCREF(Py_True);
+ return Py_True;
+ }
+
+ /* Compare the final item again using the proper operator */
+ return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
+}
+
+static int
+list_init(PyListObject *self, PyObject *args, PyObject *kw)
+{
+ PyObject *arg = NULL;
+ static char *kwlist[] = {"sequence", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg))
+ return -1;
+
+ /* Verify list invariants established by PyType_GenericAlloc() */
+ assert(0 <= Py_SIZE(self));
+ assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
+ assert(self->ob_item != NULL ||
+ self->allocated == 0 || self->allocated == -1);
+
+ /* Empty previous contents */
+ if (self->ob_item != NULL) {
+ (void)list_clear(self);
+ }
+ if (arg != NULL) {
+ PyObject *rv = listextend(self, arg);
+ if (rv == NULL)
+ return -1;
+ Py_DECREF(rv);
+ }
+ return 0;
+}
+
+static PyObject *
+list_sizeof(PyListObject *self)
+{
+ Py_ssize_t res;
+
+ res = sizeof(PyListObject) + self->allocated * sizeof(void*);
+ return PyInt_FromSsize_t(res);
+}
+
+static PyObject *list_iter(PyObject *seq);
+static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
+
+PyDoc_STRVAR(getitem_doc,
+"x.__getitem__(y) <==> x[y]");
+PyDoc_STRVAR(reversed_doc,
+"L.__reversed__() -- return a reverse iterator over the list");
+PyDoc_STRVAR(sizeof_doc,
+"L.__sizeof__() -- size of L in memory, in bytes");
+PyDoc_STRVAR(append_doc,
+"L.append(object) -- append object to end");
+PyDoc_STRVAR(extend_doc,
+"L.extend(iterable) -- extend list by appending elements from the iterable");
+PyDoc_STRVAR(insert_doc,
+"L.insert(index, object) -- insert object before index");
+PyDoc_STRVAR(pop_doc,
+"L.pop([index]) -> item -- remove and return item at index (default last).\n"
+"Raises IndexError if list is empty or index is out of range.");
+PyDoc_STRVAR(remove_doc,
+"L.remove(value) -- remove first occurrence of value.\n"
+"Raises ValueError if the value is not present.");
+PyDoc_STRVAR(index_doc,
+"L.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
+"Raises ValueError if the value is not present.");
+PyDoc_STRVAR(count_doc,
+"L.count(value) -> integer -- return number of occurrences of value");
+PyDoc_STRVAR(reverse_doc,
+"L.reverse() -- reverse *IN PLACE*");
+PyDoc_STRVAR(sort_doc,
+"L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n\
+cmp(x, y) -> -1, 0, 1");
+
+static PyObject *list_subscript(PyListObject*, PyObject*);
+
+static PyMethodDef list_methods[] = {
+ {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
+ {"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
+ {"__sizeof__", (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc},
+ {"append", (PyCFunction)listappend, METH_O, append_doc},
+ {"insert", (PyCFunction)listinsert, METH_VARARGS, insert_doc},
+ {"extend", (PyCFunction)listextend, METH_O, extend_doc},
+ {"pop", (PyCFunction)listpop, METH_VARARGS, pop_doc},
+ {"remove", (PyCFunction)listremove, METH_O, remove_doc},
+ {"index", (PyCFunction)listindex, METH_VARARGS, index_doc},
+ {"count", (PyCFunction)listcount, METH_O, count_doc},
+ {"reverse", (PyCFunction)listreverse, METH_NOARGS, reverse_doc},
+ {"sort", (PyCFunction)listsort, METH_VARARGS | METH_KEYWORDS, sort_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PySequenceMethods list_as_sequence = {
+ (lenfunc)list_length, /* sq_length */
+ (binaryfunc)list_concat, /* sq_concat */
+ (ssizeargfunc)list_repeat, /* sq_repeat */
+ (ssizeargfunc)list_item, /* sq_item */
+ (ssizessizeargfunc)list_slice, /* sq_slice */
+ (ssizeobjargproc)list_ass_item, /* sq_ass_item */
+ (ssizessizeobjargproc)list_ass_slice, /* sq_ass_slice */
+ (objobjproc)list_contains, /* sq_contains */
+ (binaryfunc)list_inplace_concat, /* sq_inplace_concat */
+ (ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */
+};
+
+PyDoc_STRVAR(list_doc,
+"list() -> new empty list\n"
+"list(iterable) -> new list initialized from iterable's items");
+
+
+static PyObject *
+list_subscript(PyListObject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i;
+ i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ PyObject* result;
+ PyObject* it;
+ PyObject **src, **dest;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyList_New(0);
+ }
+ else if (step == 1) {
+ return list_slice(self, start, stop);
+ }
+ else {
+ result = PyList_New(slicelength);
+ if (!result) return NULL;
+
+ src = self->ob_item;
+ dest = ((PyListObject *)result)->ob_item;
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ it = src[cur];
+ Py_INCREF(it);
+ dest[i] = it;
+ }
+
+ return result;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "list indices must be integers, not %.200s",
+ item->ob_type->tp_name);
+ return NULL;
+ }
+}
+
+static int
+list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (step == 1)
+ return list_ass_slice(self, start, stop, value);
+
+ /* Make sure s[5:2] = [..] inserts at the right place:
+ before 5, not before 2. */
+ if ((step < 0 && start < stop) ||
+ (step > 0 && start > stop))
+ stop = start;
+
+ if (value == NULL) {
+ /* delete slice */
+ PyObject **garbage;
+ size_t cur;
+ Py_ssize_t i;
+
+ if (slicelength <= 0)
+ return 0;
+
+ if (step < 0) {
+ stop = start + 1;
+ start = stop + step*(slicelength - 1) - 1;
+ step = -step;
+ }
+
+ assert((size_t)slicelength <=
+ PY_SIZE_MAX / sizeof(PyObject*));
+
+ garbage = (PyObject**)
+ PyMem_MALLOC(slicelength*sizeof(PyObject*));
+ if (!garbage) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ /* drawing pictures might help understand these for
+ loops. Basically, we memmove the parts of the
+ list that are *not* part of the slice: step-1
+ items for each item that is part of the slice,
+ and then tail end of the list that was not
+ covered by the slice */
+ for (cur = start, i = 0;
+ cur < (size_t)stop;
+ cur += step, i++) {
+ Py_ssize_t lim = step - 1;
+
+ garbage[i] = PyList_GET_ITEM(self, cur);
+
+ if (cur + step >= (size_t)Py_SIZE(self)) {
+ lim = Py_SIZE(self) - cur - 1;
+ }
+
+ memmove(self->ob_item + cur - i,
+ self->ob_item + cur + 1,
+ lim * sizeof(PyObject *));
+ }
+ cur = start + slicelength*step;
+ if (cur < (size_t)Py_SIZE(self)) {
+ memmove(self->ob_item + cur - slicelength,
+ self->ob_item + cur,
+ (Py_SIZE(self) - cur) *
+ sizeof(PyObject *));
+ }
+
+ Py_SIZE(self) -= slicelength;
+ list_resize(self, Py_SIZE(self));
+
+ for (i = 0; i < slicelength; i++) {
+ Py_DECREF(garbage[i]);
+ }
+ PyMem_FREE(garbage);
+
+ return 0;
+ }
+ else {
+ /* assign slice */
+ PyObject *ins, *seq;
+ PyObject **garbage, **seqitems, **selfitems;
+ Py_ssize_t cur, i;
+
+ /* protect against a[::-1] = a */
+ if (self == (PyListObject*)value) {
+ seq = list_slice((PyListObject*)value, 0,
+ PyList_GET_SIZE(value));
+ }
+ else {
+ seq = PySequence_Fast(value,
+ "must assign iterable "
+ "to extended slice");
+ }
+ if (!seq)
+ return -1;
+
+ if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
+ PyErr_Format(PyExc_ValueError,
+ "attempt to assign sequence of "
+ "size %zd to extended slice of "
+ "size %zd",
+ PySequence_Fast_GET_SIZE(seq),
+ slicelength);
+ Py_DECREF(seq);
+ return -1;
+ }
+
+ if (!slicelength) {
+ Py_DECREF(seq);
+ return 0;
+ }
+
+ garbage = (PyObject**)
+ PyMem_MALLOC(slicelength*sizeof(PyObject*));
+ if (!garbage) {
+ Py_DECREF(seq);
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ selfitems = self->ob_item;
+ seqitems = PySequence_Fast_ITEMS(seq);
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ garbage[i] = selfitems[cur];
+ ins = seqitems[i];
+ Py_INCREF(ins);
+ selfitems[cur] = ins;
+ }
+
+ for (i = 0; i < slicelength; i++) {
+ Py_DECREF(garbage[i]);
+ }
+
+ PyMem_FREE(garbage);
+ Py_DECREF(seq);
+
+ return 0;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "list indices must be integers, not %.200s",
+ item->ob_type->tp_name);
+ return -1;
+ }
+}
+
+static PyMappingMethods list_as_mapping = {
+ (lenfunc)list_length,
+ (binaryfunc)list_subscript,
+ (objobjargproc)list_ass_subscript
+};
+
+PyTypeObject PyList_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "list",
+ sizeof(PyListObject),
+ 0,
+ (destructor)list_dealloc, /* tp_dealloc */
+ (printfunc)list_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)list_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &list_as_sequence, /* tp_as_sequence */
+ &list_as_mapping, /* tp_as_mapping */
+ (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */
+ list_doc, /* tp_doc */
+ (traverseproc)list_traverse, /* tp_traverse */
+ (inquiry)list_clear, /* tp_clear */
+ list_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ list_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ list_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)list_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/*********************** List Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ long it_index;
+ PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listiterobject;
+
+static PyObject *list_iter(PyObject *);
+static void listiter_dealloc(listiterobject *);
+static int listiter_traverse(listiterobject *, visitproc, void *);
+static PyObject *listiter_next(listiterobject *);
+static PyObject *listiter_len(listiterobject *);
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef listiter_methods[] = {
+ {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyListIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "listiterator", /* tp_name */
+ sizeof(listiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)listiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)listiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)listiter_next, /* tp_iternext */
+ listiter_methods, /* tp_methods */
+ 0, /* tp_members */
+};
+
+
+static PyObject *
+list_iter(PyObject *seq)
+{
+ listiterobject *it;
+
+ if (!PyList_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_GC_New(listiterobject, &PyListIter_Type);
+ if (it == NULL)
+ return NULL;
+ it->it_index = 0;
+ Py_INCREF(seq);
+ it->it_seq = (PyListObject *)seq;
+ _PyObject_GC_TRACK(it);
+ return (PyObject *)it;
+}
+
+static void
+listiter_dealloc(listiterobject *it)
+{
+ _PyObject_GC_UNTRACK(it);
+ Py_XDECREF(it->it_seq);
+ PyObject_GC_Del(it);
+}
+
+static int
+listiter_traverse(listiterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_seq);
+ return 0;
+}
+
+static PyObject *
+listiter_next(listiterobject *it)
+{
+ PyListObject *seq;
+ PyObject *item;
+
+ assert(it != NULL);
+ seq = it->it_seq;
+ if (seq == NULL)
+ return NULL;
+ assert(PyList_Check(seq));
+
+ if (it->it_index < PyList_GET_SIZE(seq)) {
+ item = PyList_GET_ITEM(seq, it->it_index);
+ ++it->it_index;
+ Py_INCREF(item);
+ return item;
+ }
+
+ Py_DECREF(seq);
+ it->it_seq = NULL;
+ return NULL;
+}
+
+static PyObject *
+listiter_len(listiterobject *it)
+{
+ Py_ssize_t len;
+ if (it->it_seq) {
+ len = PyList_GET_SIZE(it->it_seq) - it->it_index;
+ if (len >= 0)
+ return PyInt_FromSsize_t(len);
+ }
+ return PyInt_FromLong(0);
+}
+/*********************** List Reverse Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t it_index;
+ PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
+} listreviterobject;
+
+static PyObject *list_reversed(PyListObject *, PyObject *);
+static void listreviter_dealloc(listreviterobject *);
+static int listreviter_traverse(listreviterobject *, visitproc, void *);
+static PyObject *listreviter_next(listreviterobject *);
+static PyObject *listreviter_len(listreviterobject *);
+
+static PyMethodDef listreviter_methods[] = {
+ {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyListRevIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "listreverseiterator", /* tp_name */
+ sizeof(listreviterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)listreviter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)listreviter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)listreviter_next, /* tp_iternext */
+ listreviter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+list_reversed(PyListObject *seq, PyObject *unused)
+{
+ listreviterobject *it;
+
+ it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
+ if (it == NULL)
+ return NULL;
+ assert(PyList_Check(seq));
+ it->it_index = PyList_GET_SIZE(seq) - 1;
+ Py_INCREF(seq);
+ it->it_seq = seq;
+ PyObject_GC_Track(it);
+ return (PyObject *)it;
+}
+
+static void
+listreviter_dealloc(listreviterobject *it)
+{
+ PyObject_GC_UnTrack(it);
+ Py_XDECREF(it->it_seq);
+ PyObject_GC_Del(it);
+}
+
+static int
+listreviter_traverse(listreviterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_seq);
+ return 0;
+}
+
+static PyObject *
+listreviter_next(listreviterobject *it)
+{
+ PyObject *item;
+ Py_ssize_t index = it->it_index;
+ PyListObject *seq = it->it_seq;
+
+ if (index>=0 && index < PyList_GET_SIZE(seq)) {
+ item = PyList_GET_ITEM(seq, index);
+ it->it_index--;
+ Py_INCREF(item);
+ return item;
+ }
+ it->it_index = -1;
+ if (seq != NULL) {
+ it->it_seq = NULL;
+ Py_DECREF(seq);
+ }
+ return NULL;
+}
+
+static PyObject *
+listreviter_len(listreviterobject *it)
+{
+ Py_ssize_t len = it->it_index + 1;
+ if (it->it_seq == NULL || PyList_GET_SIZE(it->it_seq) < len)
+ len = 0;
+ return PyLong_FromSsize_t(len);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/listsort.txt b/AppPkg/Applications/Python/Python-2.7.10/Objects/listsort.txt
new file mode 100644
index 0000000000..4dd9c17f02
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/listsort.txt
@@ -0,0 +1,755 @@
+Intro
+-----
+This describes an adaptive, stable, natural mergesort, modestly called
+timsort (hey, I earned it <wink>). It has supernatural performance on many
+kinds of partially ordered arrays (less than lg(N!) comparisons needed, and
+as few as N-1), yet as fast as Python's previous highly tuned samplesort
+hybrid on random arrays.
+
+In a nutshell, the main routine marches over the array once, left to right,
+alternately identifying the next run, then merging it into the previous
+runs "intelligently". Everything else is complication for speed, and some
+hard-won measure of memory efficiency.
+
+
+Comparison with Python's Samplesort Hybrid
+------------------------------------------
++ timsort can require a temp array containing as many as N//2 pointers,
+ which means as many as 2*N extra bytes on 32-bit boxes. It can be
+ expected to require a temp array this large when sorting random data; on
+ data with significant structure, it may get away without using any extra
+ heap memory. This appears to be the strongest argument against it, but
+ compared to the size of an object, 2 temp bytes worst-case (also expected-
+ case for random data) doesn't scare me much.
+
+ It turns out that Perl is moving to a stable mergesort, and the code for
+ that appears always to require a temp array with room for at least N
+ pointers. (Note that I wouldn't want to do that even if space weren't an
+ issue; I believe its efforts at memory frugality also save timsort
+ significant pointer-copying costs, and allow it to have a smaller working
+ set.)
+
++ Across about four hours of generating random arrays, and sorting them
+ under both methods, samplesort required about 1.5% more comparisons
+ (the program is at the end of this file).
+
++ In real life, this may be faster or slower on random arrays than
+ samplesort was, depending on platform quirks. Since it does fewer
+ comparisons on average, it can be expected to do better the more
+ expensive a comparison function is. OTOH, it does more data movement
+ (pointer copying) than samplesort, and that may negate its small
+ comparison advantage (depending on platform quirks) unless comparison
+ is very expensive.
+
++ On arrays with many kinds of pre-existing order, this blows samplesort out
+ of the water. It's significantly faster than samplesort even on some
+ cases samplesort was special-casing the snot out of. I believe that lists
+ very often do have exploitable partial order in real life, and this is the
+ strongest argument in favor of timsort (indeed, samplesort's special cases
+ for extreme partial order are appreciated by real users, and timsort goes
+ much deeper than those, in particular naturally covering every case where
+ someone has suggested "and it would be cool if list.sort() had a special
+ case for this too ... and for that ...").
+
++ Here are exact comparison counts across all the tests in sortperf.py,
+ when run with arguments "15 20 1".
+
+ Column Key:
+ *sort: random data
+ \sort: descending data
+ /sort: ascending data
+ 3sort: ascending, then 3 random exchanges
+ +sort: ascending, then 10 random at the end
+ %sort: ascending, then randomly replace 1% of elements w/ random values
+ ~sort: many duplicates
+ =sort: all equal
+ !sort: worst case scenario
+
+ First the trivial cases, trivial for samplesort because it special-cased
+ them, and trivial for timsort because it naturally works on runs. Within
+ an "n" block, the first line gives the # of compares done by samplesort,
+ the second line by timsort, and the third line is the percentage by
+ which the samplesort count exceeds the timsort count:
+
+ n \sort /sort =sort
+------- ------ ------ ------
+ 32768 32768 32767 32767 samplesort
+ 32767 32767 32767 timsort
+ 0.00% 0.00% 0.00% (samplesort - timsort) / timsort
+
+ 65536 65536 65535 65535
+ 65535 65535 65535
+ 0.00% 0.00% 0.00%
+
+ 131072 131072 131071 131071
+ 131071 131071 131071
+ 0.00% 0.00% 0.00%
+
+ 262144 262144 262143 262143
+ 262143 262143 262143
+ 0.00% 0.00% 0.00%
+
+ 524288 524288 524287 524287
+ 524287 524287 524287
+ 0.00% 0.00% 0.00%
+
+1048576 1048576 1048575 1048575
+ 1048575 1048575 1048575
+ 0.00% 0.00% 0.00%
+
+ The algorithms are effectively identical in these cases, except that
+ timsort does one less compare in \sort.
+
+ Now for the more interesting cases. Where lg(x) is the logarithm of x to
+ the base 2 (e.g., lg(8)=3), lg(n!) is the information-theoretic limit for
+ the best any comparison-based sorting algorithm can do on average (across
+ all permutations). When a method gets significantly below that, it's
+ either astronomically lucky, or is finding exploitable structure in the
+ data.
+
+
+ n lg(n!) *sort 3sort +sort %sort ~sort !sort
+------- ------- ------ ------- ------- ------ ------- --------
+ 32768 444255 453096 453614 32908 452871 130491 469141 old
+ 448885 33016 33007 50426 182083 65534 new
+ 0.94% 1273.92% -0.30% 798.09% -28.33% 615.87% %ch from new
+
+ 65536 954037 972699 981940 65686 973104 260029 1004607
+ 962991 65821 65808 101667 364341 131070
+ 1.01% 1391.83% -0.19% 857.15% -28.63% 666.47%
+
+ 131072 2039137 2101881 2091491 131232 2092894 554790 2161379
+ 2057533 131410 131361 206193 728871 262142
+ 2.16% 1491.58% -0.10% 915.02% -23.88% 724.51%
+
+ 262144 4340409 4464460 4403233 262314 4445884 1107842 4584560
+ 4377402 262437 262459 416347 1457945 524286
+ 1.99% 1577.82% -0.06% 967.83% -24.01% 774.44%
+
+ 524288 9205096 9453356 9408463 524468 9441930 2218577 9692015
+ 9278734 524580 524633 837947 2916107 1048574
+ 1.88% 1693.52% -0.03% 1026.79% -23.92% 824.30%
+
+1048576 19458756 19950272 19838588 1048766 19912134 4430649 20434212
+ 19606028 1048958 1048941 1694896 5832445 2097150
+ 1.76% 1791.27% -0.02% 1074.83% -24.03% 874.38%
+
+ Discussion of cases:
+
+ *sort: There's no structure in random data to exploit, so the theoretical
+ limit is lg(n!). Both methods get close to that, and timsort is hugging
+ it (indeed, in a *marginal* sense, it's a spectacular improvement --
+ there's only about 1% left before hitting the wall, and timsort knows
+ darned well it's doing compares that won't pay on random data -- but so
+ does the samplesort hybrid). For contrast, Hoare's original random-pivot
+ quicksort does about 39% more compares than the limit, and the median-of-3
+ variant about 19% more.
+
+ 3sort, %sort, and !sort: No contest; there's structure in this data, but
+ not of the specific kinds samplesort special-cases. Note that structure
+ in !sort wasn't put there on purpose -- it was crafted as a worst case for
+ a previous quicksort implementation. That timsort nails it came as a
+ surprise to me (although it's obvious in retrospect).
+
+ +sort: samplesort special-cases this data, and does a few less compares
+ than timsort. However, timsort runs this case significantly faster on all
+ boxes we have timings for, because timsort is in the business of merging
+ runs efficiently, while samplesort does much more data movement in this
+ (for it) special case.
+
+ ~sort: samplesort's special cases for large masses of equal elements are
+ extremely effective on ~sort's specific data pattern, and timsort just
+ isn't going to get close to that, despite that it's clearly getting a
+ great deal of benefit out of the duplicates (the # of compares is much less
+ than lg(n!)). ~sort has a perfectly uniform distribution of just 4
+ distinct values, and as the distribution gets more skewed, samplesort's
+ equal-element gimmicks become less effective, while timsort's adaptive
+ strategies find more to exploit; in a database supplied by Kevin Altis, a
+ sort on its highly skewed "on which stock exchange does this company's
+ stock trade?" field ran over twice as fast under timsort.
+
+ However, despite that timsort does many more comparisons on ~sort, and
+ that on several platforms ~sort runs highly significantly slower under
+ timsort, on other platforms ~sort runs highly significantly faster under
+ timsort. No other kind of data has shown this wild x-platform behavior,
+ and we don't have an explanation for it. The only thing I can think of
+ that could transform what "should be" highly significant slowdowns into
+ highly significant speedups on some boxes are catastrophic cache effects
+ in samplesort.
+
+ But timsort "should be" slower than samplesort on ~sort, so it's hard
+ to count that it isn't on some boxes as a strike against it <wink>.
+
++ Here's the highwater mark for the number of heap-based temp slots (4
+ bytes each on this box) needed by each test, again with arguments
+ "15 20 1":
+
+ 2**i *sort \sort /sort 3sort +sort %sort ~sort =sort !sort
+ 32768 16384 0 0 6256 0 10821 12288 0 16383
+ 65536 32766 0 0 21652 0 31276 24576 0 32767
+ 131072 65534 0 0 17258 0 58112 49152 0 65535
+ 262144 131072 0 0 35660 0 123561 98304 0 131071
+ 524288 262142 0 0 31302 0 212057 196608 0 262143
+1048576 524286 0 0 312438 0 484942 393216 0 524287
+
+ Discussion: The tests that end up doing (close to) perfectly balanced
+ merges (*sort, !sort) need all N//2 temp slots (or almost all). ~sort
+ also ends up doing balanced merges, but systematically benefits a lot from
+ the preliminary pre-merge searches described under "Merge Memory" later.
+ %sort approaches having a balanced merge at the end because the random
+ selection of elements to replace is expected to produce an out-of-order
+ element near the midpoint. \sort, /sort, =sort are the trivial one-run
+ cases, needing no merging at all. +sort ends up having one very long run
+ and one very short, and so gets all the temp space it needs from the small
+ temparray member of the MergeState struct (note that the same would be
+ true if the new random elements were prefixed to the sorted list instead,
+ but not if they appeared "in the middle"). 3sort approaches N//3 temp
+ slots twice, but the run lengths that remain after 3 random exchanges
+ clearly has very high variance.
+
+
+A detailed description of timsort follows.
+
+Runs
+----
+count_run() returns the # of elements in the next run. A run is either
+"ascending", which means non-decreasing:
+
+ a0 <= a1 <= a2 <= ...
+
+or "descending", which means strictly decreasing:
+
+ a0 > a1 > a2 > ...
+
+Note that a run is always at least 2 long, unless we start at the array's
+last element.
+
+The definition of descending is strict, because the main routine reverses
+a descending run in-place, transforming a descending run into an ascending
+run. Reversal is done via the obvious fast "swap elements starting at each
+end, and converge at the middle" method, and that can violate stability if
+the slice contains any equal elements. Using a strict definition of
+descending ensures that a descending run contains distinct elements.
+
+If an array is random, it's very unlikely we'll see long runs. If a natural
+run contains less than minrun elements (see next section), the main loop
+artificially boosts it to minrun elements, via a stable binary insertion sort
+applied to the right number of array elements following the short natural
+run. In a random array, *all* runs are likely to be minrun long as a
+result. This has two primary good effects:
+
+1. Random data strongly tends then toward perfectly balanced (both runs have
+ the same length) merges, which is the most efficient way to proceed when
+ data is random.
+
+2. Because runs are never very short, the rest of the code doesn't make
+ heroic efforts to shave a few cycles off per-merge overheads. For
+ example, reasonable use of function calls is made, rather than trying to
+ inline everything. Since there are no more than N/minrun runs to begin
+ with, a few "extra" function calls per merge is barely measurable.
+
+
+Computing minrun
+----------------
+If N < 64, minrun is N. IOW, binary insertion sort is used for the whole
+array then; it's hard to beat that given the overheads of trying something
+fancier (see note BINSORT).
+
+When N is a power of 2, testing on random data showed that minrun values of
+16, 32, 64 and 128 worked about equally well. At 256 the data-movement cost
+in binary insertion sort clearly hurt, and at 8 the increase in the number
+of function calls clearly hurt. Picking *some* power of 2 is important
+here, so that the merges end up perfectly balanced (see next section). We
+pick 32 as a good value in the sweet range; picking a value at the low end
+allows the adaptive gimmicks more opportunity to exploit shorter natural
+runs.
+
+Because sortperf.py only tries powers of 2, it took a long time to notice
+that 32 isn't a good choice for the general case! Consider N=2112:
+
+>>> divmod(2112, 32)
+(66, 0)
+>>>
+
+If the data is randomly ordered, we're very likely to end up with 66 runs
+each of length 32. The first 64 of these trigger a sequence of perfectly
+balanced merges (see next section), leaving runs of lengths 2048 and 64 to
+merge at the end. The adaptive gimmicks can do that with fewer than 2048+64
+compares, but it's still more compares than necessary, and-- mergesort's
+bugaboo relative to samplesort --a lot more data movement (O(N) copies just
+to get 64 elements into place).
+
+If we take minrun=33 in this case, then we're very likely to end up with 64
+runs each of length 33, and then all merges are perfectly balanced. Better!
+
+What we want to avoid is picking minrun such that in
+
+ q, r = divmod(N, minrun)
+
+q is a power of 2 and r>0 (then the last merge only gets r elements into
+place, and r < minrun is small compared to N), or q a little larger than a
+power of 2 regardless of r (then we've got a case similar to "2112", again
+leaving too little work for the last merge to do).
+
+Instead we pick a minrun in range(32, 65) such that N/minrun is exactly a
+power of 2, or if that isn't possible, is close to, but strictly less than,
+a power of 2. This is easier to do than it may sound: take the first 6
+bits of N, and add 1 if any of the remaining bits are set. In fact, that
+rule covers every case in this section, including small N and exact powers
+of 2; merge_compute_minrun() is a deceptively simple function.
+
+
+The Merge Pattern
+-----------------
+In order to exploit regularities in the data, we're merging on natural
+run lengths, and they can become wildly unbalanced. That's a Good Thing
+for this sort! It means we have to find a way to manage an assortment of
+potentially very different run lengths, though.
+
+Stability constrains permissible merging patterns. For example, if we have
+3 consecutive runs of lengths
+
+ A:10000 B:20000 C:10000
+
+we dare not merge A with C first, because if A, B and C happen to contain
+a common element, it would get out of order wrt its occurrence(s) in B. The
+merging must be done as (A+B)+C or A+(B+C) instead.
+
+So merging is always done on two consecutive runs at a time, and in-place,
+although this may require some temp memory (more on that later).
+
+When a run is identified, its base address and length are pushed on a stack
+in the MergeState struct. merge_collapse() is then called to see whether it
+should merge it with preceding run(s). We would like to delay merging as
+long as possible in order to exploit patterns that may come up later, but we
+like even more to do merging as soon as possible to exploit that the run just
+found is still high in the memory hierarchy. We also can't delay merging
+"too long" because it consumes memory to remember the runs that are still
+unmerged, and the stack has a fixed size.
+
+What turned out to be a good compromise maintains two invariants on the
+stack entries, where A, B and C are the lengths of the three righmost not-yet
+merged slices:
+
+1. A > B+C
+2. B > C
+
+Note that, by induction, #2 implies the lengths of pending runs form a
+decreasing sequence. #1 implies that, reading the lengths right to left,
+the pending-run lengths grow at least as fast as the Fibonacci numbers.
+Therefore the stack can never grow larger than about log_base_phi(N) entries,
+where phi = (1+sqrt(5))/2 ~= 1.618. Thus a small # of stack slots suffice
+for very large arrays.
+
+If A <= B+C, the smaller of A and C is merged with B (ties favor C, for the
+freshness-in-cache reason), and the new run replaces the A,B or B,C entries;
+e.g., if the last 3 entries are
+
+ A:30 B:20 C:10
+
+then B is merged with C, leaving
+
+ A:30 BC:30
+
+on the stack. Or if they were
+
+ A:500 B:400: C:1000
+
+then A is merged with B, leaving
+
+ AB:900 C:1000
+
+on the stack.
+
+In both examples, the stack configuration after the merge still violates
+invariant #2, and merge_collapse() goes on to continue merging runs until
+both invariants are satisfied. As an extreme case, suppose we didn't do the
+minrun gimmick, and natural runs were of lengths 128, 64, 32, 16, 8, 4, 2,
+and 2. Nothing would get merged until the final 2 was seen, and that would
+trigger 7 perfectly balanced merges.
+
+The thrust of these rules when they trigger merging is to balance the run
+lengths as closely as possible, while keeping a low bound on the number of
+runs we have to remember. This is maximally effective for random data,
+where all runs are likely to be of (artificially forced) length minrun, and
+then we get a sequence of perfectly balanced merges (with, perhaps, some
+oddballs at the end).
+
+OTOH, one reason this sort is so good for partly ordered data has to do
+with wildly unbalanced run lengths.
+
+
+Merge Memory
+------------
+Merging adjacent runs of lengths A and B in-place, and in linear time, is
+difficult. Theoretical constructions are known that can do it, but they're
+too difficult and slow for practical use. But if we have temp memory equal
+to min(A, B), it's easy.
+
+If A is smaller (function merge_lo), copy A to a temp array, leave B alone,
+and then we can do the obvious merge algorithm left to right, from the temp
+area and B, starting the stores into where A used to live. There's always a
+free area in the original area comprising a number of elements equal to the
+number not yet merged from the temp array (trivially true at the start;
+proceed by induction). The only tricky bit is that if a comparison raises an
+exception, we have to remember to copy the remaining elements back in from
+the temp area, lest the array end up with duplicate entries from B. But
+that's exactly the same thing we need to do if we reach the end of B first,
+so the exit code is pleasantly common to both the normal and error cases.
+
+If B is smaller (function merge_hi, which is merge_lo's "mirror image"),
+much the same, except that we need to merge right to left, copying B into a
+temp array and starting the stores at the right end of where B used to live.
+
+A refinement: When we're about to merge adjacent runs A and B, we first do
+a form of binary search (more on that later) to see where B[0] should end up
+in A. Elements in A preceding that point are already in their final
+positions, effectively shrinking the size of A. Likewise we also search to
+see where A[-1] should end up in B, and elements of B after that point can
+also be ignored. This cuts the amount of temp memory needed by the same
+amount.
+
+These preliminary searches may not pay off, and can be expected *not* to
+repay their cost if the data is random. But they can win huge in all of
+time, copying, and memory savings when they do pay, so this is one of the
+"per-merge overheads" mentioned above that we're happy to endure because
+there is at most one very short run. It's generally true in this algorithm
+that we're willing to gamble a little to win a lot, even though the net
+expectation is negative for random data.
+
+
+Merge Algorithms
+----------------
+merge_lo() and merge_hi() are where the bulk of the time is spent. merge_lo
+deals with runs where A <= B, and merge_hi where A > B. They don't know
+whether the data is clustered or uniform, but a lovely thing about merging
+is that many kinds of clustering "reveal themselves" by how many times in a
+row the winning merge element comes from the same run. We'll only discuss
+merge_lo here; merge_hi is exactly analogous.
+
+Merging begins in the usual, obvious way, comparing the first element of A
+to the first of B, and moving B[0] to the merge area if it's less than A[0],
+else moving A[0] to the merge area. Call that the "one pair at a time"
+mode. The only twist here is keeping track of how many times in a row "the
+winner" comes from the same run.
+
+If that count reaches MIN_GALLOP, we switch to "galloping mode". Here
+we *search* B for where A[0] belongs, and move over all the B's before
+that point in one chunk to the merge area, then move A[0] to the merge
+area. Then we search A for where B[0] belongs, and similarly move a
+slice of A in one chunk. Then back to searching B for where A[0] belongs,
+etc. We stay in galloping mode until both searches find slices to copy
+less than MIN_GALLOP elements long, at which point we go back to one-pair-
+at-a-time mode.
+
+A refinement: The MergeState struct contains the value of min_gallop that
+controls when we enter galloping mode, initialized to MIN_GALLOP.
+merge_lo() and merge_hi() adjust this higher when galloping isn't paying
+off, and lower when it is.
+
+
+Galloping
+---------
+Still without loss of generality, assume A is the shorter run. In galloping
+mode, we first look for A[0] in B. We do this via "galloping", comparing
+A[0] in turn to B[0], B[1], B[3], B[7], ..., B[2**j - 1], ..., until finding
+the k such that B[2**(k-1) - 1] < A[0] <= B[2**k - 1]. This takes at most
+roughly lg(B) comparisons, and, unlike a straight binary search, favors
+finding the right spot early in B (more on that later).
+
+After finding such a k, the region of uncertainty is reduced to 2**(k-1) - 1
+consecutive elements, and a straight binary search requires exactly k-1
+additional comparisons to nail it (see note REGION OF UNCERTAINTY). Then we
+copy all the B's up to that point in one chunk, and then copy A[0]. Note
+that no matter where A[0] belongs in B, the combination of galloping + binary
+search finds it in no more than about 2*lg(B) comparisons.
+
+If we did a straight binary search, we could find it in no more than
+ceiling(lg(B+1)) comparisons -- but straight binary search takes that many
+comparisons no matter where A[0] belongs. Straight binary search thus loses
+to galloping unless the run is quite long, and we simply can't guess
+whether it is in advance.
+
+If data is random and runs have the same length, A[0] belongs at B[0] half
+the time, at B[1] a quarter of the time, and so on: a consecutive winning
+sub-run in B of length k occurs with probability 1/2**(k+1). So long
+winning sub-runs are extremely unlikely in random data, and guessing that a
+winning sub-run is going to be long is a dangerous game.
+
+OTOH, if data is lopsided or lumpy or contains many duplicates, long
+stretches of winning sub-runs are very likely, and cutting the number of
+comparisons needed to find one from O(B) to O(log B) is a huge win.
+
+Galloping compromises by getting out fast if there isn't a long winning
+sub-run, yet finding such very efficiently when they exist.
+
+I first learned about the galloping strategy in a related context; see:
+
+ "Adaptive Set Intersections, Unions, and Differences" (2000)
+ Erik D. Demaine, Alejandro López-Ortiz, J. Ian Munro
+
+and its followup(s). An earlier paper called the same strategy
+"exponential search":
+
+ "Optimistic Sorting and Information Theoretic Complexity"
+ Peter McIlroy
+ SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), pp
+ 467-474, Austin, Texas, 25-27 January 1993.
+
+and it probably dates back to an earlier paper by Bentley and Yao. The
+McIlroy paper in particular has good analysis of a mergesort that's
+probably strongly related to this one in its galloping strategy.
+
+
+Galloping with a Broken Leg
+---------------------------
+So why don't we always gallop? Because it can lose, on two counts:
+
+1. While we're willing to endure small per-merge overheads, per-comparison
+ overheads are a different story. Calling Yet Another Function per
+ comparison is expensive, and gallop_left() and gallop_right() are
+ too long-winded for sane inlining.
+
+2. Galloping can-- alas --require more comparisons than linear one-at-time
+ search, depending on the data.
+
+#2 requires details. If A[0] belongs before B[0], galloping requires 1
+compare to determine that, same as linear search, except it costs more
+to call the gallop function. If A[0] belongs right before B[1], galloping
+requires 2 compares, again same as linear search. On the third compare,
+galloping checks A[0] against B[3], and if it's <=, requires one more
+compare to determine whether A[0] belongs at B[2] or B[3]. That's a total
+of 4 compares, but if A[0] does belong at B[2], linear search would have
+discovered that in only 3 compares, and that's a huge loss! Really. It's
+an increase of 33% in the number of compares needed, and comparisons are
+expensive in Python.
+
+index in B where # compares linear # gallop # binary gallop
+A[0] belongs search needs compares compares total
+---------------- ----------------- -------- -------- ------
+ 0 1 1 0 1
+
+ 1 2 2 0 2
+
+ 2 3 3 1 4
+ 3 4 3 1 4
+
+ 4 5 4 2 6
+ 5 6 4 2 6
+ 6 7 4 2 6
+ 7 8 4 2 6
+
+ 8 9 5 3 8
+ 9 10 5 3 8
+ 10 11 5 3 8
+ 11 12 5 3 8
+ ...
+
+In general, if A[0] belongs at B[i], linear search requires i+1 comparisons
+to determine that, and galloping a total of 2*floor(lg(i))+2 comparisons.
+The advantage of galloping is unbounded as i grows, but it doesn't win at
+all until i=6. Before then, it loses twice (at i=2 and i=4), and ties
+at the other values. At and after i=6, galloping always wins.
+
+We can't guess in advance when it's going to win, though, so we do one pair
+at a time until the evidence seems strong that galloping may pay. MIN_GALLOP
+is 7, and that's pretty strong evidence. However, if the data is random, it
+simply will trigger galloping mode purely by luck every now and again, and
+it's quite likely to hit one of the losing cases next. On the other hand,
+in cases like ~sort, galloping always pays, and MIN_GALLOP is larger than it
+"should be" then. So the MergeState struct keeps a min_gallop variable
+that merge_lo and merge_hi adjust: the longer we stay in galloping mode,
+the smaller min_gallop gets, making it easier to transition back to
+galloping mode (if we ever leave it in the current merge, and at the
+start of the next merge). But whenever the gallop loop doesn't pay,
+min_gallop is increased by one, making it harder to transition back
+to galloping mode (and again both within a merge and across merges). For
+random data, this all but eliminates the gallop penalty: min_gallop grows
+large enough that we almost never get into galloping mode. And for cases
+like ~sort, min_gallop can fall to as low as 1. This seems to work well,
+but in all it's a minor improvement over using a fixed MIN_GALLOP value.
+
+
+Galloping Complication
+----------------------
+The description above was for merge_lo. merge_hi has to merge "from the
+other end", and really needs to gallop starting at the last element in a run
+instead of the first. Galloping from the first still works, but does more
+comparisons than it should (this is significant -- I timed it both ways). For
+this reason, the gallop_left() and gallop_right() (see note LEFT OR RIGHT)
+functions have a "hint" argument, which is the index at which galloping
+should begin. So galloping can actually start at any index, and proceed at
+offsets of 1, 3, 7, 15, ... or -1, -3, -7, -15, ... from the starting index.
+
+In the code as I type it's always called with either 0 or n-1 (where n is
+the # of elements in a run). It's tempting to try to do something fancier,
+melding galloping with some form of interpolation search; for example, if
+we're merging a run of length 1 with a run of length 10000, index 5000 is
+probably a better guess at the final result than either 0 or 9999. But
+it's unclear how to generalize that intuition usefully, and merging of
+wildly unbalanced runs already enjoys excellent performance.
+
+~sort is a good example of when balanced runs could benefit from a better
+hint value: to the extent possible, this would like to use a starting
+offset equal to the previous value of acount/bcount. Doing so saves about
+10% of the compares in ~sort. However, doing so is also a mixed bag,
+hurting other cases.
+
+
+Comparing Average # of Compares on Random Arrays
+------------------------------------------------
+[NOTE: This was done when the new algorithm used about 0.1% more compares
+ on random data than does its current incarnation.]
+
+Here list.sort() is samplesort, and list.msort() this sort:
+
+"""
+import random
+from time import clock as now
+
+def fill(n):
+ from random import random
+ return [random() for i in xrange(n)]
+
+def mycmp(x, y):
+ global ncmp
+ ncmp += 1
+ return cmp(x, y)
+
+def timeit(values, method):
+ global ncmp
+ X = values[:]
+ bound = getattr(X, method)
+ ncmp = 0
+ t1 = now()
+ bound(mycmp)
+ t2 = now()
+ return t2-t1, ncmp
+
+format = "%5s %9.2f %11d"
+f2 = "%5s %9.2f %11.2f"
+
+def drive():
+ count = sst = sscmp = mst = mscmp = nelts = 0
+ while True:
+ n = random.randrange(100000)
+ nelts += n
+ x = fill(n)
+
+ t, c = timeit(x, 'sort')
+ sst += t
+ sscmp += c
+
+ t, c = timeit(x, 'msort')
+ mst += t
+ mscmp += c
+
+ count += 1
+ if count % 10:
+ continue
+
+ print "count", count, "nelts", nelts
+ print format % ("sort", sst, sscmp)
+ print format % ("msort", mst, mscmp)
+ print f2 % ("", (sst-mst)*1e2/mst, (sscmp-mscmp)*1e2/mscmp)
+
+drive()
+"""
+
+I ran this on Windows and kept using the computer lightly while it was
+running. time.clock() is wall-clock time on Windows, with better than
+microsecond resolution. samplesort started with a 1.52% #-of-comparisons
+disadvantage, fell quickly to 1.48%, and then fluctuated within that small
+range. Here's the last chunk of output before I killed the job:
+
+count 2630 nelts 130906543
+ sort 6110.80 1937887573
+msort 6002.78 1909389381
+ 1.80 1.49
+
+We've done nearly 2 billion comparisons apiece at Python speed there, and
+that's enough <wink>.
+
+For random arrays of size 2 (yes, there are only 2 interesting ones),
+samplesort has a 50%(!) comparison disadvantage. This is a consequence of
+samplesort special-casing at most one ascending run at the start, then
+falling back to the general case if it doesn't find an ascending run
+immediately. The consequence is that it ends up using two compares to sort
+[2, 1]. Gratifyingly, timsort doesn't do any special-casing, so had to be
+taught how to deal with mixtures of ascending and descending runs
+efficiently in all cases.
+
+
+NOTES
+-----
+
+BINSORT
+A "binary insertion sort" is just like a textbook insertion sort, but instead
+of locating the correct position of the next item via linear (one at a time)
+search, an equivalent to Python's bisect.bisect_right is used to find the
+correct position in logarithmic time. Most texts don't mention this
+variation, and those that do usually say it's not worth the bother: insertion
+sort remains quadratic (expected and worst cases) either way. Speeding the
+search doesn't reduce the quadratic data movement costs.
+
+But in CPython's case, comparisons are extraordinarily expensive compared to
+moving data, and the details matter. Moving objects is just copying
+pointers. Comparisons can be arbitrarily expensive (can invoke arbitary
+user-supplied Python code), but even in simple cases (like 3 < 4) _all_
+decisions are made at runtime: what's the type of the left comparand? the
+type of the right? do they need to be coerced to a common type? where's the
+code to compare these types? And so on. Even the simplest Python comparison
+triggers a large pile of C-level pointer dereferences, conditionals, and
+function calls.
+
+So cutting the number of compares is almost always measurably helpful in
+CPython, and the savings swamp the quadratic-time data movement costs for
+reasonable minrun values.
+
+
+LEFT OR RIGHT
+gallop_left() and gallop_right() are akin to the Python bisect module's
+bisect_left() and bisect_right(): they're the same unless the slice they're
+searching contains a (at least one) value equal to the value being searched
+for. In that case, gallop_left() returns the position immediately before the
+leftmost equal value, and gallop_right() the position immediately after the
+rightmost equal value. The distinction is needed to preserve stability. In
+general, when merging adjacent runs A and B, gallop_left is used to search
+thru B for where an element from A belongs, and gallop_right to search thru A
+for where an element from B belongs.
+
+
+REGION OF UNCERTAINTY
+Two kinds of confusion seem to be common about the claim that after finding
+a k such that
+
+ B[2**(k-1) - 1] < A[0] <= B[2**k - 1]
+
+then a binary search requires exactly k-1 tries to find A[0]'s proper
+location. For concreteness, say k=3, so B[3] < A[0] <= B[7].
+
+The first confusion takes the form "OK, then the region of uncertainty is at
+indices 3, 4, 5, 6 and 7: that's 5 elements, not the claimed 2**(k-1) - 1 =
+3"; or the region is viewed as a Python slice and the objection is "but that's
+the slice B[3:7], so has 7-3 = 4 elements". Resolution: we've already
+compared A[0] against B[3] and against B[7], so A[0]'s correct location is
+already known wrt _both_ endpoints. What remains is to find A[0]'s correct
+location wrt B[4], B[5] and B[6], which spans 3 elements. Or in general, the
+slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1
+inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has
+ (2**k-1)-1 - 2**(k-1) + 1 =
+ 2**k-1 - 2**(k-1) =
+ 2*2**k-1 - 2**(k-1) =
+ (2-1)*2**(k-1) - 1 =
+ 2**(k-1) - 1
+elements.
+
+The second confusion: "k-1 = 2 binary searches can find the correct location
+among 2**(k-1) = 4 elements, but you're only applying it to 3 elements: we
+could make this more efficient by arranging for the region of uncertainty to
+span 2**(k-1) elements." Resolution: that confuses "elements" with
+"locations". In a slice with N elements, there are N+1 _locations_. In the
+example, with the region of uncertainty B[4], B[5], B[6], there are 4
+locations: before B[4], between B[4] and B[5], between B[5] and B[6], and
+after B[6]. In general, across 2**(k-1)-1 elements, there are 2**(k-1)
+locations. That's why k-1 binary searches are necessary and sufficient.
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/lnotab_notes.txt b/AppPkg/Applications/Python/Python-2.7.10/Objects/lnotab_notes.txt
new file mode 100644
index 0000000000..c9d45cf861
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/lnotab_notes.txt
@@ -0,0 +1,124 @@
+All about co_lnotab, the line number table.
+
+Code objects store a field named co_lnotab. This is an array of unsigned bytes
+disguised as a Python string. It is used to map bytecode offsets to source code
+line #s for tracebacks and to identify line number boundaries for line tracing.
+
+The array is conceptually a compressed list of
+ (bytecode offset increment, line number increment)
+pairs. The details are important and delicate, best illustrated by example:
+
+ byte code offset source code line number
+ 0 1
+ 6 2
+ 50 7
+ 350 307
+ 361 308
+
+Instead of storing these numbers literally, we compress the list by storing only
+the increments from one row to the next. Conceptually, the stored list might
+look like:
+
+ 0, 1, 6, 1, 44, 5, 300, 300, 11, 1
+
+The above doesn't really work, but it's a start. Note that an unsigned byte
+can't hold negative values, or values larger than 255, and the above example
+contains two such values. So we make two tweaks:
+
+ (a) there's a deep assumption that byte code offsets and their corresponding
+ line #s both increase monotonically, and
+ (b) if at least one column jumps by more than 255 from one row to the next,
+ more than one pair is written to the table. In case #b, there's no way to know
+ from looking at the table later how many were written. That's the delicate
+ part. A user of co_lnotab desiring to find the source line number
+ corresponding to a bytecode address A should do something like this
+
+ lineno = addr = 0
+ for addr_incr, line_incr in co_lnotab:
+ addr += addr_incr
+ if addr > A:
+ return lineno
+ lineno += line_incr
+
+(In C, this is implemented by PyCode_Addr2Line().) In order for this to work,
+when the addr field increments by more than 255, the line # increment in each
+pair generated must be 0 until the remaining addr increment is < 256. So, in
+the example above, assemble_lnotab in compile.c should not (as was actually done
+until 2.2) expand 300, 300 to
+ 255, 255, 45, 45,
+but to
+ 255, 0, 45, 255, 0, 45.
+
+The above is sufficient to reconstruct line numbers for tracebacks, but not for
+line tracing. Tracing is handled by PyCode_CheckLineNumber() in codeobject.c
+and maybe_call_line_trace() in ceval.c.
+
+*** Tracing ***
+
+To a first approximation, we want to call the tracing function when the line
+number of the current instruction changes. Re-computing the current line for
+every instruction is a little slow, though, so each time we compute the line
+number we save the bytecode indices where it's valid:
+
+ *instr_lb <= frame->f_lasti < *instr_ub
+
+is true so long as execution does not change lines. That is, *instr_lb holds
+the first bytecode index of the current line, and *instr_ub holds the first
+bytecode index of the next line. As long as the above expression is true,
+maybe_call_line_trace() does not need to call PyCode_CheckLineNumber(). Note
+that the same line may appear multiple times in the lnotab, either because the
+bytecode jumped more than 255 indices between line number changes or because
+the compiler inserted the same line twice. Even in that case, *instr_ub holds
+the first index of the next line.
+
+However, we don't *always* want to call the line trace function when the above
+test fails.
+
+Consider this code:
+
+1: def f(a):
+2: while a:
+3: print 1,
+4: break
+5: else:
+6: print 2,
+
+which compiles to this:
+
+ 2 0 SETUP_LOOP 19 (to 22)
+ >> 3 LOAD_FAST 0 (a)
+ 6 POP_JUMP_IF_FALSE 17
+
+ 3 9 LOAD_CONST 1 (1)
+ 12 PRINT_ITEM
+
+ 4 13 BREAK_LOOP
+ 14 JUMP_ABSOLUTE 3
+ >> 17 POP_BLOCK
+
+ 6 18 LOAD_CONST 2 (2)
+ 21 PRINT_ITEM
+ >> 22 LOAD_CONST 0 (None)
+ 25 RETURN_VALUE
+
+If 'a' is false, execution will jump to the POP_BLOCK instruction at offset 17
+and the co_lnotab will claim that execution has moved to line 4, which is wrong.
+In this case, we could instead associate the POP_BLOCK with line 5, but that
+would break jumps around loops without else clauses.
+
+We fix this by only calling the line trace function for a forward jump if the
+co_lnotab indicates we have jumped to the *start* of a line, i.e. if the current
+instruction offset matches the offset given for the start of a line by the
+co_lnotab. For backward jumps, however, we always call the line trace function,
+which lets a debugger stop on every evaluation of a loop guard (which usually
+won't be the first opcode in a line).
+
+Why do we set f_lineno when tracing, and only just before calling the trace
+function? Well, consider the code above when 'a' is true. If stepping through
+this with 'n' in pdb, you would stop at line 1 with a "call" type event, then
+line events on lines 2, 3, and 4, then a "return" type event -- but because the
+code for the return actually falls in the range of the "line 6" opcodes, you
+would be shown line 6 during this event. This is a change from the behaviour in
+2.2 and before, and I've found it confusing in practice. By setting and using
+f_lineno when tracing, one can report a line number different from that
+suggested by f_lasti on this one occasion where it's desirable.
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c
new file mode 100644
index 0000000000..00da8b995e
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c
@@ -0,0 +1,842 @@
+
+/* Memoryview object implementation */
+
+#include "Python.h"
+
+static Py_ssize_t
+get_shape0(Py_buffer *buf)
+{
+ if (buf->shape != NULL)
+ return buf->shape[0];
+ if (buf->ndim == 0)
+ return 1;
+ PyErr_SetString(PyExc_TypeError,
+ "exported buffer does not have any shape information associated "
+ "to it");
+ return -1;
+}
+
+static void
+dup_buffer(Py_buffer *dest, Py_buffer *src)
+{
+ *dest = *src;
+ if (src->ndim == 1 && src->shape != NULL) {
+ dest->shape = &(dest->smalltable[0]);
+ dest->shape[0] = get_shape0(src);
+ }
+ if (src->ndim == 1 && src->strides != NULL) {
+ dest->strides = &(dest->smalltable[1]);
+ dest->strides[0] = src->strides[0];
+ }
+}
+
+static int
+memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
+{
+ int res = 0;
+ if (self->view.obj != NULL)
+ res = PyObject_GetBuffer(self->view.obj, view, flags);
+ if (view)
+ dup_buffer(view, &self->view);
+ return res;
+}
+
+static void
+memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
+{
+ PyBuffer_Release(view);
+}
+
+PyDoc_STRVAR(memory_doc,
+"memoryview(object)\n\
+\n\
+Create a new memoryview object which references the given object.");
+
+PyObject *
+PyMemoryView_FromBuffer(Py_buffer *info)
+{
+ PyMemoryViewObject *mview;
+
+ mview = (PyMemoryViewObject *)
+ PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mview == NULL)
+ return NULL;
+ mview->base = NULL;
+ dup_buffer(&mview->view, info);
+ /* NOTE: mview->view.obj should already have been incref'ed as
+ part of PyBuffer_FillInfo(). */
+ _PyObject_GC_TRACK(mview);
+ return (PyObject *)mview;
+}
+
+PyObject *
+PyMemoryView_FromObject(PyObject *base)
+{
+ PyMemoryViewObject *mview;
+ Py_buffer view;
+
+ if (!PyObject_CheckBuffer(base)) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot make memory view because object does "
+ "not have the buffer interface");
+ return NULL;
+ }
+
+ if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
+ return NULL;
+
+ mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
+ if (mview == NULL) {
+ PyBuffer_Release(&view);
+ return NULL;
+ }
+
+ mview->base = base;
+ Py_INCREF(base);
+ return (PyObject *)mview;
+}
+
+static PyObject *
+memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+{
+ PyObject *obj;
+ static char *kwlist[] = {"object", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
+ &obj)) {
+ return NULL;
+ }
+
+ return PyMemoryView_FromObject(obj);
+}
+
+
+static void
+_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
+ Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
+{
+ int k;
+ Py_ssize_t outstride;
+
+ if (nd==0) {
+ memcpy(dest, src, itemsize);
+ }
+ else if (nd == 1) {
+ for (k = 0; k<shape[0]; k++) {
+ memcpy(dest, src, itemsize);
+ dest += itemsize;
+ src += strides[0];
+ }
+ }
+ else {
+ if (fort == 'F') {
+ /* Copy first dimension first,
+ second dimension second, etc...
+ Set up the recursive loop backwards so that final
+ dimension is actually copied last.
+ */
+ outstride = itemsize;
+ for (k=1; k<nd-1;k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[nd-1]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape,
+ strides, itemsize, fort);
+ dest += outstride;
+ src += strides[nd-1];
+ }
+ }
+
+ else {
+ /* Copy last dimension first,
+ second-to-last dimension second, etc.
+ Set up the recursion so that the
+ first dimension is copied last
+ */
+ outstride = itemsize;
+ for (k=1; k < nd; k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[0]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape+1,
+ strides+1, itemsize,
+ fort);
+ dest += outstride;
+ src += strides[0];
+ }
+ }
+ }
+ return;
+}
+
+static int
+_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
+{
+ Py_ssize_t *indices;
+ int k;
+ Py_ssize_t elements;
+ char *ptr;
+ void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
+
+ if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ for (k=0; k<view->ndim;k++) {
+ indices[k] = 0;
+ }
+
+ elements = 1;
+ for (k=0; k<view->ndim; k++) {
+ elements *= view->shape[k];
+ }
+ if (fort == 'F') {
+ func = _Py_add_one_to_index_F;
+ }
+ else {
+ func = _Py_add_one_to_index_C;
+ }
+ while (elements--) {
+ func(view->ndim, indices, view->shape);
+ ptr = PyBuffer_GetPointer(view, indices);
+ memcpy(dest, ptr, view->itemsize);
+ dest += view->itemsize;
+ }
+
+ PyMem_Free(indices);
+ return 0;
+}
+
+/*
+ Get a the data from an object as a contiguous chunk of memory (in
+ either 'C' or 'F'ortran order) even if it means copying it into a
+ separate memory area.
+
+ Returns a new reference to a Memory view object. If no copy is needed,
+ the memory view object points to the original memory and holds a
+ lock on the original. If a copy is needed, then the memory view object
+ points to a brand-new Bytes object (and holds a memory lock on it).
+
+ buffertype
+
+ PyBUF_READ buffer only needs to be read-only
+ PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
+ PyBUF_SHADOW buffer needs to be writable so shadow it with
+ a contiguous buffer if it is not. The view will point to
+ the shadow buffer which can be written to and then
+ will be copied back into the other buffer when the memory
+ view is de-allocated. While the shadow buffer is
+ being used, it will have an exclusive write lock on
+ the original buffer.
+ */
+
+PyObject *
+PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
+{
+ PyMemoryViewObject *mem;
+ PyObject *bytes;
+ Py_buffer *view;
+ int flags;
+ char *dest;
+
+ if (!PyObject_CheckBuffer(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "object does not have the buffer interface");
+ return NULL;
+ }
+
+ mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mem == NULL)
+ return NULL;
+
+ view = &mem->view;
+ flags = PyBUF_FULL_RO;
+ switch(buffertype) {
+ case PyBUF_WRITE:
+ flags = PyBUF_FULL;
+ break;
+ }
+
+ if (PyObject_GetBuffer(obj, view, flags) != 0) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+
+ if (PyBuffer_IsContiguous(view, fort)) {
+ /* no copy needed */
+ Py_INCREF(obj);
+ mem->base = obj;
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
+ }
+ /* otherwise a copy is needed */
+ if (buffertype == PyBUF_WRITE) {
+ Py_DECREF(mem);
+ PyErr_SetString(PyExc_BufferError,
+ "writable contiguous buffer requested "
+ "for a non-contiguousobject.");
+ return NULL;
+ }
+ bytes = PyBytes_FromStringAndSize(NULL, view->len);
+ if (bytes == NULL) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+ dest = PyBytes_AS_STRING(bytes);
+ /* different copying strategy depending on whether
+ or not any pointer de-referencing is needed
+ */
+ /* strided or in-direct copy */
+ if (view->suboffsets==NULL) {
+ _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
+ view->strides, view->itemsize, fort);
+ }
+ else {
+ if (_indirect_copy_nd(dest, view, fort) < 0) {
+ Py_DECREF(bytes);
+ Py_DECREF(mem);
+ return NULL;
+ }
+ }
+ if (buffertype == PyBUF_SHADOW) {
+ /* return a shadowed memory-view object */
+ view->buf = dest;
+ mem->base = PyTuple_Pack(2, obj, bytes);
+ Py_DECREF(bytes);
+ if (mem->base == NULL) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+ }
+ else {
+ PyBuffer_Release(view); /* XXX ? */
+ /* steal the reference */
+ mem->base = bytes;
+ }
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
+}
+
+
+static PyObject *
+memory_format_get(PyMemoryViewObject *self)
+{
+ return PyString_FromString(self->view.format);
+}
+
+static PyObject *
+memory_itemsize_get(PyMemoryViewObject *self)
+{
+ return PyLong_FromSsize_t(self->view.itemsize);
+}
+
+static PyObject *
+_IntTupleFromSsizet(int len, Py_ssize_t *vals)
+{
+ int i;
+ PyObject *o;
+ PyObject *intTuple;
+
+ if (vals == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ intTuple = PyTuple_New(len);
+ if (!intTuple) return NULL;
+ for(i=0; i<len; i++) {
+ o = PyLong_FromSsize_t(vals[i]);
+ if (!o) {
+ Py_DECREF(intTuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(intTuple, i, o);
+ }
+ return intTuple;
+}
+
+static PyObject *
+memory_shape_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
+}
+
+static PyObject *
+memory_strides_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
+}
+
+static PyObject *
+memory_suboffsets_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
+}
+
+static PyObject *
+memory_readonly_get(PyMemoryViewObject *self)
+{
+ return PyBool_FromLong(self->view.readonly);
+}
+
+static PyObject *
+memory_ndim_get(PyMemoryViewObject *self)
+{
+ return PyLong_FromLong(self->view.ndim);
+}
+
+static PyGetSetDef memory_getsetlist[] ={
+ {"format", (getter)memory_format_get, NULL, NULL},
+ {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
+ {"shape", (getter)memory_shape_get, NULL, NULL},
+ {"strides", (getter)memory_strides_get, NULL, NULL},
+ {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
+ {"readonly", (getter)memory_readonly_get, NULL, NULL},
+ {"ndim", (getter)memory_ndim_get, NULL, NULL},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+static PyObject *
+memory_tobytes(PyMemoryViewObject *self, PyObject *noargs)
+{
+ Py_buffer view;
+ PyObject *res;
+
+ if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_SIMPLE) < 0)
+ return NULL;
+
+ res = PyBytes_FromStringAndSize(NULL, view.len);
+ PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
+ PyBuffer_Release(&view);
+ return res;
+}
+
+/* TODO: rewrite this function using the struct module to unpack
+ each buffer item */
+
+static PyObject *
+memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
+{
+ Py_buffer *view = &(mem->view);
+ Py_ssize_t i;
+ PyObject *res, *item;
+ char *buf;
+
+ if (strcmp(view->format, "B") || view->itemsize != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports byte views");
+ return NULL;
+ }
+ if (view->ndim != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports one-dimensional objects");
+ return NULL;
+ }
+ res = PyList_New(view->len);
+ if (res == NULL)
+ return NULL;
+ buf = view->buf;
+ for (i = 0; i < view->len; i++) {
+ item = PyInt_FromLong((unsigned char) *buf);
+ if (item == NULL) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ PyList_SET_ITEM(res, i, item);
+ buf++;
+ }
+ return res;
+}
+
+static PyMethodDef memory_methods[] = {
+ {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+ {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static void
+memory_dealloc(PyMemoryViewObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ if (self->view.obj != NULL) {
+ if (self->base && PyTuple_Check(self->base)) {
+ /* Special case when first element is generic object
+ with buffer interface and the second element is a
+ contiguous "shadow" that must be copied back into
+ the data areay of the first tuple element before
+ releasing the buffer on the first element.
+ */
+
+ PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
+ PyTuple_GET_ITEM(self->base,1));
+
+ /* The view member should have readonly == -1 in
+ this instance indicating that the memory can
+ be "locked" and was locked and will be unlocked
+ again after this call.
+ */
+ PyBuffer_Release(&(self->view));
+ }
+ else {
+ PyBuffer_Release(&(self->view));
+ }
+ Py_CLEAR(self->base);
+ }
+ PyObject_GC_Del(self);
+}
+
+static PyObject *
+memory_repr(PyMemoryViewObject *self)
+{
+ return PyString_FromFormat("<memory at %p>", self);
+}
+
+/* Sequence methods */
+static Py_ssize_t
+memory_length(PyMemoryViewObject *self)
+{
+ return get_shape0(&self->view);
+}
+
+/* Alternate version of memory_subcript that only accepts indices.
+ Used by PySeqIter_New().
+*/
+static PyObject *
+memory_item(PyMemoryViewObject *self, Py_ssize_t result)
+{
+ Py_buffer *view = &(self->view);
+
+ if (view->ndim == 0) {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
+ if (view->ndim == 1) {
+ /* Return a bytes object */
+ char *ptr;
+ ptr = (char *)view->buf;
+ if (result < 0) {
+ result += get_shape0(view);
+ }
+ if ((result < 0) || (result >= get_shape0(view))) {
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return NULL;
+ }
+ if (view->strides == NULL)
+ ptr += view->itemsize * result;
+ else
+ ptr += view->strides[0] * result;
+ if (view->suboffsets != NULL &&
+ view->suboffsets[0] >= 0) {
+ ptr = *((char **)ptr) + view->suboffsets[0];
+ }
+ return PyBytes_FromStringAndSize(ptr, view->itemsize);
+ } else {
+ /* Return a new memory-view object */
+ Py_buffer newview;
+ memset(&newview, 0, sizeof(newview));
+ /* XXX: This needs to be fixed so it actually returns a sub-view */
+ return PyMemoryView_FromBuffer(&newview);
+ }
+}
+
+/*
+ mem[obj] returns a bytes object holding the data for one element if
+ obj fully indexes the memory view or another memory-view object
+ if it does not.
+
+ 0-d memory-view objects can be referenced using ... or () but
+ not with anything else.
+ */
+static PyObject *
+memory_subscript(PyMemoryViewObject *self, PyObject *key)
+{
+ Py_buffer *view;
+ view = &(self->view);
+
+ if (view->ndim == 0) {
+ if (key == Py_Ellipsis ||
+ (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
+ }
+ if (PyIndex_Check(key)) {
+ Py_ssize_t result;
+ result = PyNumber_AsSsize_t(key, NULL);
+ if (result == -1 && PyErr_Occurred())
+ return NULL;
+ return memory_item(self, result);
+ }
+ else if (PySlice_Check(key)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (step == 1 && view->ndim == 1) {
+ Py_buffer newview;
+ void *newbuf = (char *) view->buf
+ + start * view->itemsize;
+ int newflags = view->readonly
+ ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
+
+ /* XXX There should be an API to create a subbuffer */
+ if (view->obj != NULL) {
+ if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
+ return NULL;
+ }
+ else {
+ newview = *view;
+ }
+ newview.buf = newbuf;
+ newview.len = slicelength * newview.itemsize;
+ newview.format = view->format;
+ newview.shape = &(newview.smalltable[0]);
+ newview.shape[0] = slicelength;
+ newview.strides = &(newview.itemsize);
+ return PyMemoryView_FromBuffer(&newview);
+ }
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "cannot index memory using \"%.200s\"",
+ key->ob_type->tp_name);
+ return NULL;
+}
+
+
+/* Need to support assigning memory if we can */
+static int
+memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
+{
+ Py_ssize_t start, len, bytelen;
+ Py_buffer srcview;
+ Py_buffer *view = &(self->view);
+ char *srcbuf, *destbuf;
+
+ if (view->readonly) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot modify read-only memory");
+ return -1;
+ }
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot delete memory");
+ return -1;
+ }
+ if (view->ndim != 1) {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return -1;
+ }
+ if (PyIndex_Check(key)) {
+ start = PyNumber_AsSsize_t(key, NULL);
+ if (start == -1 && PyErr_Occurred())
+ return -1;
+ if (start < 0) {
+ start += get_shape0(view);
+ }
+ if ((start < 0) || (start >= get_shape0(view))) {
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return -1;
+ }
+ len = 1;
+ }
+ else if (PySlice_Check(key)) {
+ Py_ssize_t stop, step;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ &start, &stop, &step, &len) < 0) {
+ return -1;
+ }
+ if (step != 1) {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "cannot index memory using \"%.200s\"",
+ key->ob_type->tp_name);
+ return -1;
+ }
+ if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
+ return -1;
+ }
+ /* XXX should we allow assignment of different item sizes
+ as long as the byte length is the same?
+ (e.g. assign 2 shorts to a 4-byte slice) */
+ if (srcview.itemsize != view->itemsize) {
+ PyErr_Format(PyExc_TypeError,
+ "mismatching item sizes for \"%.200s\" and \"%.200s\"",
+ view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
+ goto _error;
+ }
+ bytelen = len * view->itemsize;
+ if (bytelen != srcview.len) {
+ PyErr_SetString(PyExc_ValueError,
+ "cannot modify size of memoryview object");
+ goto _error;
+ }
+ /* Do the actual copy */
+ destbuf = (char *) view->buf + start * view->itemsize;
+ srcbuf = (char *) srcview.buf;
+ if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
+ /* No overlapping */
+ memcpy(destbuf, srcbuf, bytelen);
+ else
+ memmove(destbuf, srcbuf, bytelen);
+
+ PyBuffer_Release(&srcview);
+ return 0;
+
+_error:
+ PyBuffer_Release(&srcview);
+ return -1;
+}
+
+static PyObject *
+memory_richcompare(PyObject *v, PyObject *w, int op)
+{
+ Py_buffer vv, ww;
+ int equal = 0;
+ PyObject *res;
+
+ vv.obj = NULL;
+ ww.obj = NULL;
+ if (op != Py_EQ && op != Py_NE)
+ goto _notimpl;
+ if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+ if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+
+ if (vv.itemsize != ww.itemsize || vv.len != ww.len)
+ goto _end;
+
+ equal = !memcmp(vv.buf, ww.buf, vv.len);
+
+_end:
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+
+_notimpl:
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+
+static int
+memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
+{
+ if (self->base != NULL)
+ Py_VISIT(self->base);
+ if (self->view.obj != NULL)
+ Py_VISIT(self->view.obj);
+ return 0;
+}
+
+static int
+memory_clear(PyMemoryViewObject *self)
+{
+ Py_CLEAR(self->base);
+ PyBuffer_Release(&self->view);
+ return 0;
+}
+
+
+/* As mapping */
+static PyMappingMethods memory_as_mapping = {
+ (lenfunc)memory_length, /* mp_length */
+ (binaryfunc)memory_subscript, /* mp_subscript */
+ (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
+};
+
+static PySequenceMethods memory_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)memory_item, /* sq_item */
+};
+
+/* Buffer methods */
+static PyBufferProcs memory_as_buffer = {
+ 0, /* bf_getreadbuffer */
+ 0, /* bf_getwritebuffer */
+ 0, /* bf_getsegcount */
+ 0, /* bf_getcharbuffer */
+ (getbufferproc)memory_getbuf, /* bf_getbuffer */
+ (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
+};
+
+
+PyTypeObject PyMemoryView_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "memoryview",
+ sizeof(PyMemoryViewObject),
+ 0,
+ (destructor)memory_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)memory_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &memory_as_sequence, /* tp_as_sequence */
+ &memory_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &memory_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+ memory_doc, /* tp_doc */
+ (traverseproc)memory_traverse, /* tp_traverse */
+ (inquiry)memory_clear, /* tp_clear */
+ memory_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ memory_methods, /* tp_methods */
+ 0, /* tp_members */
+ memory_getsetlist, /* 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 */
+ memory_new, /* tp_new */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/methodobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/methodobject.c
new file mode 100644
index 0000000000..5fe69a09e4
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/methodobject.c
@@ -0,0 +1,427 @@
+
+/* Method object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Free list for method objects to safe malloc/free overhead
+ * The m_self element is used to chain the objects.
+ */
+static PyCFunctionObject *free_list = NULL;
+static int numfree = 0;
+#ifndef PyCFunction_MAXFREELIST
+#define PyCFunction_MAXFREELIST 256
+#endif
+
+PyObject *
+PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
+{
+ PyCFunctionObject *op;
+ op = free_list;
+ if (op != NULL) {
+ free_list = (PyCFunctionObject *)(op->m_self);
+ PyObject_INIT(op, &PyCFunction_Type);
+ numfree--;
+ }
+ else {
+ op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
+ if (op == NULL)
+ return NULL;
+ }
+ op->m_ml = ml;
+ Py_XINCREF(self);
+ op->m_self = self;
+ Py_XINCREF(module);
+ op->m_module = module;
+ _PyObject_GC_TRACK(op);
+ return (PyObject *)op;
+}
+
+PyCFunction
+PyCFunction_GetFunction(PyObject *op)
+{
+ if (!PyCFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
+}
+
+PyObject *
+PyCFunction_GetSelf(PyObject *op)
+{
+ if (!PyCFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return ((PyCFunctionObject *)op) -> m_self;
+}
+
+int
+PyCFunction_GetFlags(PyObject *op)
+{
+ if (!PyCFunction_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
+}
+
+PyObject *
+PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (kw == NULL || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ case METH_OLDARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (kw == NULL || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (kw == NULL || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_OLDARGS:
+ /* the really old style */
+ if (kw == NULL || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ arg = PyTuple_GET_ITEM(arg, 0);
+ else if (size == 0)
+ arg = NULL;
+ return (*meth)(self, arg);
+ }
+ break;
+ default:
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+
+/* Methods (the standard built-in methods, that is) */
+
+static void
+meth_dealloc(PyCFunctionObject *m)
+{
+ _PyObject_GC_UNTRACK(m);
+ Py_XDECREF(m->m_self);
+ Py_XDECREF(m->m_module);
+ if (numfree < PyCFunction_MAXFREELIST) {
+ m->m_self = (PyObject *)free_list;
+ free_list = m;
+ numfree++;
+ }
+ else {
+ PyObject_GC_Del(m);
+ }
+}
+
+static PyObject *
+meth_get__doc__(PyCFunctionObject *m, void *closure)
+{
+ const char *doc = m->m_ml->ml_doc;
+
+ if (doc != NULL)
+ return PyString_FromString(doc);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+meth_get__name__(PyCFunctionObject *m, void *closure)
+{
+ return PyString_FromString(m->m_ml->ml_name);
+}
+
+static int
+meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->m_self);
+ Py_VISIT(m->m_module);
+ return 0;
+}
+
+static PyObject *
+meth_get__self__(PyCFunctionObject *m, void *closure)
+{
+ PyObject *self;
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "method.__self__ not accessible in restricted mode");
+ return NULL;
+ }
+ self = m->m_self;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+
+static PyGetSetDef meth_getsets [] = {
+ {"__doc__", (getter)meth_get__doc__, NULL, NULL},
+ {"__name__", (getter)meth_get__name__, NULL, NULL},
+ {"__self__", (getter)meth_get__self__, NULL, NULL},
+ {0}
+};
+
+#define OFF(x) offsetof(PyCFunctionObject, x)
+
+static PyMemberDef meth_members[] = {
+ {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
+ {NULL}
+};
+
+static PyObject *
+meth_repr(PyCFunctionObject *m)
+{
+ if (m->m_self == NULL)
+ return PyString_FromFormat("<built-in function %s>",
+ m->m_ml->ml_name);
+ return PyString_FromFormat("<built-in method %s of %s object at %p>",
+ m->m_ml->ml_name,
+ m->m_self->ob_type->tp_name,
+ m->m_self);
+}
+
+static int
+meth_compare(PyCFunctionObject *a, PyCFunctionObject *b)
+{
+ if (a->m_self != b->m_self)
+ return (a->m_self < b->m_self) ? -1 : 1;
+ if (a->m_ml->ml_meth == b->m_ml->ml_meth)
+ return 0;
+ if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
+ return -1;
+ else
+ return 1;
+}
+
+static PyObject *
+meth_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyCFunctionObject *a, *b;
+ PyObject *res;
+ int eq;
+
+ if (op != Py_EQ && op != Py_NE) {
+ /* Py3K warning if comparison isn't == or !=. */
+ if (PyErr_WarnPy3k("builtin_function_or_method order "
+ "comparisons not supported in 3.x", 1) < 0) {
+ return NULL;
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ else if (!PyCFunction_Check(self) || !PyCFunction_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ a = (PyCFunctionObject *)self;
+ b = (PyCFunctionObject *)other;
+ eq = a->m_self == b->m_self;
+ if (eq)
+ eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
+ if (op == Py_EQ)
+ res = eq ? Py_True : Py_False;
+ else
+ res = eq ? Py_False : Py_True;
+ Py_INCREF(res);
+ return res;
+}
+
+static long
+meth_hash(PyCFunctionObject *a)
+{
+ long x,y;
+ if (a->m_self == NULL)
+ x = 0;
+ else {
+ x = PyObject_Hash(a->m_self);
+ if (x == -1)
+ return -1;
+ }
+ y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
+ if (y == -1)
+ return -1;
+ x ^= y;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+
+PyTypeObject PyCFunction_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "builtin_function_or_method",
+ sizeof(PyCFunctionObject),
+ 0,
+ (destructor)meth_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)meth_compare, /* tp_compare */
+ (reprfunc)meth_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)meth_hash, /* tp_hash */
+ PyCFunction_Call, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)meth_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ meth_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ meth_members, /* tp_members */
+ meth_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+};
+
+/* List all methods in a chain -- helper for findmethodinchain */
+
+static PyObject *
+listmethodchain(PyMethodChain *chain)
+{
+ PyMethodChain *c;
+ PyMethodDef *ml;
+ int i, n;
+ PyObject *v;
+
+ n = 0;
+ for (c = chain; c != NULL; c = c->link) {
+ for (ml = c->methods; ml->ml_name != NULL; ml++)
+ n++;
+ }
+ v = PyList_New(n);
+ if (v == NULL)
+ return NULL;
+ i = 0;
+ for (c = chain; c != NULL; c = c->link) {
+ for (ml = c->methods; ml->ml_name != NULL; ml++) {
+ PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
+ i++;
+ }
+ }
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+ PyList_Sort(v);
+ return v;
+}
+
+/* Find a method in a method chain */
+
+PyObject *
+Py_FindMethodInChain(PyMethodChain *chain, PyObject *self, const char *name)
+{
+ if (name[0] == '_' && name[1] == '_') {
+ if (strcmp(name, "__methods__") == 0) {
+ if (PyErr_WarnPy3k("__methods__ not supported in 3.x",
+ 1) < 0)
+ return NULL;
+ return listmethodchain(chain);
+ }
+ if (strcmp(name, "__doc__") == 0) {
+ const char *doc = self->ob_type->tp_doc;
+ if (doc != NULL)
+ return PyString_FromString(doc);
+ }
+ }
+ while (chain != NULL) {
+ PyMethodDef *ml = chain->methods;
+ for (; ml->ml_name != NULL; ml++) {
+ if (name[0] == ml->ml_name[0] &&
+ strcmp(name+1, ml->ml_name+1) == 0)
+ /* XXX */
+ return PyCFunction_New(ml, self);
+ }
+ chain = chain->link;
+ }
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+/* Find a method in a single method list */
+
+PyObject *
+Py_FindMethod(PyMethodDef *methods, PyObject *self, const char *name)
+{
+ PyMethodChain chain;
+ chain.methods = methods;
+ chain.link = NULL;
+ return Py_FindMethodInChain(&chain, self, name);
+}
+
+/* Clear out the free list */
+
+int
+PyCFunction_ClearFreeList(void)
+{
+ int freelist_size = numfree;
+
+ while (free_list) {
+ PyCFunctionObject *v = free_list;
+ free_list = (PyCFunctionObject *)(v->m_self);
+ PyObject_GC_Del(v);
+ numfree--;
+ }
+ assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+PyCFunction_Fini(void)
+{
+ (void)PyCFunction_ClearFreeList();
+}
+
+/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
+ but it's part of the API so we need to keep a function around that
+ existing C extensions can call.
+*/
+
+#undef PyCFunction_New
+PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);
+
+PyObject *
+PyCFunction_New(PyMethodDef *ml, PyObject *self)
+{
+ return PyCFunction_NewEx(ml, self, NULL);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/moduleobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/moduleobject.c
new file mode 100644
index 0000000000..8aa788d871
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/moduleobject.c
@@ -0,0 +1,262 @@
+
+/* Module object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *md_dict;
+} PyModuleObject;
+
+static PyMemberDef module_members[] = {
+ {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
+ {0}
+};
+
+PyObject *
+PyModule_New(const char *name)
+{
+ PyModuleObject *m;
+ PyObject *nameobj;
+ m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
+ if (m == NULL)
+ return NULL;
+ nameobj = PyString_FromString(name);
+ m->md_dict = PyDict_New();
+ if (m->md_dict == NULL || nameobj == NULL)
+ goto fail;
+ if (PyDict_SetItemString(m->md_dict, "__name__", nameobj) != 0)
+ goto fail;
+ if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
+ goto fail;
+ if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
+ goto fail;
+ Py_DECREF(nameobj);
+ PyObject_GC_Track(m);
+ return (PyObject *)m;
+
+ fail:
+ Py_XDECREF(nameobj);
+ Py_DECREF(m);
+ return NULL;
+}
+
+PyObject *
+PyModule_GetDict(PyObject *m)
+{
+ PyObject *d;
+ if (!PyModule_Check(m)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ d = ((PyModuleObject *)m) -> md_dict;
+ if (d == NULL)
+ ((PyModuleObject *)m) -> md_dict = d = PyDict_New();
+ return d;
+}
+
+char *
+PyModule_GetName(PyObject *m)
+{
+ PyObject *d;
+ PyObject *nameobj;
+ if (!PyModule_Check(m)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ d = ((PyModuleObject *)m)->md_dict;
+ if (d == NULL ||
+ (nameobj = PyDict_GetItemString(d, "__name__")) == NULL ||
+ !PyString_Check(nameobj))
+ {
+ PyErr_SetString(PyExc_SystemError, "nameless module");
+ return NULL;
+ }
+ return PyString_AsString(nameobj);
+}
+
+char *
+PyModule_GetFilename(PyObject *m)
+{
+ PyObject *d;
+ PyObject *fileobj;
+ if (!PyModule_Check(m)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ d = ((PyModuleObject *)m)->md_dict;
+ if (d == NULL ||
+ (fileobj = PyDict_GetItemString(d, "__file__")) == NULL ||
+ !PyString_Check(fileobj))
+ {
+ PyErr_SetString(PyExc_SystemError, "module filename missing");
+ return NULL;
+ }
+ return PyString_AsString(fileobj);
+}
+
+void
+_PyModule_Clear(PyObject *m)
+{
+ /* To make the execution order of destructors for global
+ objects a bit more predictable, we first zap all objects
+ whose name starts with a single underscore, before we clear
+ the entire dictionary. We zap them by replacing them with
+ None, rather than deleting them from the dictionary, to
+ avoid rehashing the dictionary (to some extent). */
+
+ Py_ssize_t pos;
+ PyObject *key, *value;
+ PyObject *d;
+
+ d = ((PyModuleObject *)m)->md_dict;
+ if (d == NULL)
+ return;
+
+ /* First, clear only names starting with a single underscore */
+ pos = 0;
+ while (PyDict_Next(d, &pos, &key, &value)) {
+ if (value != Py_None && PyString_Check(key)) {
+ char *s = PyString_AsString(key);
+ if (s[0] == '_' && s[1] != '_') {
+ if (Py_VerboseFlag > 1)
+ PySys_WriteStderr("# clear[1] %s\n", s);
+ if (PyDict_SetItem(d, key, Py_None) != 0)
+ PyErr_Clear();
+ }
+ }
+ }
+
+ /* Next, clear all names except for __builtins__ */
+ pos = 0;
+ while (PyDict_Next(d, &pos, &key, &value)) {
+ if (value != Py_None && PyString_Check(key)) {
+ char *s = PyString_AsString(key);
+ if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
+ if (Py_VerboseFlag > 1)
+ PySys_WriteStderr("# clear[2] %s\n", s);
+ if (PyDict_SetItem(d, key, Py_None) != 0)
+ PyErr_Clear();
+ }
+ }
+ }
+
+ /* Note: we leave __builtins__ in place, so that destructors
+ of non-global objects defined in this module can still use
+ builtins, in particularly 'None'. */
+
+}
+
+/* Methods */
+
+static int
+module_init(PyModuleObject *m, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", "doc", NULL};
+ PyObject *dict, *name = Py_None, *doc = Py_None;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|O:module.__init__",
+ kwlist, &name, &doc))
+ return -1;
+ dict = m->md_dict;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ if (dict == NULL)
+ return -1;
+ m->md_dict = dict;
+ }
+ if (PyDict_SetItemString(dict, "__name__", name) < 0)
+ return -1;
+ if (PyDict_SetItemString(dict, "__doc__", doc) < 0)
+ return -1;
+ return 0;
+}
+
+static void
+module_dealloc(PyModuleObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (m->md_dict != NULL) {
+ _PyModule_Clear((PyObject *)m);
+ Py_DECREF(m->md_dict);
+ }
+ Py_TYPE(m)->tp_free((PyObject *)m);
+}
+
+static PyObject *
+module_repr(PyModuleObject *m)
+{
+ char *name;
+ char *filename;
+
+ name = PyModule_GetName((PyObject *)m);
+ if (name == NULL) {
+ PyErr_Clear();
+ name = "?";
+ }
+ filename = PyModule_GetFilename((PyObject *)m);
+ if (filename == NULL) {
+ PyErr_Clear();
+ return PyString_FromFormat("<module '%s' (built-in)>", name);
+ }
+ return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
+}
+
+/* We only need a traverse function, no clear function: If the module
+ is in a cycle, md_dict will be cleared as well, which will break
+ the cycle. */
+static int
+module_traverse(PyModuleObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->md_dict);
+ return 0;
+}
+
+PyDoc_STRVAR(module_doc,
+"module(name[, doc])\n\
+\n\
+Create a module object.\n\
+The name must be a string; the optional doc argument can have any type.");
+
+PyTypeObject PyModule_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "module", /* tp_name */
+ sizeof(PyModuleObject), /* tp_size */
+ 0, /* tp_itemsize */
+ (destructor)module_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)module_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 */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ module_doc, /* tp_doc */
+ (traverseproc)module_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ module_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyModuleObject, md_dict), /* tp_dictoffset */
+ (initproc)module_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/object.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/object.c
new file mode 100644
index 0000000000..bbc2a2ee24
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/object.c
@@ -0,0 +1,2513 @@
+
+/* Generic object operations; and implementation of None (NoObject) */
+
+#include "Python.h"
+#include "frameobject.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef Py_REF_DEBUG
+Py_ssize_t _Py_RefTotal;
+
+Py_ssize_t
+_Py_GetRefTotal(void)
+{
+ PyObject *o;
+ Py_ssize_t total = _Py_RefTotal;
+ /* ignore the references to the dummy object of the dicts and sets
+ because they are not reliable and not useful (now that the
+ hash table code is well-tested) */
+ o = _PyDict_Dummy();
+ if (o != NULL)
+ total -= o->ob_refcnt;
+ o = _PySet_Dummy();
+ if (o != NULL)
+ total -= o->ob_refcnt;
+ return total;
+}
+#endif /* Py_REF_DEBUG */
+
+int Py_DivisionWarningFlag;
+int Py_Py3kWarningFlag;
+
+/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
+ These are used by the individual routines for object creation.
+ Do not call them otherwise, they do not initialize the object! */
+
+#ifdef Py_TRACE_REFS
+/* Head of circular doubly-linked list of all objects. These are linked
+ * together via the _ob_prev and _ob_next members of a PyObject, which
+ * exist only in a Py_TRACE_REFS build.
+ */
+static PyObject refchain = {&refchain, &refchain};
+
+/* Insert op at the front of the list of all objects. If force is true,
+ * op is added even if _ob_prev and _ob_next are non-NULL already. If
+ * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
+ * force should be true if and only if op points to freshly allocated,
+ * uninitialized memory, or you've unlinked op from the list and are
+ * relinking it into the front.
+ * Note that objects are normally added to the list via _Py_NewReference,
+ * which is called by PyObject_Init. Not all objects are initialized that
+ * way, though; exceptions include statically allocated type objects, and
+ * statically allocated singletons (like Py_True and Py_None).
+ */
+void
+_Py_AddToAllObjects(PyObject *op, int force)
+{
+#ifdef Py_DEBUG
+ if (!force) {
+ /* If it's initialized memory, op must be in or out of
+ * the list unambiguously.
+ */
+ assert((op->_ob_prev == NULL) == (op->_ob_next == NULL));
+ }
+#endif
+ if (force || op->_ob_prev == NULL) {
+ op->_ob_next = refchain._ob_next;
+ op->_ob_prev = &refchain;
+ refchain._ob_next->_ob_prev = op;
+ refchain._ob_next = op;
+ }
+}
+#endif /* Py_TRACE_REFS */
+
+#ifdef COUNT_ALLOCS
+static PyTypeObject *type_list;
+/* All types are added to type_list, at least when
+ they get one object created. That makes them
+ immortal, which unfortunately contributes to
+ garbage itself. If unlist_types_without_objects
+ is set, they will be removed from the type_list
+ once the last object is deallocated. */
+static int unlist_types_without_objects;
+extern Py_ssize_t tuple_zero_allocs, fast_tuple_allocs;
+extern Py_ssize_t quick_int_allocs, quick_neg_int_allocs;
+extern Py_ssize_t null_strings, one_strings;
+void
+dump_counts(FILE* f)
+{
+ PyTypeObject *tp;
+
+ for (tp = type_list; tp; tp = tp->tp_next)
+ fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, "
+ "freed: %" PY_FORMAT_SIZE_T "d, "
+ "max in use: %" PY_FORMAT_SIZE_T "d\n",
+ tp->tp_name, tp->tp_allocs, tp->tp_frees,
+ tp->tp_maxalloc);
+ fprintf(f, "fast tuple allocs: %" PY_FORMAT_SIZE_T "d, "
+ "empty: %" PY_FORMAT_SIZE_T "d\n",
+ fast_tuple_allocs, tuple_zero_allocs);
+ fprintf(f, "fast int allocs: pos: %" PY_FORMAT_SIZE_T "d, "
+ "neg: %" PY_FORMAT_SIZE_T "d\n",
+ quick_int_allocs, quick_neg_int_allocs);
+ fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, "
+ "1-strings: %" PY_FORMAT_SIZE_T "d\n",
+ null_strings, one_strings);
+}
+
+PyObject *
+get_counts(void)
+{
+ PyTypeObject *tp;
+ PyObject *result;
+ PyObject *v;
+
+ result = PyList_New(0);
+ if (result == NULL)
+ return NULL;
+ for (tp = type_list; tp; tp = tp->tp_next) {
+ v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs,
+ tp->tp_frees, tp->tp_maxalloc);
+ if (v == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (PyList_Append(result, v) < 0) {
+ Py_DECREF(v);
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_DECREF(v);
+ }
+ return result;
+}
+
+void
+inc_count(PyTypeObject *tp)
+{
+ if (tp->tp_next == NULL && tp->tp_prev == NULL) {
+ /* first time; insert in linked list */
+ if (tp->tp_next != NULL) /* sanity check */
+ Py_FatalError("XXX inc_count sanity check");
+ if (type_list)
+ type_list->tp_prev = tp;
+ tp->tp_next = type_list;
+ /* Note that as of Python 2.2, heap-allocated type objects
+ * can go away, but this code requires that they stay alive
+ * until program exit. That's why we're careful with
+ * refcounts here. type_list gets a new reference to tp,
+ * while ownership of the reference type_list used to hold
+ * (if any) was transferred to tp->tp_next in the line above.
+ * tp is thus effectively immortal after this.
+ */
+ Py_INCREF(tp);
+ type_list = tp;
+#ifdef Py_TRACE_REFS
+ /* Also insert in the doubly-linked list of all objects,
+ * if not already there.
+ */
+ _Py_AddToAllObjects((PyObject *)tp, 0);
+#endif
+ }
+ tp->tp_allocs++;
+ if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
+ tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
+}
+
+void dec_count(PyTypeObject *tp)
+{
+ tp->tp_frees++;
+ if (unlist_types_without_objects &&
+ tp->tp_allocs == tp->tp_frees) {
+ /* unlink the type from type_list */
+ if (tp->tp_prev)
+ tp->tp_prev->tp_next = tp->tp_next;
+ else
+ type_list = tp->tp_next;
+ if (tp->tp_next)
+ tp->tp_next->tp_prev = tp->tp_prev;
+ tp->tp_next = tp->tp_prev = NULL;
+ Py_DECREF(tp);
+ }
+}
+
+#endif
+
+#ifdef Py_REF_DEBUG
+/* Log a fatal error; doesn't return. */
+void
+_Py_NegativeRefcount(const char *fname, int lineno, PyObject *op)
+{
+ char buf[300];
+
+ PyOS_snprintf(buf, sizeof(buf),
+ "%s:%i object at %p has negative ref count "
+ "%" PY_FORMAT_SIZE_T "d",
+ fname, lineno, op, op->ob_refcnt);
+ Py_FatalError(buf);
+}
+
+#endif /* Py_REF_DEBUG */
+
+void
+Py_IncRef(PyObject *o)
+{
+ Py_XINCREF(o);
+}
+
+void
+Py_DecRef(PyObject *o)
+{
+ Py_XDECREF(o);
+}
+
+PyObject *
+PyObject_Init(PyObject *op, PyTypeObject *tp)
+{
+ if (op == NULL)
+ return PyErr_NoMemory();
+ /* Any changes should be reflected in PyObject_INIT (objimpl.h) */
+ Py_TYPE(op) = tp;
+ _Py_NewReference(op);
+ return op;
+}
+
+PyVarObject *
+PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
+{
+ if (op == NULL)
+ return (PyVarObject *) PyErr_NoMemory();
+ /* Any changes should be reflected in PyObject_INIT_VAR */
+ op->ob_size = size;
+ Py_TYPE(op) = tp;
+ _Py_NewReference((PyObject *)op);
+ return op;
+}
+
+PyObject *
+_PyObject_New(PyTypeObject *tp)
+{
+ PyObject *op;
+ op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp));
+ if (op == NULL)
+ return PyErr_NoMemory();
+ return PyObject_INIT(op, tp);
+}
+
+PyVarObject *
+_PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
+{
+ PyVarObject *op;
+ const size_t size = _PyObject_VAR_SIZE(tp, nitems);
+ op = (PyVarObject *) PyObject_MALLOC(size);
+ if (op == NULL)
+ return (PyVarObject *)PyErr_NoMemory();
+ return PyObject_INIT_VAR(op, tp, nitems);
+}
+
+/* for binary compatibility with 2.2 */
+#undef _PyObject_Del
+void
+_PyObject_Del(PyObject *op)
+{
+ PyObject_FREE(op);
+}
+
+/* Implementation of PyObject_Print with recursion checking */
+static int
+internal_print(PyObject *op, FILE *fp, int flags, int nesting)
+{
+ int ret = 0;
+ if (nesting > 10) {
+ PyErr_SetString(PyExc_RuntimeError, "print recursion");
+ return -1;
+ }
+ if (PyErr_CheckSignals())
+ return -1;
+#ifdef USE_STACKCHECK
+ if (PyOS_CheckStack()) {
+ PyErr_SetString(PyExc_MemoryError, "stack overflow");
+ return -1;
+ }
+#endif
+ clearerr(fp); /* Clear any previous error condition */
+ if (op == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "<nil>");
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ if (op->ob_refcnt <= 0)
+ /* XXX(twouters) cast refcount to long until %zd is
+ universally available */
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "<refcnt %ld at %p>",
+ (long)op->ob_refcnt, op);
+ Py_END_ALLOW_THREADS
+ else if (Py_TYPE(op)->tp_print == NULL) {
+ PyObject *s;
+ if (flags & Py_PRINT_RAW)
+ s = PyObject_Str(op);
+ else
+ s = PyObject_Repr(op);
+ if (s == NULL)
+ ret = -1;
+ else {
+ ret = internal_print(s, fp, Py_PRINT_RAW,
+ nesting+1);
+ }
+ Py_XDECREF(s);
+ }
+ else
+ ret = (*Py_TYPE(op)->tp_print)(op, fp, flags);
+ }
+ if (ret == 0) {
+ if (ferror(fp)) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ clearerr(fp);
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
+int
+PyObject_Print(PyObject *op, FILE *fp, int flags)
+{
+ return internal_print(op, fp, flags, 0);
+}
+
+
+/* For debugging convenience. See Misc/gdbinit for some useful gdb hooks */
+void _PyObject_Dump(PyObject* op)
+{
+ if (op == NULL)
+ fprintf(stderr, "NULL\n");
+ else {
+#ifdef WITH_THREAD
+ PyGILState_STATE gil;
+#endif
+ fprintf(stderr, "object : ");
+#ifdef WITH_THREAD
+ gil = PyGILState_Ensure();
+#endif
+ (void)PyObject_Print(op, stderr, 0);
+#ifdef WITH_THREAD
+ PyGILState_Release(gil);
+#endif
+ /* XXX(twouters) cast refcount to long until %zd is
+ universally available */
+ fprintf(stderr, "\n"
+ "type : %s\n"
+ "refcount: %ld\n"
+ "address : %p\n",
+ Py_TYPE(op)==NULL ? "NULL" : Py_TYPE(op)->tp_name,
+ (long)op->ob_refcnt,
+ op);
+ }
+}
+
+PyObject *
+PyObject_Repr(PyObject *v)
+{
+ if (PyErr_CheckSignals())
+ return NULL;
+#ifdef USE_STACKCHECK
+ if (PyOS_CheckStack()) {
+ PyErr_SetString(PyExc_MemoryError, "stack overflow");
+ return NULL;
+ }
+#endif
+ if (v == NULL)
+ return PyString_FromString("<NULL>");
+ else if (Py_TYPE(v)->tp_repr == NULL)
+ return PyString_FromFormat("<%s object at %p>",
+ Py_TYPE(v)->tp_name, v);
+ else {
+ PyObject *res;
+ res = (*Py_TYPE(v)->tp_repr)(v);
+ if (res == NULL)
+ return NULL;
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(res)) {
+ PyObject* str;
+ str = PyUnicode_AsEncodedString(res, NULL, NULL);
+ Py_DECREF(res);
+ if (str)
+ res = str;
+ else
+ return NULL;
+ }
+#endif
+ if (!PyString_Check(res)) {
+ PyErr_Format(PyExc_TypeError,
+ "__repr__ returned non-string (type %.200s)",
+ Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+ }
+}
+
+PyObject *
+_PyObject_Str(PyObject *v)
+{
+ PyObject *res;
+ int type_ok;
+ if (v == NULL)
+ return PyString_FromString("<NULL>");
+ if (PyString_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+#endif
+ if (Py_TYPE(v)->tp_str == NULL)
+ return PyObject_Repr(v);
+
+ /* It is possible for a type to have a tp_str representation that loops
+ infinitely. */
+ if (Py_EnterRecursiveCall(" while getting the str of an object"))
+ return NULL;
+ res = (*Py_TYPE(v)->tp_str)(v);
+ Py_LeaveRecursiveCall();
+ if (res == NULL)
+ return NULL;
+ type_ok = PyString_Check(res);
+#ifdef Py_USING_UNICODE
+ type_ok = type_ok || PyUnicode_Check(res);
+#endif
+ if (!type_ok) {
+ PyErr_Format(PyExc_TypeError,
+ "__str__ returned non-string (type %.200s)",
+ Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ return res;
+}
+
+PyObject *
+PyObject_Str(PyObject *v)
+{
+ PyObject *res = _PyObject_Str(v);
+ if (res == NULL)
+ return NULL;
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(res)) {
+ PyObject* str;
+ str = PyUnicode_AsEncodedString(res, NULL, NULL);
+ Py_DECREF(res);
+ if (str)
+ res = str;
+ else
+ return NULL;
+ }
+#endif
+ assert(PyString_Check(res));
+ return res;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyObject_Unicode(PyObject *v)
+{
+ PyObject *res;
+ PyObject *func;
+ PyObject *str;
+ int unicode_method_found = 0;
+ static PyObject *unicodestr = NULL;
+
+ if (v == NULL) {
+ res = PyString_FromString("<NULL>");
+ if (res == NULL)
+ return NULL;
+ str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+ Py_DECREF(res);
+ return str;
+ } else if (PyUnicode_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+
+ if (PyInstance_Check(v)) {
+ /* We're an instance of a classic class */
+ /* Try __unicode__ from the instance -- alas we have no type */
+ if (!unicodestr) {
+ unicodestr = PyString_InternFromString("__unicode__");
+ if (!unicodestr)
+ return NULL;
+ }
+ func = PyObject_GetAttr(v, unicodestr);
+ if (func != NULL) {
+ unicode_method_found = 1;
+ res = PyObject_CallFunctionObjArgs(func, NULL);
+ Py_DECREF(func);
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+ else {
+ /* Not a classic class instance, try __unicode__. */
+ func = _PyObject_LookupSpecial(v, "__unicode__", &unicodestr);
+ if (func != NULL) {
+ unicode_method_found = 1;
+ res = PyObject_CallFunctionObjArgs(func, NULL);
+ Py_DECREF(func);
+ }
+ else if (PyErr_Occurred())
+ return NULL;
+ }
+
+ /* Didn't find __unicode__ */
+ if (!unicode_method_found) {
+ if (PyUnicode_Check(v)) {
+ /* For a Unicode subtype that's didn't overwrite __unicode__,
+ return a true Unicode object with the same data. */
+ return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v),
+ PyUnicode_GET_SIZE(v));
+ }
+ if (PyString_CheckExact(v)) {
+ Py_INCREF(v);
+ res = v;
+ }
+ else {
+ if (Py_TYPE(v)->tp_str != NULL)
+ res = (*Py_TYPE(v)->tp_str)(v);
+ else
+ res = PyObject_Repr(v);
+ }
+ }
+
+ if (res == NULL)
+ return NULL;
+ if (!PyUnicode_Check(res)) {
+ str = PyUnicode_FromEncodedObject(res, NULL, "strict");
+ Py_DECREF(res);
+ res = str;
+ }
+ return res;
+}
+#endif
+
+
+/* Helper to warn about deprecated tp_compare return values. Return:
+ -2 for an exception;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w.
+ (This function cannot return 2.)
+*/
+static int
+adjust_tp_compare(int c)
+{
+ if (PyErr_Occurred()) {
+ if (c != -1 && c != -2) {
+ PyObject *t, *v, *tb;
+ PyErr_Fetch(&t, &v, &tb);
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tp_compare didn't return -1 or -2 "
+ "for exception") < 0) {
+ Py_XDECREF(t);
+ Py_XDECREF(v);
+ Py_XDECREF(tb);
+ }
+ else
+ PyErr_Restore(t, v, tb);
+ }
+ return -2;
+ }
+ else if (c < -1 || c > 1) {
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tp_compare didn't return -1, 0 or 1") < 0)
+ return -2;
+ else
+ return c < -1 ? -1 : 1;
+ }
+ else {
+ assert(c >= -1 && c <= 1);
+ return c;
+ }
+}
+
+
+/* Macro to get the tp_richcompare field of a type if defined */
+#define RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) \
+ ? (t)->tp_richcompare : NULL)
+
+/* Map rich comparison operators to their swapped version, e.g. LT --> GT */
+int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
+
+/* Try a genuine rich comparison, returning an object. Return:
+ NULL for exception;
+ NotImplemented if this particular rich comparison is not implemented or
+ undefined;
+ some object not equal to NotImplemented if it is implemented
+ (this latter object may not be a Boolean).
+*/
+static PyObject *
+try_rich_compare(PyObject *v, PyObject *w, int op)
+{
+ richcmpfunc f;
+ PyObject *res;
+
+ if (v->ob_type != w->ob_type &&
+ PyType_IsSubtype(w->ob_type, v->ob_type) &&
+ (f = RICHCOMPARE(w->ob_type)) != NULL) {
+ res = (*f)(w, v, _Py_SwappedOp[op]);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+ if ((f = RICHCOMPARE(v->ob_type)) != NULL) {
+ res = (*f)(v, w, op);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+ if ((f = RICHCOMPARE(w->ob_type)) != NULL) {
+ return (*f)(w, v, _Py_SwappedOp[op]);
+ }
+ res = Py_NotImplemented;
+ Py_INCREF(res);
+ return res;
+}
+
+/* Try a genuine rich comparison, returning an int. Return:
+ -1 for exception (including the case where try_rich_compare() returns an
+ object that's not a Boolean);
+ 0 if the outcome is false;
+ 1 if the outcome is true;
+ 2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_compare_bool(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+ int ok;
+
+ if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+ return 2; /* Shortcut, avoid INCREF+DECREF */
+ res = try_rich_compare(v, w, op);
+ if (res == NULL)
+ return -1;
+ if (res == Py_NotImplemented) {
+ Py_DECREF(res);
+ return 2;
+ }
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ return ok;
+}
+
+/* Try rich comparisons to determine a 3-way comparison. Return:
+ -2 for an exception;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w;
+ 2 if this particular rich comparison is not implemented or undefined.
+*/
+static int
+try_rich_to_3way_compare(PyObject *v, PyObject *w)
+{
+ static struct { int op; int outcome; } tries[3] = {
+ /* Try this operator, and if it is true, use this outcome: */
+ {Py_EQ, 0},
+ {Py_LT, -1},
+ {Py_GT, 1},
+ };
+ int i;
+
+ if (RICHCOMPARE(v->ob_type) == NULL && RICHCOMPARE(w->ob_type) == NULL)
+ return 2; /* Shortcut */
+
+ for (i = 0; i < 3; i++) {
+ switch (try_rich_compare_bool(v, w, tries[i].op)) {
+ case -1:
+ return -2;
+ case 1:
+ return tries[i].outcome;
+ }
+ }
+
+ return 2;
+}
+
+/* Try a 3-way comparison, returning an int. Return:
+ -2 for an exception;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w;
+ 2 if this particular 3-way comparison is not implemented or undefined.
+*/
+static int
+try_3way_compare(PyObject *v, PyObject *w)
+{
+ int c;
+ cmpfunc f;
+
+ /* Comparisons involving instances are given to instance_compare,
+ which has the same return conventions as this function. */
+
+ f = v->ob_type->tp_compare;
+ if (PyInstance_Check(v))
+ return (*f)(v, w);
+ if (PyInstance_Check(w))
+ return (*w->ob_type->tp_compare)(v, w);
+
+ /* If both have the same (non-NULL) tp_compare, use it. */
+ if (f != NULL && f == w->ob_type->tp_compare) {
+ c = (*f)(v, w);
+ return adjust_tp_compare(c);
+ }
+
+ /* If either tp_compare is _PyObject_SlotCompare, that's safe. */
+ if (f == _PyObject_SlotCompare ||
+ w->ob_type->tp_compare == _PyObject_SlotCompare)
+ return _PyObject_SlotCompare(v, w);
+
+ /* If we're here, v and w,
+ a) are not instances;
+ b) have different types or a type without tp_compare; and
+ c) don't have a user-defined tp_compare.
+ tp_compare implementations in C assume that both arguments
+ have their type, so we give up if the coercion fails or if
+ it yields types which are still incompatible (which can
+ happen with a user-defined nb_coerce).
+ */
+ c = PyNumber_CoerceEx(&v, &w);
+ if (c < 0)
+ return -2;
+ if (c > 0)
+ return 2;
+ f = v->ob_type->tp_compare;
+ if (f != NULL && f == w->ob_type->tp_compare) {
+ c = (*f)(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return adjust_tp_compare(c);
+ }
+
+ /* No comparison defined */
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return 2;
+}
+
+/* Final fallback 3-way comparison, returning an int. Return:
+ -2 if an error occurred;
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w.
+*/
+static int
+default_3way_compare(PyObject *v, PyObject *w)
+{
+ int c;
+ const char *vname, *wname;
+
+ if (v->ob_type == w->ob_type) {
+ /* When comparing these pointers, they must be cast to
+ * integer types (i.e. Py_uintptr_t, our spelling of C9X's
+ * uintptr_t). ANSI specifies that pointer compares other
+ * than == and != to non-related structures are undefined.
+ */
+ Py_uintptr_t vv = (Py_uintptr_t)v;
+ Py_uintptr_t ww = (Py_uintptr_t)w;
+ return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
+ }
+
+ /* None is smaller than anything */
+ if (v == Py_None)
+ return -1;
+ if (w == Py_None)
+ return 1;
+
+ /* different type: compare type names; numbers are smaller */
+ if (PyNumber_Check(v))
+ vname = "";
+ else
+ vname = v->ob_type->tp_name;
+ if (PyNumber_Check(w))
+ wname = "";
+ else
+ wname = w->ob_type->tp_name;
+ c = strcmp(vname, wname);
+ if (c < 0)
+ return -1;
+ if (c > 0)
+ return 1;
+ /* Same type name, or (more likely) incomparable numeric types */
+ return ((Py_uintptr_t)(v->ob_type) < (
+ Py_uintptr_t)(w->ob_type)) ? -1 : 1;
+}
+
+/* Do a 3-way comparison, by hook or by crook. Return:
+ -2 for an exception (but see below);
+ -1 if v < w;
+ 0 if v == w;
+ 1 if v > w;
+ BUT: if the object implements a tp_compare function, it returns
+ whatever this function returns (whether with an exception or not).
+*/
+static int
+do_cmp(PyObject *v, PyObject *w)
+{
+ int c;
+ cmpfunc f;
+
+ if (v->ob_type == w->ob_type
+ && (f = v->ob_type->tp_compare) != NULL) {
+ c = (*f)(v, w);
+ if (PyInstance_Check(v)) {
+ /* Instance tp_compare has a different signature.
+ But if it returns undefined we fall through. */
+ if (c != 2)
+ return c;
+ /* Else fall through to try_rich_to_3way_compare() */
+ }
+ else
+ return adjust_tp_compare(c);
+ }
+ /* We only get here if one of the following is true:
+ a) v and w have different types
+ b) v and w have the same type, which doesn't have tp_compare
+ c) v and w are instances, and either __cmp__ is not defined or
+ __cmp__ returns NotImplemented
+ */
+ c = try_rich_to_3way_compare(v, w);
+ if (c < 2)
+ return c;
+ c = try_3way_compare(v, w);
+ if (c < 2)
+ return c;
+ return default_3way_compare(v, w);
+}
+
+/* Compare v to w. Return
+ -1 if v < w or exception (PyErr_Occurred() true in latter case).
+ 0 if v == w.
+ 1 if v > w.
+ XXX The docs (C API manual) say the return value is undefined in case
+ XXX of error.
+*/
+int
+PyObject_Compare(PyObject *v, PyObject *w)
+{
+ int result;
+
+ if (v == NULL || w == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (v == w)
+ return 0;
+ if (Py_EnterRecursiveCall(" in cmp"))
+ return -1;
+ result = do_cmp(v, w);
+ Py_LeaveRecursiveCall();
+ return result < 0 ? -1 : result;
+}
+
+/* Return (new reference to) Py_True or Py_False. */
+static PyObject *
+convert_3way_to_object(int op, int c)
+{
+ PyObject *result;
+ switch (op) {
+ case Py_LT: c = c < 0; break;
+ case Py_LE: c = c <= 0; break;
+ case Py_EQ: c = c == 0; break;
+ case Py_NE: c = c != 0; break;
+ case Py_GT: c = c > 0; break;
+ case Py_GE: c = c >= 0; break;
+ }
+ result = c ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+/* We want a rich comparison but don't have one. Try a 3-way cmp instead.
+ Return
+ NULL if error
+ Py_True if v op w
+ Py_False if not (v op w)
+*/
+static PyObject *
+try_3way_to_rich_compare(PyObject *v, PyObject *w, int op)
+{
+ int c;
+
+ c = try_3way_compare(v, w);
+ if (c >= 2) {
+
+ /* Py3K warning if types are not equal and comparison isn't == or != */
+ if (Py_Py3kWarningFlag &&
+ v->ob_type != w->ob_type && op != Py_EQ && op != Py_NE &&
+ PyErr_WarnEx(PyExc_DeprecationWarning,
+ "comparing unequal types not supported "
+ "in 3.x", 1) < 0) {
+ return NULL;
+ }
+
+ c = default_3way_compare(v, w);
+ }
+ if (c <= -2)
+ return NULL;
+ return convert_3way_to_object(op, c);
+}
+
+/* Do rich comparison on v and w. Return
+ NULL if error
+ Else a new reference to an object other than Py_NotImplemented, usually(?):
+ Py_True if v op w
+ Py_False if not (v op w)
+*/
+static PyObject *
+do_richcmp(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+
+ res = try_rich_compare(v, w, op);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+
+ return try_3way_to_rich_compare(v, w, op);
+}
+
+/* Return:
+ NULL for exception;
+ some object not equal to NotImplemented if it is implemented
+ (this latter object may not be a Boolean).
+*/
+PyObject *
+PyObject_RichCompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+
+ assert(Py_LT <= op && op <= Py_GE);
+ if (Py_EnterRecursiveCall(" in cmp"))
+ return NULL;
+
+ /* If the types are equal, and not old-style instances, try to
+ get out cheap (don't bother with coercions etc.). */
+ if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
+ cmpfunc fcmp;
+ richcmpfunc frich = RICHCOMPARE(v->ob_type);
+ /* If the type has richcmp, try it first. try_rich_compare
+ tries it two-sided, which is not needed since we've a
+ single type only. */
+ if (frich != NULL) {
+ res = (*frich)(v, w, op);
+ if (res != Py_NotImplemented)
+ goto Done;
+ Py_DECREF(res);
+ }
+ /* No richcmp, or this particular richmp not implemented.
+ Try 3-way cmp. */
+ fcmp = v->ob_type->tp_compare;
+ if (fcmp != NULL) {
+ int c = (*fcmp)(v, w);
+ c = adjust_tp_compare(c);
+ if (c == -2) {
+ res = NULL;
+ goto Done;
+ }
+ res = convert_3way_to_object(op, c);
+ goto Done;
+ }
+ }
+
+ /* Fast path not taken, or couldn't deliver a useful result. */
+ res = do_richcmp(v, w, op);
+Done:
+ Py_LeaveRecursiveCall();
+ return res;
+}
+
+/* Return -1 if error; 1 if v op w; 0 if not (v op w). */
+int
+PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
+{
+ PyObject *res;
+ int ok;
+
+ /* Quick result when objects are the same.
+ Guarantees that identity implies equality. */
+ if (v == w) {
+ if (op == Py_EQ)
+ return 1;
+ else if (op == Py_NE)
+ return 0;
+ }
+
+ res = PyObject_RichCompare(v, w, op);
+ if (res == NULL)
+ return -1;
+ if (PyBool_Check(res))
+ ok = (res == Py_True);
+ else
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ return ok;
+}
+
+/* Set of hash utility functions to help maintaining the invariant that
+ if a==b then hash(a)==hash(b)
+
+ All the utility functions (_Py_Hash*()) return "-1" to signify an error.
+*/
+
+long
+_Py_HashDouble(double v)
+{
+ double intpart, fractpart;
+ int expo;
+ long hipart;
+ long x; /* the final hash value */
+ /* This is designed so that Python numbers of different types
+ * that compare equal hash to the same value; otherwise comparisons
+ * of mapping keys will turn out weird.
+ */
+
+ if (!Py_IS_FINITE(v)) {
+ if (Py_IS_INFINITY(v))
+ return v < 0 ? -271828 : 314159;
+ else
+ return 0;
+ }
+ fractpart = modf(v, &intpart);
+ if (fractpart == 0.0) {
+ /* This must return the same hash as an equal int or long. */
+ if (intpart > LONG_MAX/2 || -intpart > LONG_MAX/2) {
+ /* Convert to long and use its hash. */
+ PyObject *plong; /* converted to Python long */
+ plong = PyLong_FromDouble(v);
+ if (plong == NULL)
+ return -1;
+ x = PyObject_Hash(plong);
+ Py_DECREF(plong);
+ return x;
+ }
+ /* Fits in a C long == a Python int, so is its own hash. */
+ x = (long)intpart;
+ if (x == -1)
+ x = -2;
+ return x;
+ }
+ /* The fractional part is non-zero, so we don't have to worry about
+ * making this match the hash of some other type.
+ * Use frexp to get at the bits in the double.
+ * Since the VAX D double format has 56 mantissa bits, which is the
+ * most of any double format in use, each of these parts may have as
+ * many as (but no more than) 56 significant bits.
+ * So, assuming sizeof(long) >= 4, each part can be broken into two
+ * longs; frexp and multiplication are used to do that.
+ * Also, since the Cray double format has 15 exponent bits, which is
+ * the most of any double format in use, shifting the exponent field
+ * left by 15 won't overflow a long (again assuming sizeof(long) >= 4).
+ */
+ v = frexp(v, &expo);
+ v *= 2147483648.0; /* 2**31 */
+ hipart = (long)v; /* take the top 32 bits */
+ v = (v - (double)hipart) * 2147483648.0; /* get the next 32 bits */
+ x = hipart + (long)v + (expo << 15);
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+long
+_Py_HashPointer(void *p)
+{
+ long x;
+ size_t y = (size_t)p;
+ /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
+ excessive hash collisions for dicts and sets */
+ y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
+ x = (long)y;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+long
+PyObject_HashNotImplemented(PyObject *self)
+{
+ PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
+ self->ob_type->tp_name);
+ return -1;
+}
+
+_Py_HashSecret_t _Py_HashSecret;
+
+long
+PyObject_Hash(PyObject *v)
+{
+ PyTypeObject *tp = v->ob_type;
+ if (tp->tp_hash != NULL)
+ return (*tp->tp_hash)(v);
+ /* To keep to the general practice that inheriting
+ * solely from object in C code should work without
+ * an explicit call to PyType_Ready, we implicitly call
+ * PyType_Ready here and then check the tp_hash slot again
+ */
+ if (tp->tp_dict == NULL) {
+ if (PyType_Ready(tp) < 0)
+ return -1;
+ if (tp->tp_hash != NULL)
+ return (*tp->tp_hash)(v);
+ }
+ if (tp->tp_compare == NULL && RICHCOMPARE(tp) == NULL) {
+ return _Py_HashPointer(v); /* Use address as hash value */
+ }
+ /* If there's a cmp but no hash defined, the object can't be hashed */
+ return PyObject_HashNotImplemented(v);
+}
+
+PyObject *
+PyObject_GetAttrString(PyObject *v, const char *name)
+{
+ PyObject *w, *res;
+
+ if (Py_TYPE(v)->tp_getattr != NULL)
+ return (*Py_TYPE(v)->tp_getattr)(v, (char*)name);
+ w = PyString_InternFromString(name);
+ if (w == NULL)
+ return NULL;
+ res = PyObject_GetAttr(v, w);
+ Py_XDECREF(w);
+ return res;
+}
+
+int
+PyObject_HasAttrString(PyObject *v, const char *name)
+{
+ PyObject *res = PyObject_GetAttrString(v, name);
+ if (res != NULL) {
+ Py_DECREF(res);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
+}
+
+int
+PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w)
+{
+ PyObject *s;
+ int res;
+
+ if (Py_TYPE(v)->tp_setattr != NULL)
+ return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w);
+ s = PyString_InternFromString(name);
+ if (s == NULL)
+ return -1;
+ res = PyObject_SetAttr(v, s, w);
+ Py_XDECREF(s);
+ return res;
+}
+
+PyObject *
+PyObject_GetAttr(PyObject *v, PyObject *name)
+{
+ PyTypeObject *tp = Py_TYPE(v);
+
+ if (!PyString_Check(name)) {
+#ifdef Py_USING_UNICODE
+ /* The Unicode to string conversion is done here because the
+ existing tp_getattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = _PyUnicode_AsDefaultEncodedString(name, NULL);
+ if (name == NULL)
+ return NULL;
+ }
+ else
+#endif
+ {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ Py_TYPE(name)->tp_name);
+ return NULL;
+ }
+ }
+ if (tp->tp_getattro != NULL)
+ return (*tp->tp_getattro)(v, name);
+ if (tp->tp_getattr != NULL)
+ return (*tp->tp_getattr)(v, PyString_AS_STRING(name));
+ PyErr_Format(PyExc_AttributeError,
+ "'%.50s' object has no attribute '%.400s'",
+ tp->tp_name, PyString_AS_STRING(name));
+ return NULL;
+}
+
+int
+PyObject_HasAttr(PyObject *v, PyObject *name)
+{
+ PyObject *res = PyObject_GetAttr(v, name);
+ if (res != NULL) {
+ Py_DECREF(res);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
+}
+
+int
+PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
+{
+ PyTypeObject *tp = Py_TYPE(v);
+ int err;
+
+ if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+ /* The Unicode to string conversion is done here because the
+ existing tp_setattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = PyUnicode_AsEncodedString(name, NULL, NULL);
+ if (name == NULL)
+ return -1;
+ }
+ else
+#endif
+ {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ Py_TYPE(name)->tp_name);
+ return -1;
+ }
+ }
+ else
+ Py_INCREF(name);
+
+ PyString_InternInPlace(&name);
+ if (tp->tp_setattro != NULL) {
+ err = (*tp->tp_setattro)(v, name, value);
+ Py_DECREF(name);
+ return err;
+ }
+ if (tp->tp_setattr != NULL) {
+ err = (*tp->tp_setattr)(v, PyString_AS_STRING(name), value);
+ Py_DECREF(name);
+ return err;
+ }
+ Py_DECREF(name);
+ if (tp->tp_getattr == NULL && tp->tp_getattro == NULL)
+ PyErr_Format(PyExc_TypeError,
+ "'%.100s' object has no attributes "
+ "(%s .%.100s)",
+ tp->tp_name,
+ value==NULL ? "del" : "assign to",
+ PyString_AS_STRING(name));
+ else
+ PyErr_Format(PyExc_TypeError,
+ "'%.100s' object has only read-only attributes "
+ "(%s .%.100s)",
+ tp->tp_name,
+ value==NULL ? "del" : "assign to",
+ PyString_AS_STRING(name));
+ return -1;
+}
+
+/* Helper to get a pointer to an object's __dict__ slot, if any */
+
+PyObject **
+_PyObject_GetDictPtr(PyObject *obj)
+{
+ Py_ssize_t dictoffset;
+ PyTypeObject *tp = Py_TYPE(obj);
+
+ if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+ return NULL;
+ dictoffset = tp->tp_dictoffset;
+ if (dictoffset == 0)
+ return NULL;
+ if (dictoffset < 0) {
+ Py_ssize_t tsize;
+ size_t size;
+
+ tsize = ((PyVarObject *)obj)->ob_size;
+ if (tsize < 0)
+ tsize = -tsize;
+ size = _PyObject_VAR_SIZE(tp, tsize);
+
+ dictoffset += (long)size;
+ assert(dictoffset > 0);
+ assert(dictoffset % SIZEOF_VOID_P == 0);
+ }
+ return (PyObject **) ((char *)obj + dictoffset);
+}
+
+PyObject *
+PyObject_SelfIter(PyObject *obj)
+{
+ Py_INCREF(obj);
+ return obj;
+}
+
+/* Helper used when the __next__ method is removed from a type:
+ tp_iternext is never NULL and can be safely called without checking
+ on every iteration.
+ */
+
+PyObject *
+_PyObject_NextNotImplemented(PyObject *self)
+{
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not iterable",
+ Py_TYPE(self)->tp_name);
+ return NULL;
+}
+
+/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
+
+PyObject *
+_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
+{
+ PyTypeObject *tp = Py_TYPE(obj);
+ PyObject *descr = NULL;
+ PyObject *res = NULL;
+ descrgetfunc f;
+ Py_ssize_t dictoffset;
+ PyObject **dictptr;
+
+ if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+ /* The Unicode to string conversion is done here because the
+ existing tp_setattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = PyUnicode_AsEncodedString(name, NULL, NULL);
+ if (name == NULL)
+ return NULL;
+ }
+ else
+#endif
+ {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ Py_TYPE(name)->tp_name);
+ return NULL;
+ }
+ }
+ else
+ Py_INCREF(name);
+
+ if (tp->tp_dict == NULL) {
+ if (PyType_Ready(tp) < 0)
+ goto done;
+ }
+
+#if 0 /* XXX this is not quite _PyType_Lookup anymore */
+ /* Inline _PyType_Lookup */
+ {
+ Py_ssize_t i, n;
+ PyObject *mro, *base, *dict;
+
+ /* Look in tp_dict of types in MRO */
+ mro = tp->tp_mro;
+ assert(mro != NULL);
+ assert(PyTuple_Check(mro));
+ n = PyTuple_GET_SIZE(mro);
+ for (i = 0; i < n; i++) {
+ base = PyTuple_GET_ITEM(mro, i);
+ if (PyClass_Check(base))
+ dict = ((PyClassObject *)base)->cl_dict;
+ else {
+ assert(PyType_Check(base));
+ dict = ((PyTypeObject *)base)->tp_dict;
+ }
+ assert(dict && PyDict_Check(dict));
+ descr = PyDict_GetItem(dict, name);
+ if (descr != NULL)
+ break;
+ }
+ }
+#else
+ descr = _PyType_Lookup(tp, name);
+#endif
+
+ Py_XINCREF(descr);
+
+ f = NULL;
+ if (descr != NULL &&
+ PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+ f = descr->ob_type->tp_descr_get;
+ if (f != NULL && PyDescr_IsData(descr)) {
+ res = f(descr, obj, (PyObject *)obj->ob_type);
+ Py_DECREF(descr);
+ goto done;
+ }
+ }
+
+ if (dict == NULL) {
+ /* Inline _PyObject_GetDictPtr */
+ dictoffset = tp->tp_dictoffset;
+ if (dictoffset != 0) {
+ if (dictoffset < 0) {
+ Py_ssize_t tsize;
+ size_t size;
+
+ tsize = ((PyVarObject *)obj)->ob_size;
+ if (tsize < 0)
+ tsize = -tsize;
+ size = _PyObject_VAR_SIZE(tp, tsize);
+
+ dictoffset += (long)size;
+ assert(dictoffset > 0);
+ assert(dictoffset % SIZEOF_VOID_P == 0);
+ }
+ dictptr = (PyObject **) ((char *)obj + dictoffset);
+ dict = *dictptr;
+ }
+ }
+ if (dict != NULL) {
+ Py_INCREF(dict);
+ res = PyDict_GetItem(dict, name);
+ if (res != NULL) {
+ Py_INCREF(res);
+ Py_XDECREF(descr);
+ Py_DECREF(dict);
+ goto done;
+ }
+ Py_DECREF(dict);
+ }
+
+ if (f != NULL) {
+ res = f(descr, obj, (PyObject *)Py_TYPE(obj));
+ Py_DECREF(descr);
+ goto done;
+ }
+
+ if (descr != NULL) {
+ res = descr;
+ /* descr was already increfed above */
+ goto done;
+ }
+
+ PyErr_Format(PyExc_AttributeError,
+ "'%.50s' object has no attribute '%.400s'",
+ tp->tp_name, PyString_AS_STRING(name));
+ done:
+ Py_DECREF(name);
+ return res;
+}
+
+PyObject *
+PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
+{
+ return _PyObject_GenericGetAttrWithDict(obj, name, NULL);
+}
+
+int
+_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
+ PyObject *value, PyObject *dict)
+{
+ PyTypeObject *tp = Py_TYPE(obj);
+ PyObject *descr;
+ descrsetfunc f;
+ PyObject **dictptr;
+ int res = -1;
+
+ if (!PyString_Check(name)){
+#ifdef Py_USING_UNICODE
+ /* The Unicode to string conversion is done here because the
+ existing tp_setattro slots expect a string object as name
+ and we wouldn't want to break those. */
+ if (PyUnicode_Check(name)) {
+ name = PyUnicode_AsEncodedString(name, NULL, NULL);
+ if (name == NULL)
+ return -1;
+ }
+ else
+#endif
+ {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ Py_TYPE(name)->tp_name);
+ return -1;
+ }
+ }
+ else
+ Py_INCREF(name);
+
+ if (tp->tp_dict == NULL) {
+ if (PyType_Ready(tp) < 0)
+ goto done;
+ }
+
+ descr = _PyType_Lookup(tp, name);
+ f = NULL;
+ if (descr != NULL &&
+ PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
+ f = descr->ob_type->tp_descr_set;
+ if (f != NULL && PyDescr_IsData(descr)) {
+ res = f(descr, obj, value);
+ goto done;
+ }
+ }
+
+ if (dict == NULL) {
+ dictptr = _PyObject_GetDictPtr(obj);
+ if (dictptr != NULL) {
+ dict = *dictptr;
+ if (dict == NULL && value != NULL) {
+ dict = PyDict_New();
+ if (dict == NULL)
+ goto done;
+ *dictptr = dict;
+ }
+ }
+ }
+ if (dict != NULL) {
+ Py_INCREF(dict);
+ if (value == NULL)
+ res = PyDict_DelItem(dict, name);
+ else
+ res = PyDict_SetItem(dict, name, value);
+ if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+ PyErr_SetObject(PyExc_AttributeError, name);
+ Py_DECREF(dict);
+ goto done;
+ }
+
+ if (f != NULL) {
+ res = f(descr, obj, value);
+ goto done;
+ }
+
+ if (descr == NULL) {
+ PyErr_Format(PyExc_AttributeError,
+ "'%.100s' object has no attribute '%.200s'",
+ tp->tp_name, PyString_AS_STRING(name));
+ goto done;
+ }
+
+ PyErr_Format(PyExc_AttributeError,
+ "'%.50s' object attribute '%.400s' is read-only",
+ tp->tp_name, PyString_AS_STRING(name));
+ done:
+ Py_DECREF(name);
+ return res;
+}
+
+int
+PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
+{
+ return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL);
+}
+
+
+/* Test a value used as condition, e.g., in a for or if statement.
+ Return -1 if an error occurred */
+
+int
+PyObject_IsTrue(PyObject *v)
+{
+ Py_ssize_t res;
+ if (v == Py_True)
+ return 1;
+ if (v == Py_False)
+ return 0;
+ if (v == Py_None)
+ return 0;
+ else if (v->ob_type->tp_as_number != NULL &&
+ v->ob_type->tp_as_number->nb_nonzero != NULL)
+ res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
+ else if (v->ob_type->tp_as_mapping != NULL &&
+ v->ob_type->tp_as_mapping->mp_length != NULL)
+ res = (*v->ob_type->tp_as_mapping->mp_length)(v);
+ else if (v->ob_type->tp_as_sequence != NULL &&
+ v->ob_type->tp_as_sequence->sq_length != NULL)
+ res = (*v->ob_type->tp_as_sequence->sq_length)(v);
+ else
+ return 1;
+ /* if it is negative, it should be either -1 or -2 */
+ return (res > 0) ? 1 : Py_SAFE_DOWNCAST(res, Py_ssize_t, int);
+}
+
+/* equivalent of 'not v'
+ Return -1 if an error occurred */
+
+int
+PyObject_Not(PyObject *v)
+{
+ int res;
+ res = PyObject_IsTrue(v);
+ if (res < 0)
+ return res;
+ return res == 0;
+}
+
+/* Coerce two numeric types to the "larger" one.
+ Increment the reference count on each argument.
+ Return value:
+ -1 if an error occurred;
+ 0 if the coercion succeeded (and then the reference counts are increased);
+ 1 if no coercion is possible (and no error is raised).
+*/
+int
+PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
+{
+ register PyObject *v = *pv;
+ register PyObject *w = *pw;
+ int res;
+
+ /* Shortcut only for old-style types */
+ if (v->ob_type == w->ob_type &&
+ !PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
+ {
+ Py_INCREF(v);
+ Py_INCREF(w);
+ return 0;
+ }
+ if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
+ res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
+ if (res <= 0)
+ return res;
+ }
+ if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) {
+ res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv);
+ if (res <= 0)
+ return res;
+ }
+ return 1;
+}
+
+/* Coerce two numeric types to the "larger" one.
+ Increment the reference count on each argument.
+ Return -1 and raise an exception if no coercion is possible
+ (and then no reference count is incremented).
+*/
+int
+PyNumber_Coerce(PyObject **pv, PyObject **pw)
+{
+ int err = PyNumber_CoerceEx(pv, pw);
+ if (err <= 0)
+ return err;
+ PyErr_SetString(PyExc_TypeError, "number coercion failed");
+ return -1;
+}
+
+
+/* Test whether an object can be called */
+
+int
+PyCallable_Check(PyObject *x)
+{
+ if (x == NULL)
+ return 0;
+ if (PyInstance_Check(x)) {
+ PyObject *call = PyObject_GetAttrString(x, "__call__");
+ if (call == NULL) {
+ PyErr_Clear();
+ return 0;
+ }
+ /* Could test recursively but don't, for fear of endless
+ recursion if some joker sets self.__call__ = self */
+ Py_DECREF(call);
+ return 1;
+ }
+ else {
+ return x->ob_type->tp_call != NULL;
+ }
+}
+
+/* ------------------------- PyObject_Dir() helpers ------------------------- */
+
+/* Helper for PyObject_Dir.
+ Merge the __dict__ of aclass into dict, and recursively also all
+ the __dict__s of aclass's base classes. The order of merging isn't
+ defined, as it's expected that only the final set of dict keys is
+ interesting.
+ Return 0 on success, -1 on error.
+*/
+
+static int
+merge_class_dict(PyObject* dict, PyObject* aclass)
+{
+ PyObject *classdict;
+ PyObject *bases;
+
+ assert(PyDict_Check(dict));
+ assert(aclass);
+
+ /* Merge in the type's dict (if any). */
+ classdict = PyObject_GetAttrString(aclass, "__dict__");
+ if (classdict == NULL)
+ PyErr_Clear();
+ else {
+ int status = PyDict_Update(dict, classdict);
+ Py_DECREF(classdict);
+ if (status < 0)
+ return -1;
+ }
+
+ /* Recursively merge in the base types' (if any) dicts. */
+ bases = PyObject_GetAttrString(aclass, "__bases__");
+ if (bases == NULL)
+ PyErr_Clear();
+ else {
+ /* We have no guarantee that bases is a real tuple */
+ Py_ssize_t i, n;
+ n = PySequence_Size(bases); /* This better be right */
+ if (n < 0)
+ PyErr_Clear();
+ else {
+ for (i = 0; i < n; i++) {
+ int status;
+ PyObject *base = PySequence_GetItem(bases, i);
+ if (base == NULL) {
+ Py_DECREF(bases);
+ return -1;
+ }
+ status = merge_class_dict(dict, base);
+ Py_DECREF(base);
+ if (status < 0) {
+ Py_DECREF(bases);
+ return -1;
+ }
+ }
+ }
+ Py_DECREF(bases);
+ }
+ return 0;
+}
+
+/* Helper for PyObject_Dir.
+ If obj has an attr named attrname that's a list, merge its string
+ elements into keys of dict.
+ Return 0 on success, -1 on error. Errors due to not finding the attr,
+ or the attr not being a list, are suppressed.
+*/
+
+static int
+merge_list_attr(PyObject* dict, PyObject* obj, const char *attrname)
+{
+ PyObject *list;
+ int result = 0;
+
+ assert(PyDict_Check(dict));
+ assert(obj);
+ assert(attrname);
+
+ list = PyObject_GetAttrString(obj, attrname);
+ if (list == NULL)
+ PyErr_Clear();
+
+ else if (PyList_Check(list)) {
+ int i;
+ for (i = 0; i < PyList_GET_SIZE(list); ++i) {
+ PyObject *item = PyList_GET_ITEM(list, i);
+ if (PyString_Check(item)) {
+ result = PyDict_SetItem(dict, item, Py_None);
+ if (result < 0)
+ break;
+ }
+ }
+ if (Py_Py3kWarningFlag &&
+ (strcmp(attrname, "__members__") == 0 ||
+ strcmp(attrname, "__methods__") == 0)) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "__members__ and __methods__ not "
+ "supported in 3.x", 1) < 0) {
+ Py_XDECREF(list);
+ return -1;
+ }
+ }
+ }
+
+ Py_XDECREF(list);
+ return result;
+}
+
+/* Helper for PyObject_Dir without arguments: returns the local scope. */
+static PyObject *
+_dir_locals(void)
+{
+ PyObject *names;
+ PyObject *locals = PyEval_GetLocals();
+
+ if (locals == NULL) {
+ PyErr_SetString(PyExc_SystemError, "frame does not exist");
+ return NULL;
+ }
+
+ names = PyMapping_Keys(locals);
+ if (!names)
+ return NULL;
+ if (!PyList_Check(names)) {
+ PyErr_Format(PyExc_TypeError,
+ "dir(): expected keys() of locals to be a list, "
+ "not '%.200s'", Py_TYPE(names)->tp_name);
+ Py_DECREF(names);
+ return NULL;
+ }
+ /* the locals don't need to be DECREF'd */
+ return names;
+}
+
+/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__.
+ We deliberately don't suck up its __class__, as methods belonging to the
+ metaclass would probably be more confusing than helpful.
+*/
+static PyObject *
+_specialized_dir_type(PyObject *obj)
+{
+ PyObject *result = NULL;
+ PyObject *dict = PyDict_New();
+
+ if (dict != NULL && merge_class_dict(dict, obj) == 0)
+ result = PyDict_Keys(dict);
+
+ Py_XDECREF(dict);
+ return result;
+}
+
+/* Helper for PyObject_Dir of module objects: returns the module's __dict__. */
+static PyObject *
+_specialized_dir_module(PyObject *obj)
+{
+ PyObject *result = NULL;
+ PyObject *dict = PyObject_GetAttrString(obj, "__dict__");
+
+ if (dict != NULL) {
+ if (PyDict_Check(dict))
+ result = PyDict_Keys(dict);
+ else {
+ char *name = PyModule_GetName(obj);
+ if (name)
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.__dict__ is not a dictionary",
+ name);
+ }
+ }
+
+ Py_XDECREF(dict);
+ return result;
+}
+
+/* Helper for PyObject_Dir of generic objects: returns __dict__, __class__,
+ and recursively up the __class__.__bases__ chain.
+*/
+static PyObject *
+_generic_dir(PyObject *obj)
+{
+ PyObject *result = NULL;
+ PyObject *dict = NULL;
+ PyObject *itsclass = NULL;
+
+ /* Get __dict__ (which may or may not be a real dict...) */
+ dict = PyObject_GetAttrString(obj, "__dict__");
+ if (dict == NULL) {
+ PyErr_Clear();
+ dict = PyDict_New();
+ }
+ else if (!PyDict_Check(dict)) {
+ Py_DECREF(dict);
+ dict = PyDict_New();
+ }
+ else {
+ /* Copy __dict__ to avoid mutating it. */
+ PyObject *temp = PyDict_Copy(dict);
+ Py_DECREF(dict);
+ dict = temp;
+ }
+
+ if (dict == NULL)
+ goto error;
+
+ /* Merge in __members__ and __methods__ (if any).
+ * This is removed in Python 3000. */
+ if (merge_list_attr(dict, obj, "__members__") < 0)
+ goto error;
+ if (merge_list_attr(dict, obj, "__methods__") < 0)
+ goto error;
+
+ /* Merge in attrs reachable from its class. */
+ itsclass = PyObject_GetAttrString(obj, "__class__");
+ if (itsclass == NULL)
+ /* XXX(tomer): Perhaps fall back to obj->ob_type if no
+ __class__ exists? */
+ PyErr_Clear();
+ else {
+ if (merge_class_dict(dict, itsclass) != 0)
+ goto error;
+ }
+
+ result = PyDict_Keys(dict);
+ /* fall through */
+error:
+ Py_XDECREF(itsclass);
+ Py_XDECREF(dict);
+ return result;
+}
+
+/* Helper for PyObject_Dir: object introspection.
+ This calls one of the above specialized versions if no __dir__ method
+ exists. */
+static PyObject *
+_dir_object(PyObject *obj)
+{
+ PyObject *result = NULL;
+ static PyObject *dir_str = NULL;
+ PyObject *dirfunc;
+
+ assert(obj);
+ if (PyInstance_Check(obj)) {
+ dirfunc = PyObject_GetAttrString(obj, "__dir__");
+ if (dirfunc == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str);
+ if (PyErr_Occurred())
+ return NULL;
+ }
+ if (dirfunc == NULL) {
+ /* use default implementation */
+ if (PyModule_Check(obj))
+ result = _specialized_dir_module(obj);
+ else if (PyType_Check(obj) || PyClass_Check(obj))
+ result = _specialized_dir_type(obj);
+ else
+ result = _generic_dir(obj);
+ }
+ else {
+ /* use __dir__ */
+ result = PyObject_CallFunctionObjArgs(dirfunc, NULL);
+ Py_DECREF(dirfunc);
+ if (result == NULL)
+ return NULL;
+
+ /* result must be a list */
+ /* XXX(gbrandl): could also check if all items are strings */
+ if (!PyList_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "__dir__() must return a list, not %.200s",
+ Py_TYPE(result)->tp_name);
+ Py_DECREF(result);
+ result = NULL;
+ }
+ }
+
+ return result;
+}
+
+/* Implementation of dir() -- if obj is NULL, returns the names in the current
+ (local) scope. Otherwise, performs introspection of the object: returns a
+ sorted list of attribute names (supposedly) accessible from the object
+*/
+PyObject *
+PyObject_Dir(PyObject *obj)
+{
+ PyObject * result;
+
+ if (obj == NULL)
+ /* no object -- introspect the locals */
+ result = _dir_locals();
+ else
+ /* object -- introspect the object */
+ result = _dir_object(obj);
+
+ assert(result == NULL || PyList_Check(result));
+
+ if (result != NULL && PyList_Sort(result) != 0) {
+ /* sorting the list failed */
+ Py_DECREF(result);
+ result = NULL;
+ }
+
+ return result;
+}
+
+/*
+NoObject is usable as a non-NULL undefined value, used by the macro None.
+There is (and should be!) no way to create other objects of this type,
+so there is exactly one (which is indestructible, by the way).
+(XXX This type and the type of NotImplemented below should be unified.)
+*/
+
+/* ARGSUSED */
+static PyObject *
+none_repr(PyObject *op)
+{
+ return PyString_FromString("None");
+}
+
+/* ARGUSED */
+static void
+none_dealloc(PyObject* ignore)
+{
+ /* This should never get called, but we also don't want to SEGV if
+ * we accidentally decref None out of existence.
+ */
+ Py_FatalError("deallocating None");
+}
+
+
+static PyTypeObject PyNone_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "NoneType",
+ 0,
+ 0,
+ none_dealloc, /*tp_dealloc*/ /*never called*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ none_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)_Py_HashPointer, /*tp_hash */
+};
+
+PyObject _Py_NoneStruct = {
+ _PyObject_EXTRA_INIT
+ 1, &PyNone_Type
+};
+
+/* NotImplemented is an object that can be used to signal that an
+ operation is not implemented for the given type combination. */
+
+static PyObject *
+NotImplemented_repr(PyObject *op)
+{
+ return PyString_FromString("NotImplemented");
+}
+
+static PyTypeObject PyNotImplemented_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "NotImplementedType",
+ 0,
+ 0,
+ none_dealloc, /*tp_dealloc*/ /*never called*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ NotImplemented_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+};
+
+PyObject _Py_NotImplementedStruct = {
+ _PyObject_EXTRA_INIT
+ 1, &PyNotImplemented_Type
+};
+
+void
+_Py_ReadyTypes(void)
+{
+ if (PyType_Ready(&PyType_Type) < 0)
+ Py_FatalError("Can't initialize type type");
+
+ if (PyType_Ready(&_PyWeakref_RefType) < 0)
+ Py_FatalError("Can't initialize weakref type");
+
+ if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0)
+ Py_FatalError("Can't initialize callable weakref proxy type");
+
+ if (PyType_Ready(&_PyWeakref_ProxyType) < 0)
+ Py_FatalError("Can't initialize weakref proxy type");
+
+ if (PyType_Ready(&PyBool_Type) < 0)
+ Py_FatalError("Can't initialize bool type");
+
+ if (PyType_Ready(&PyString_Type) < 0)
+ Py_FatalError("Can't initialize str type");
+
+ if (PyType_Ready(&PyByteArray_Type) < 0)
+ Py_FatalError("Can't initialize bytearray type");
+
+ if (PyType_Ready(&PyList_Type) < 0)
+ Py_FatalError("Can't initialize list type");
+
+ if (PyType_Ready(&PyNone_Type) < 0)
+ Py_FatalError("Can't initialize None type");
+
+ if (PyType_Ready(&PyNotImplemented_Type) < 0)
+ Py_FatalError("Can't initialize NotImplemented type");
+
+ if (PyType_Ready(&PyTraceBack_Type) < 0)
+ Py_FatalError("Can't initialize traceback type");
+
+ if (PyType_Ready(&PySuper_Type) < 0)
+ Py_FatalError("Can't initialize super type");
+
+ if (PyType_Ready(&PyBaseObject_Type) < 0)
+ Py_FatalError("Can't initialize object type");
+
+ if (PyType_Ready(&PyRange_Type) < 0)
+ Py_FatalError("Can't initialize xrange type");
+
+ if (PyType_Ready(&PyDict_Type) < 0)
+ Py_FatalError("Can't initialize dict type");
+
+ if (PyType_Ready(&PySet_Type) < 0)
+ Py_FatalError("Can't initialize set type");
+
+#ifdef Py_USING_UNICODE
+ if (PyType_Ready(&PyUnicode_Type) < 0)
+ Py_FatalError("Can't initialize unicode type");
+#endif
+
+ if (PyType_Ready(&PySlice_Type) < 0)
+ Py_FatalError("Can't initialize slice type");
+
+ if (PyType_Ready(&PyStaticMethod_Type) < 0)
+ Py_FatalError("Can't initialize static method type");
+
+#ifndef WITHOUT_COMPLEX
+ if (PyType_Ready(&PyComplex_Type) < 0)
+ Py_FatalError("Can't initialize complex type");
+#endif
+
+ if (PyType_Ready(&PyFloat_Type) < 0)
+ Py_FatalError("Can't initialize float type");
+
+ if (PyType_Ready(&PyBuffer_Type) < 0)
+ Py_FatalError("Can't initialize buffer type");
+
+ if (PyType_Ready(&PyLong_Type) < 0)
+ Py_FatalError("Can't initialize long type");
+
+ if (PyType_Ready(&PyInt_Type) < 0)
+ Py_FatalError("Can't initialize int type");
+
+ if (PyType_Ready(&PyFrozenSet_Type) < 0)
+ Py_FatalError("Can't initialize frozenset type");
+
+ if (PyType_Ready(&PyProperty_Type) < 0)
+ Py_FatalError("Can't initialize property type");
+
+ if (PyType_Ready(&PyMemoryView_Type) < 0)
+ Py_FatalError("Can't initialize memoryview type");
+
+ if (PyType_Ready(&PyTuple_Type) < 0)
+ Py_FatalError("Can't initialize tuple type");
+
+ if (PyType_Ready(&PyEnum_Type) < 0)
+ Py_FatalError("Can't initialize enumerate type");
+
+ if (PyType_Ready(&PyReversed_Type) < 0)
+ Py_FatalError("Can't initialize reversed type");
+
+ if (PyType_Ready(&PyCode_Type) < 0)
+ Py_FatalError("Can't initialize code type");
+
+ if (PyType_Ready(&PyFrame_Type) < 0)
+ Py_FatalError("Can't initialize frame type");
+
+ if (PyType_Ready(&PyCFunction_Type) < 0)
+ Py_FatalError("Can't initialize builtin function type");
+
+ if (PyType_Ready(&PyMethod_Type) < 0)
+ Py_FatalError("Can't initialize method type");
+
+ if (PyType_Ready(&PyFunction_Type) < 0)
+ Py_FatalError("Can't initialize function type");
+
+ if (PyType_Ready(&PyClass_Type) < 0)
+ Py_FatalError("Can't initialize class type");
+
+ if (PyType_Ready(&PyDictProxy_Type) < 0)
+ Py_FatalError("Can't initialize dict proxy type");
+
+ if (PyType_Ready(&PyGen_Type) < 0)
+ Py_FatalError("Can't initialize generator type");
+
+ if (PyType_Ready(&PyGetSetDescr_Type) < 0)
+ Py_FatalError("Can't initialize get-set descriptor type");
+
+ if (PyType_Ready(&PyWrapperDescr_Type) < 0)
+ Py_FatalError("Can't initialize wrapper type");
+
+ if (PyType_Ready(&PyInstance_Type) < 0)
+ Py_FatalError("Can't initialize instance type");
+
+ if (PyType_Ready(&PyEllipsis_Type) < 0)
+ Py_FatalError("Can't initialize ellipsis type");
+
+ if (PyType_Ready(&PyMemberDescr_Type) < 0)
+ Py_FatalError("Can't initialize member descriptor type");
+
+ if (PyType_Ready(&PyFile_Type) < 0)
+ Py_FatalError("Can't initialize file type");
+
+ if (PyType_Ready(&PyCapsule_Type) < 0)
+ Py_FatalError("Can't initialize capsule type");
+
+ if (PyType_Ready(&PyCell_Type) < 0)
+ Py_FatalError("Can't initialize cell type");
+
+ if (PyType_Ready(&PyCallIter_Type) < 0)
+ Py_FatalError("Can't initialize call iter type");
+
+ if (PyType_Ready(&PySeqIter_Type) < 0)
+ Py_FatalError("Can't initialize sequence iterator type");
+}
+
+
+#ifdef Py_TRACE_REFS
+
+void
+_Py_NewReference(PyObject *op)
+{
+ _Py_INC_REFTOTAL;
+ op->ob_refcnt = 1;
+ _Py_AddToAllObjects(op, 1);
+ _Py_INC_TPALLOCS(op);
+}
+
+void
+_Py_ForgetReference(register PyObject *op)
+{
+#ifdef SLOW_UNREF_CHECK
+ register PyObject *p;
+#endif
+ if (op->ob_refcnt < 0)
+ Py_FatalError("UNREF negative refcnt");
+ if (op == &refchain ||
+ op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
+ Py_FatalError("UNREF invalid object");
+#ifdef SLOW_UNREF_CHECK
+ for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
+ if (p == op)
+ break;
+ }
+ if (p == &refchain) /* Not found */
+ Py_FatalError("UNREF unknown object");
+#endif
+ op->_ob_next->_ob_prev = op->_ob_prev;
+ op->_ob_prev->_ob_next = op->_ob_next;
+ op->_ob_next = op->_ob_prev = NULL;
+ _Py_INC_TPFREES(op);
+}
+
+void
+_Py_Dealloc(PyObject *op)
+{
+ destructor dealloc = Py_TYPE(op)->tp_dealloc;
+ _Py_ForgetReference(op);
+ (*dealloc)(op);
+}
+
+/* Print all live objects. Because PyObject_Print is called, the
+ * interpreter must be in a healthy state.
+ */
+void
+_Py_PrintReferences(FILE *fp)
+{
+ PyObject *op;
+ fprintf(fp, "Remaining objects:\n");
+ for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
+ fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", op, op->ob_refcnt);
+ if (PyObject_Print(op, fp, 0) != 0)
+ PyErr_Clear();
+ putc('\n', fp);
+ }
+}
+
+/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
+ * doesn't make any calls to the Python C API, so is always safe to call.
+ */
+void
+_Py_PrintReferenceAddresses(FILE *fp)
+{
+ PyObject *op;
+ fprintf(fp, "Remaining object addresses:\n");
+ for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
+ fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", op,
+ op->ob_refcnt, Py_TYPE(op)->tp_name);
+}
+
+PyObject *
+_Py_GetObjects(PyObject *self, PyObject *args)
+{
+ int i, n;
+ PyObject *t = NULL;
+ PyObject *res, *op;
+
+ if (!PyArg_ParseTuple(args, "i|O", &n, &t))
+ return NULL;
+ op = refchain._ob_next;
+ res = PyList_New(0);
+ if (res == NULL)
+ return NULL;
+ for (i = 0; (n == 0 || i < n) && op != &refchain; i++) {
+ while (op == self || op == args || op == res || op == t ||
+ (t != NULL && Py_TYPE(op) != (PyTypeObject *) t)) {
+ op = op->_ob_next;
+ if (op == &refchain)
+ return res;
+ }
+ if (PyList_Append(res, op) < 0) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ op = op->_ob_next;
+ }
+ return res;
+}
+
+#endif
+
+
+/* Hack to force loading of capsule.o */
+PyTypeObject *_Py_capsule_hack = &PyCapsule_Type;
+
+
+/* Hack to force loading of cobject.o */
+PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
+
+
+/* Hack to force loading of abstract.o */
+Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
+
+
+/* Python's malloc wrappers (see pymem.h) */
+
+void *
+PyMem_Malloc(size_t nbytes)
+{
+ return PyMem_MALLOC(nbytes);
+}
+
+void *
+PyMem_Realloc(void *p, size_t nbytes)
+{
+ return PyMem_REALLOC(p, nbytes);
+}
+
+void
+PyMem_Free(void *p)
+{
+ PyMem_FREE(p);
+}
+
+
+/* These methods are used to control infinite recursion in repr, str, print,
+ etc. Container objects that may recursively contain themselves,
+ e.g. builtin dictionaries and lists, should used Py_ReprEnter() and
+ Py_ReprLeave() to avoid infinite recursion.
+
+ Py_ReprEnter() returns 0 the first time it is called for a particular
+ object and 1 every time thereafter. It returns -1 if an exception
+ occurred. Py_ReprLeave() has no return value.
+
+ See dictobject.c and listobject.c for examples of use.
+*/
+
+#define KEY "Py_Repr"
+
+int
+Py_ReprEnter(PyObject *obj)
+{
+ PyObject *dict;
+ PyObject *list;
+ Py_ssize_t i;
+
+ dict = PyThreadState_GetDict();
+ if (dict == NULL)
+ return 0;
+ list = PyDict_GetItemString(dict, KEY);
+ if (list == NULL) {
+ list = PyList_New(0);
+ if (list == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, KEY, list) < 0)
+ return -1;
+ Py_DECREF(list);
+ }
+ i = PyList_GET_SIZE(list);
+ while (--i >= 0) {
+ if (PyList_GET_ITEM(list, i) == obj)
+ return 1;
+ }
+ PyList_Append(list, obj);
+ return 0;
+}
+
+void
+Py_ReprLeave(PyObject *obj)
+{
+ PyObject *dict;
+ PyObject *list;
+ Py_ssize_t i;
+
+ dict = PyThreadState_GetDict();
+ if (dict == NULL)
+ return;
+ list = PyDict_GetItemString(dict, KEY);
+ if (list == NULL || !PyList_Check(list))
+ return;
+ i = PyList_GET_SIZE(list);
+ /* Count backwards because we always expect obj to be list[-1] */
+ while (--i >= 0) {
+ if (PyList_GET_ITEM(list, i) == obj) {
+ PyList_SetSlice(list, i, i + 1, NULL);
+ break;
+ }
+ }
+}
+
+/* Trashcan support. */
+
+/* Current call-stack depth of tp_dealloc calls. */
+int _PyTrash_delete_nesting = 0;
+
+/* List of objects that still need to be cleaned up, singly linked via their
+ * gc headers' gc_prev pointers.
+ */
+PyObject *_PyTrash_delete_later = NULL;
+
+/* Add op to the _PyTrash_delete_later list. Called when the current
+ * call-stack depth gets large. op must be a currently untracked gc'ed
+ * object, with refcount 0. Py_DECREF must already have been called on it.
+ */
+void
+_PyTrash_deposit_object(PyObject *op)
+{
+ assert(PyObject_IS_GC(op));
+ assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);
+ assert(op->ob_refcnt == 0);
+ _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *)_PyTrash_delete_later;
+ _PyTrash_delete_later = op;
+}
+
+/* The equivalent API, using per-thread state recursion info */
+void
+_PyTrash_thread_deposit_object(PyObject *op)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ assert(PyObject_IS_GC(op));
+ assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);
+ assert(op->ob_refcnt == 0);
+ _Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *) tstate->trash_delete_later;
+ tstate->trash_delete_later = op;
+}
+
+/* Dealloccate all the objects in the _PyTrash_delete_later list. Called when
+ * the call-stack unwinds again.
+ */
+void
+_PyTrash_destroy_chain(void)
+{
+ while (_PyTrash_delete_later) {
+ PyObject *op = _PyTrash_delete_later;
+ destructor dealloc = Py_TYPE(op)->tp_dealloc;
+
+ _PyTrash_delete_later =
+ (PyObject*) _Py_AS_GC(op)->gc.gc_prev;
+
+ /* Call the deallocator directly. This used to try to
+ * fool Py_DECREF into calling it indirectly, but
+ * Py_DECREF was already called on this object, and in
+ * assorted non-release builds calling Py_DECREF again ends
+ * up distorting allocation statistics.
+ */
+ assert(op->ob_refcnt == 0);
+ ++_PyTrash_delete_nesting;
+ (*dealloc)(op);
+ --_PyTrash_delete_nesting;
+ }
+}
+
+/* The equivalent API, using per-thread state recursion info */
+void
+_PyTrash_thread_destroy_chain(void)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ while (tstate->trash_delete_later) {
+ PyObject *op = tstate->trash_delete_later;
+ destructor dealloc = Py_TYPE(op)->tp_dealloc;
+
+ tstate->trash_delete_later =
+ (PyObject*) _Py_AS_GC(op)->gc.gc_prev;
+
+ /* Call the deallocator directly. This used to try to
+ * fool Py_DECREF into calling it indirectly, but
+ * Py_DECREF was already called on this object, and in
+ * assorted non-release builds calling Py_DECREF again ends
+ * up distorting allocation statistics.
+ */
+ assert(op->ob_refcnt == 0);
+ ++tstate->trash_delete_nesting;
+ (*dealloc)(op);
+ --tstate->trash_delete_nesting;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/obmalloc.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/obmalloc.c
new file mode 100644
index 0000000000..2e83c3e1ad
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/obmalloc.c
@@ -0,0 +1,1937 @@
+#include "Python.h"
+
+#if defined(__has_feature) /* Clang */
+ #if __has_feature(address_sanitizer) /* is ASAN enabled? */
+ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
+ __attribute__((no_address_safety_analysis)) \
+ __attribute__ ((noinline))
+ #else
+ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
+ #endif
+#else
+ #if defined(__SANITIZE_ADDRESS__) /* GCC 4.8.x, is ASAN enabled? */
+ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
+ __attribute__((no_address_safety_analysis)) \
+ __attribute__ ((noinline))
+ #else
+ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
+ #endif
+#endif
+
+#ifdef WITH_PYMALLOC
+
+#ifdef HAVE_MMAP
+ #include <sys/mman.h>
+ #ifdef MAP_ANONYMOUS
+ #define ARENAS_USE_MMAP
+ #endif
+#endif
+
+#ifdef WITH_VALGRIND
+#include <valgrind/valgrind.h>
+
+/* If we're using GCC, use __builtin_expect() to reduce overhead of
+ the valgrind checks */
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+# define UNLIKELY(value) __builtin_expect((value), 0)
+#else
+# define UNLIKELY(value) (value)
+#endif
+
+/* -1 indicates that we haven't checked that we're running on valgrind yet. */
+static int running_on_valgrind = -1;
+#endif
+
+/* An object allocator for Python.
+
+ Here is an introduction to the layers of the Python memory architecture,
+ showing where the object allocator is actually used (layer +2), It is
+ called for every object allocation and deallocation (PyObject_New/Del),
+ unless the object-specific allocators implement a proprietary allocation
+ scheme (ex.: ints use a simple free list). This is also the place where
+ the cyclic garbage collector operates selectively on container objects.
+
+
+ Object-specific allocators
+ _____ ______ ______ ________
+ [ int ] [ dict ] [ list ] ... [ string ] Python core |
++3 | <----- Object-specific memory -----> | <-- Non-object memory --> |
+ _______________________________ | |
+ [ Python's object allocator ] | |
++2 | ####### Object memory ####### | <------ Internal buffers ------> |
+ ______________________________________________________________ |
+ [ Python's raw memory allocator (PyMem_ API) ] |
++1 | <----- Python memory (under PyMem manager's control) ------> | |
+ __________________________________________________________________
+ [ Underlying general-purpose allocator (ex: C library malloc) ]
+ 0 | <------ Virtual memory allocated for the python process -------> |
+
+ =========================================================================
+ _______________________________________________________________________
+ [ OS-specific Virtual Memory Manager (VMM) ]
+-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> |
+ __________________________________ __________________________________
+ [ ] [ ]
+-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> |
+
+*/
+/*==========================================================================*/
+
+/* A fast, special-purpose memory allocator for small blocks, to be used
+ on top of a general-purpose malloc -- heavily based on previous art. */
+
+/* Vladimir Marangozov -- August 2000 */
+
+/*
+ * "Memory management is where the rubber meets the road -- if we do the wrong
+ * thing at any level, the results will not be good. And if we don't make the
+ * levels work well together, we are in serious trouble." (1)
+ *
+ * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles,
+ * "Dynamic Storage Allocation: A Survey and Critical Review",
+ * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995.
+ */
+
+/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */
+
+/*==========================================================================*/
+
+/*
+ * Allocation strategy abstract:
+ *
+ * For small requests, the allocator sub-allocates <Big> blocks of memory.
+ * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the
+ * system's allocator.
+ *
+ * Small requests are grouped in size classes spaced 8 bytes apart, due
+ * to the required valid alignment of the returned address. Requests of
+ * a particular size are serviced from memory pools of 4K (one VMM page).
+ * Pools are fragmented on demand and contain free lists of blocks of one
+ * particular size class. In other words, there is a fixed-size allocator
+ * for each size class. Free pools are shared by the different allocators
+ * thus minimizing the space reserved for a particular size class.
+ *
+ * This allocation strategy is a variant of what is known as "simple
+ * segregated storage based on array of free lists". The main drawback of
+ * simple segregated storage is that we might end up with lot of reserved
+ * memory for the different free lists, which degenerate in time. To avoid
+ * this, we partition each free list in pools and we share dynamically the
+ * reserved space between all free lists. This technique is quite efficient
+ * for memory intensive programs which allocate mainly small-sized blocks.
+ *
+ * For small requests we have the following table:
+ *
+ * Request in bytes Size of allocated block Size class idx
+ * ----------------------------------------------------------------
+ * 1-8 8 0
+ * 9-16 16 1
+ * 17-24 24 2
+ * 25-32 32 3
+ * 33-40 40 4
+ * 41-48 48 5
+ * 49-56 56 6
+ * 57-64 64 7
+ * 65-72 72 8
+ * ... ... ...
+ * 497-504 504 62
+ * 505-512 512 63
+ *
+ * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying
+ * allocator.
+ */
+
+/*==========================================================================*/
+
+/*
+ * -- Main tunable settings section --
+ */
+
+/*
+ * Alignment of addresses returned to the user. 8-bytes alignment works
+ * on most current architectures (with 32-bit or 64-bit address busses).
+ * The alignment value is also used for grouping small requests in size
+ * classes spaced ALIGNMENT bytes apart.
+ *
+ * You shouldn't change this unless you know what you are doing.
+ */
+#define ALIGNMENT 8 /* must be 2^N */
+#define ALIGNMENT_SHIFT 3
+#define ALIGNMENT_MASK (ALIGNMENT - 1)
+
+/* Return the number of bytes in size class I, as a uint. */
+#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT)
+
+/*
+ * Max size threshold below which malloc requests are considered to be
+ * small enough in order to use preallocated memory pools. You can tune
+ * this value according to your application behaviour and memory needs.
+ *
+ * The following invariants must hold:
+ * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 256
+ * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT
+ *
+ * Note: a size threshold of 512 guarantees that newly created dictionaries
+ * will be allocated from preallocated memory pools on 64-bit.
+ *
+ * Although not required, for better performance and space efficiency,
+ * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2.
+ */
+#define SMALL_REQUEST_THRESHOLD 512
+#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT)
+
+/*
+ * The system's VMM page size can be obtained on most unices with a
+ * getpagesize() call or deduced from various header files. To make
+ * things simpler, we assume that it is 4K, which is OK for most systems.
+ * It is probably better if this is the native page size, but it doesn't
+ * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page
+ * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation
+ * violation fault. 4K is apparently OK for all the platforms that python
+ * currently targets.
+ */
+#define SYSTEM_PAGE_SIZE (4 * 1024)
+#define SYSTEM_PAGE_SIZE_MASK (SYSTEM_PAGE_SIZE - 1)
+
+/*
+ * Maximum amount of memory managed by the allocator for small requests.
+ */
+#ifdef WITH_MEMORY_LIMITS
+#ifndef SMALL_MEMORY_LIMIT
+#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */
+#endif
+#endif
+
+/*
+ * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned
+ * on a page boundary. This is a reserved virtual address space for the
+ * current process (obtained through a malloc()/mmap() call). In no way this
+ * means that the memory arenas will be used entirely. A malloc(<Big>) is
+ * usually an address range reservation for <Big> bytes, unless all pages within
+ * this space are referenced subsequently. So malloc'ing big blocks and not
+ * using them does not mean "wasting memory". It's an addressable range
+ * wastage...
+ *
+ * Arenas are allocated with mmap() on systems supporting anonymous memory
+ * mappings to reduce heap fragmentation.
+ */
+#define ARENA_SIZE (256 << 10) /* 256KB */
+
+#ifdef WITH_MEMORY_LIMITS
+#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE)
+#endif
+
+/*
+ * Size of the pools used for small blocks. Should be a power of 2,
+ * between 1K and SYSTEM_PAGE_SIZE, that is: 1k, 2k, 4k.
+ */
+#define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */
+#define POOL_SIZE_MASK SYSTEM_PAGE_SIZE_MASK
+
+/*
+ * -- End of tunable settings section --
+ */
+
+/*==========================================================================*/
+
+/*
+ * Locking
+ *
+ * To reduce lock contention, it would probably be better to refine the
+ * crude function locking with per size class locking. I'm not positive
+ * however, whether it's worth switching to such locking policy because
+ * of the performance penalty it might introduce.
+ *
+ * The following macros describe the simplest (should also be the fastest)
+ * lock object on a particular platform and the init/fini/lock/unlock
+ * operations on it. The locks defined here are not expected to be recursive
+ * because it is assumed that they will always be called in the order:
+ * INIT, [LOCK, UNLOCK]*, FINI.
+ */
+
+/*
+ * Python's threads are serialized, so object malloc locking is disabled.
+ */
+#define SIMPLELOCK_DECL(lock) /* simple lock declaration */
+#define SIMPLELOCK_INIT(lock) /* allocate (if needed) and initialize */
+#define SIMPLELOCK_FINI(lock) /* free/destroy an existing lock */
+#define SIMPLELOCK_LOCK(lock) /* acquire released lock */
+#define SIMPLELOCK_UNLOCK(lock) /* release acquired lock */
+
+/*
+ * Basic types
+ * I don't care if these are defined in <sys/types.h> or elsewhere. Axiom.
+ */
+#undef uchar
+#define uchar unsigned char /* assuming == 8 bits */
+
+#undef uint
+#define uint unsigned int /* assuming >= 16 bits */
+
+#undef ulong
+#define ulong unsigned long /* assuming >= 32 bits */
+
+#undef uptr
+#define uptr Py_uintptr_t
+
+/* When you say memory, my mind reasons in terms of (pointers to) blocks */
+typedef uchar block;
+
+/* Pool for small blocks. */
+struct pool_header {
+ union { block *_padding;
+ uint count; } ref; /* number of allocated blocks */
+ block *freeblock; /* pool's free list head */
+ struct pool_header *nextpool; /* next pool of this size class */
+ struct pool_header *prevpool; /* previous pool "" */
+ uint arenaindex; /* index into arenas of base adr */
+ uint szidx; /* block size class index */
+ uint nextoffset; /* bytes to virgin block */
+ uint maxnextoffset; /* largest valid nextoffset */
+};
+
+typedef struct pool_header *poolp;
+
+/* Record keeping for arenas. */
+struct arena_object {
+ /* The address of the arena, as returned by malloc. Note that 0
+ * will never be returned by a successful malloc, and is used
+ * here to mark an arena_object that doesn't correspond to an
+ * allocated arena.
+ */
+ uptr address;
+
+ /* Pool-aligned pointer to the next pool to be carved off. */
+ block* pool_address;
+
+ /* The number of available pools in the arena: free pools + never-
+ * allocated pools.
+ */
+ uint nfreepools;
+
+ /* The total number of pools in the arena, whether or not available. */
+ uint ntotalpools;
+
+ /* Singly-linked list of available pools. */
+ struct pool_header* freepools;
+
+ /* Whenever this arena_object is not associated with an allocated
+ * arena, the nextarena member is used to link all unassociated
+ * arena_objects in the singly-linked `unused_arena_objects` list.
+ * The prevarena member is unused in this case.
+ *
+ * When this arena_object is associated with an allocated arena
+ * with at least one available pool, both members are used in the
+ * doubly-linked `usable_arenas` list, which is maintained in
+ * increasing order of `nfreepools` values.
+ *
+ * Else this arena_object is associated with an allocated arena
+ * all of whose pools are in use. `nextarena` and `prevarena`
+ * are both meaningless in this case.
+ */
+ struct arena_object* nextarena;
+ struct arena_object* prevarena;
+};
+
+#undef ROUNDUP
+#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
+#define POOL_OVERHEAD ROUNDUP(sizeof(struct pool_header))
+
+#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */
+
+/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */
+#define POOL_ADDR(P) ((poolp)((uptr)(P) & ~(uptr)POOL_SIZE_MASK))
+
+/* Return total number of blocks in pool of size index I, as a uint. */
+#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I))
+
+/*==========================================================================*/
+
+/*
+ * This malloc lock
+ */
+SIMPLELOCK_DECL(_malloc_lock)
+#define LOCK() SIMPLELOCK_LOCK(_malloc_lock)
+#define UNLOCK() SIMPLELOCK_UNLOCK(_malloc_lock)
+#define LOCK_INIT() SIMPLELOCK_INIT(_malloc_lock)
+#define LOCK_FINI() SIMPLELOCK_FINI(_malloc_lock)
+
+/*
+ * Pool table -- headed, circular, doubly-linked lists of partially used pools.
+
+This is involved. For an index i, usedpools[i+i] is the header for a list of
+all partially used pools holding small blocks with "size class idx" i. So
+usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size
+16, and so on: index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT.
+
+Pools are carved off an arena's highwater mark (an arena_object's pool_address
+member) as needed. Once carved off, a pool is in one of three states forever
+after:
+
+used == partially used, neither empty nor full
+ At least one block in the pool is currently allocated, and at least one
+ block in the pool is not currently allocated (note this implies a pool
+ has room for at least two blocks).
+ This is a pool's initial state, as a pool is created only when malloc
+ needs space.
+ The pool holds blocks of a fixed size, and is in the circular list headed
+ at usedpools[i] (see above). It's linked to the other used pools of the
+ same size class via the pool_header's nextpool and prevpool members.
+ If all but one block is currently allocated, a malloc can cause a
+ transition to the full state. If all but one block is not currently
+ allocated, a free can cause a transition to the empty state.
+
+full == all the pool's blocks are currently allocated
+ On transition to full, a pool is unlinked from its usedpools[] list.
+ It's not linked to from anything then anymore, and its nextpool and
+ prevpool members are meaningless until it transitions back to used.
+ A free of a block in a full pool puts the pool back in the used state.
+ Then it's linked in at the front of the appropriate usedpools[] list, so
+ that the next allocation for its size class will reuse the freed block.
+
+empty == all the pool's blocks are currently available for allocation
+ On transition to empty, a pool is unlinked from its usedpools[] list,
+ and linked to the front of its arena_object's singly-linked freepools list,
+ via its nextpool member. The prevpool member has no meaning in this case.
+ Empty pools have no inherent size class: the next time a malloc finds
+ an empty list in usedpools[], it takes the first pool off of freepools.
+ If the size class needed happens to be the same as the size class the pool
+ last had, some pool initialization can be skipped.
+
+
+Block Management
+
+Blocks within pools are again carved out as needed. pool->freeblock points to
+the start of a singly-linked list of free blocks within the pool. When a
+block is freed, it's inserted at the front of its pool's freeblock list. Note
+that the available blocks in a pool are *not* linked all together when a pool
+is initialized. Instead only "the first two" (lowest addresses) blocks are
+set up, returning the first such block, and setting pool->freeblock to a
+one-block list holding the second such block. This is consistent with that
+pymalloc strives at all levels (arena, pool, and block) never to touch a piece
+of memory until it's actually needed.
+
+So long as a pool is in the used state, we're certain there *is* a block
+available for allocating, and pool->freeblock is not NULL. If pool->freeblock
+points to the end of the free list before we've carved the entire pool into
+blocks, that means we simply haven't yet gotten to one of the higher-address
+blocks. The offset from the pool_header to the start of "the next" virgin
+block is stored in the pool_header nextoffset member, and the largest value
+of nextoffset that makes sense is stored in the maxnextoffset member when a
+pool is initialized. All the blocks in a pool have been passed out at least
+once when and only when nextoffset > maxnextoffset.
+
+
+Major obscurity: While the usedpools vector is declared to have poolp
+entries, it doesn't really. It really contains two pointers per (conceptual)
+poolp entry, the nextpool and prevpool members of a pool_header. The
+excruciating initialization code below fools C so that
+
+ usedpool[i+i]
+
+"acts like" a genuine poolp, but only so long as you only reference its
+nextpool and prevpool members. The "- 2*sizeof(block *)" gibberish is
+compensating for that a pool_header's nextpool and prevpool members
+immediately follow a pool_header's first two members:
+
+ union { block *_padding;
+ uint count; } ref;
+ block *freeblock;
+
+each of which consume sizeof(block *) bytes. So what usedpools[i+i] really
+contains is a fudged-up pointer p such that *if* C believes it's a poolp
+pointer, then p->nextpool and p->prevpool are both p (meaning that the headed
+circular list is empty).
+
+It's unclear why the usedpools setup is so convoluted. It could be to
+minimize the amount of cache required to hold this heavily-referenced table
+(which only *needs* the two interpool pointer members of a pool_header). OTOH,
+referencing code has to remember to "double the index" and doing so isn't
+free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying
+on that C doesn't insert any padding anywhere in a pool_header at or before
+the prevpool member.
+**************************************************************************** */
+
+#define PTA(x) ((poolp )((uchar *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
+#define PT(x) PTA(x), PTA(x)
+
+static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = {
+ PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7)
+#if NB_SMALL_SIZE_CLASSES > 8
+ , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15)
+#if NB_SMALL_SIZE_CLASSES > 16
+ , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23)
+#if NB_SMALL_SIZE_CLASSES > 24
+ , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31)
+#if NB_SMALL_SIZE_CLASSES > 32
+ , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39)
+#if NB_SMALL_SIZE_CLASSES > 40
+ , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47)
+#if NB_SMALL_SIZE_CLASSES > 48
+ , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55)
+#if NB_SMALL_SIZE_CLASSES > 56
+ , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63)
+#if NB_SMALL_SIZE_CLASSES > 64
+#error "NB_SMALL_SIZE_CLASSES should be less than 64"
+#endif /* NB_SMALL_SIZE_CLASSES > 64 */
+#endif /* NB_SMALL_SIZE_CLASSES > 56 */
+#endif /* NB_SMALL_SIZE_CLASSES > 48 */
+#endif /* NB_SMALL_SIZE_CLASSES > 40 */
+#endif /* NB_SMALL_SIZE_CLASSES > 32 */
+#endif /* NB_SMALL_SIZE_CLASSES > 24 */
+#endif /* NB_SMALL_SIZE_CLASSES > 16 */
+#endif /* NB_SMALL_SIZE_CLASSES > 8 */
+};
+
+/*==========================================================================
+Arena management.
+
+`arenas` is a vector of arena_objects. It contains maxarenas entries, some of
+which may not be currently used (== they're arena_objects that aren't
+currently associated with an allocated arena). Note that arenas proper are
+separately malloc'ed.
+
+Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5,
+we do try to free() arenas, and use some mild heuristic strategies to increase
+the likelihood that arenas eventually can be freed.
+
+unused_arena_objects
+
+ This is a singly-linked list of the arena_objects that are currently not
+ being used (no arena is associated with them). Objects are taken off the
+ head of the list in new_arena(), and are pushed on the head of the list in
+ PyObject_Free() when the arena is empty. Key invariant: an arena_object
+ is on this list if and only if its .address member is 0.
+
+usable_arenas
+
+ This is a doubly-linked list of the arena_objects associated with arenas
+ that have pools available. These pools are either waiting to be reused,
+ or have not been used before. The list is sorted to have the most-
+ allocated arenas first (ascending order based on the nfreepools member).
+ This means that the next allocation will come from a heavily used arena,
+ which gives the nearly empty arenas a chance to be returned to the system.
+ In my unscientific tests this dramatically improved the number of arenas
+ that could be freed.
+
+Note that an arena_object associated with an arena all of whose pools are
+currently in use isn't on either list.
+*/
+
+/* Array of objects used to track chunks of memory (arenas). */
+static struct arena_object* arenas = NULL;
+/* Number of slots currently allocated in the `arenas` vector. */
+static uint maxarenas = 0;
+
+/* The head of the singly-linked, NULL-terminated list of available
+ * arena_objects.
+ */
+static struct arena_object* unused_arena_objects = NULL;
+
+/* The head of the doubly-linked, NULL-terminated at each end, list of
+ * arena_objects associated with arenas that have pools available.
+ */
+static struct arena_object* usable_arenas = NULL;
+
+/* How many arena_objects do we initially allocate?
+ * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
+ * `arenas` vector.
+ */
+#define INITIAL_ARENA_OBJECTS 16
+
+/* Number of arenas allocated that haven't been free()'d. */
+static size_t narenas_currently_allocated = 0;
+
+#ifdef PYMALLOC_DEBUG
+/* Total number of times malloc() called to allocate an arena. */
+static size_t ntimes_arena_allocated = 0;
+/* High water mark (max value ever seen) for narenas_currently_allocated. */
+static size_t narenas_highwater = 0;
+#endif
+
+/* Allocate a new arena. If we run out of memory, return NULL. Else
+ * allocate a new arena, and return the address of an arena_object
+ * describing the new arena. It's expected that the caller will set
+ * `usable_arenas` to the return value.
+ */
+static struct arena_object*
+new_arena(void)
+{
+ struct arena_object* arenaobj;
+ uint excess; /* number of bytes above pool alignment */
+ void *address;
+ int err;
+
+#ifdef PYMALLOC_DEBUG
+ if (Py_GETENV("PYTHONMALLOCSTATS"))
+ _PyObject_DebugMallocStats();
+#endif
+ if (unused_arena_objects == NULL) {
+ uint i;
+ uint numarenas;
+ size_t nbytes;
+
+ /* Double the number of arena objects on each allocation.
+ * Note that it's possible for `numarenas` to overflow.
+ */
+ numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
+ if (numarenas <= maxarenas)
+ return NULL; /* overflow */
+#if SIZEOF_SIZE_T <= SIZEOF_INT
+ if (numarenas > PY_SIZE_MAX / sizeof(*arenas))
+ return NULL; /* overflow */
+#endif
+ nbytes = numarenas * sizeof(*arenas);
+ arenaobj = (struct arena_object *)realloc(arenas, nbytes);
+ if (arenaobj == NULL)
+ return NULL;
+ arenas = arenaobj;
+
+ /* We might need to fix pointers that were copied. However,
+ * new_arena only gets called when all the pages in the
+ * previous arenas are full. Thus, there are *no* pointers
+ * into the old array. Thus, we don't have to worry about
+ * invalid pointers. Just to be sure, some asserts:
+ */
+ assert(usable_arenas == NULL);
+ assert(unused_arena_objects == NULL);
+
+ /* Put the new arenas on the unused_arena_objects list. */
+ for (i = maxarenas; i < numarenas; ++i) {
+ arenas[i].address = 0; /* mark as unassociated */
+ arenas[i].nextarena = i < numarenas - 1 ?
+ &arenas[i+1] : NULL;
+ }
+
+ /* Update globals. */
+ unused_arena_objects = &arenas[maxarenas];
+ maxarenas = numarenas;
+ }
+
+ /* Take the next available arena object off the head of the list. */
+ assert(unused_arena_objects != NULL);
+ arenaobj = unused_arena_objects;
+ unused_arena_objects = arenaobj->nextarena;
+ assert(arenaobj->address == 0);
+#ifdef ARENAS_USE_MMAP
+ address = mmap(NULL, ARENA_SIZE, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ err = (address == MAP_FAILED);
+#else
+ address = malloc(ARENA_SIZE);
+ err = (address == 0);
+#endif
+ if (err) {
+ /* The allocation failed: return NULL after putting the
+ * arenaobj back.
+ */
+ arenaobj->nextarena = unused_arena_objects;
+ unused_arena_objects = arenaobj;
+ return NULL;
+ }
+ arenaobj->address = (uptr)address;
+
+ ++narenas_currently_allocated;
+#ifdef PYMALLOC_DEBUG
+ ++ntimes_arena_allocated;
+ if (narenas_currently_allocated > narenas_highwater)
+ narenas_highwater = narenas_currently_allocated;
+#endif
+ arenaobj->freepools = NULL;
+ /* pool_address <- first pool-aligned address in the arena
+ nfreepools <- number of whole pools that fit after alignment */
+ arenaobj->pool_address = (block*)arenaobj->address;
+ arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE;
+ assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE);
+ excess = (uint)(arenaobj->address & POOL_SIZE_MASK);
+ if (excess != 0) {
+ --arenaobj->nfreepools;
+ arenaobj->pool_address += POOL_SIZE - excess;
+ }
+ arenaobj->ntotalpools = arenaobj->nfreepools;
+
+ return arenaobj;
+}
+
+/*
+Py_ADDRESS_IN_RANGE(P, POOL)
+
+Return true if and only if P is an address that was allocated by pymalloc.
+POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
+(the caller is asked to compute this because the macro expands POOL more than
+once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
+variable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
+called on every alloc/realloc/free, micro-efficiency is important here).
+
+Tricky: Let B be the arena base address associated with the pool, B =
+arenas[(POOL)->arenaindex].address. Then P belongs to the arena if and only if
+
+ B <= P < B + ARENA_SIZE
+
+Subtracting B throughout, this is true iff
+
+ 0 <= P-B < ARENA_SIZE
+
+By using unsigned arithmetic, the "0 <=" half of the test can be skipped.
+
+Obscure: A PyMem "free memory" function can call the pymalloc free or realloc
+before the first arena has been allocated. `arenas` is still NULL in that
+case. We're relying on that maxarenas is also 0 in that case, so that
+(POOL)->arenaindex < maxarenas must be false, saving us from trying to index
+into a NULL arenas.
+
+Details: given P and POOL, the arena_object corresponding to P is AO =
+arenas[(POOL)->arenaindex]. Suppose obmalloc controls P. Then (barring wild
+stores, etc), POOL is the correct address of P's pool, AO.address is the
+correct base address of the pool's arena, and P must be within ARENA_SIZE of
+AO.address. In addition, AO.address is not 0 (no arena can start at address 0
+(NULL)). Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
+controls P.
+
+Now suppose obmalloc does not control P (e.g., P was obtained via a direct
+call to the system malloc() or realloc()). (POOL)->arenaindex may be anything
+in this case -- it may even be uninitialized trash. If the trash arenaindex
+is >= maxarenas, the macro correctly concludes at once that obmalloc doesn't
+control P.
+
+Else arenaindex is < maxarena, and AO is read up. If AO corresponds to an
+allocated arena, obmalloc controls all the memory in slice AO.address :
+AO.address+ARENA_SIZE. By case assumption, P is not controlled by obmalloc,
+so P doesn't lie in that slice, so the macro correctly reports that P is not
+controlled by obmalloc.
+
+Finally, if P is not controlled by obmalloc and AO corresponds to an unused
+arena_object (one not currently associated with an allocated arena),
+AO.address is 0, and the second test in the macro reduces to:
+
+ P < ARENA_SIZE
+
+If P >= ARENA_SIZE (extremely likely), the macro again correctly concludes
+that P is not controlled by obmalloc. However, if P < ARENA_SIZE, this part
+of the test still passes, and the third clause (AO.address != 0) is necessary
+to get the correct result: AO.address is 0 in this case, so the macro
+correctly reports that P is not controlled by obmalloc (despite that P lies in
+slice AO.address : AO.address + ARENA_SIZE).
+
+Note: The third (AO.address != 0) clause was added in Python 2.5. Before
+2.5, arenas were never free()'ed, and an arenaindex < maxarena always
+corresponded to a currently-allocated arena, so the "P is not controlled by
+obmalloc, AO corresponds to an unused arena_object, and P < ARENA_SIZE" case
+was impossible.
+
+Note that the logic is excruciating, and reading up possibly uninitialized
+memory when P is not controlled by obmalloc (to get at (POOL)->arenaindex)
+creates problems for some memory debuggers. The overwhelming advantage is
+that this test determines whether an arbitrary address is controlled by
+obmalloc in a small constant time, independent of the number of arenas
+obmalloc controls. Since this test is needed at every entry point, it's
+extremely desirable that it be this fast.
+
+Since Py_ADDRESS_IN_RANGE may be reading from memory which was not allocated
+by Python, it is important that (POOL)->arenaindex is read only once, as
+another thread may be concurrently modifying the value without holding the
+GIL. To accomplish this, the arenaindex_temp variable is used to store
+(POOL)->arenaindex for the duration of the Py_ADDRESS_IN_RANGE macro's
+execution. The caller of the macro is responsible for declaring this
+variable.
+*/
+#define Py_ADDRESS_IN_RANGE(P, POOL) \
+ ((arenaindex_temp = (POOL)->arenaindex) < maxarenas && \
+ (uptr)(P) - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && \
+ arenas[arenaindex_temp].address != 0)
+
+
+/* This is only useful when running memory debuggers such as
+ * Purify or Valgrind. Uncomment to use.
+ *
+#define Py_USING_MEMORY_DEBUGGER
+ */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+
+/* Py_ADDRESS_IN_RANGE may access uninitialized memory by design
+ * This leads to thousands of spurious warnings when using
+ * Purify or Valgrind. By making a function, we can easily
+ * suppress the uninitialized memory reads in this one function.
+ * So we won't ignore real errors elsewhere.
+ *
+ * Disable the macro and use a function.
+ */
+
+#undef Py_ADDRESS_IN_RANGE
+
+#if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \
+ (__GNUC__ >= 4))
+#define Py_NO_INLINE __attribute__((__noinline__))
+#else
+#define Py_NO_INLINE
+#endif
+
+/* Don't make static, to try to ensure this isn't inlined. */
+int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE;
+#undef Py_NO_INLINE
+#endif
+
+/*==========================================================================*/
+
+/* malloc. Note that nbytes==0 tries to return a non-NULL pointer, distinct
+ * from all other currently live pointers. This may not be possible.
+ */
+
+/*
+ * The basic blocks are ordered by decreasing execution frequency,
+ * which minimizes the number of jumps in the most common cases,
+ * improves branching prediction and instruction scheduling (small
+ * block allocations typically result in a couple of instructions).
+ * Unless the optimizer reorders everything, being too smart...
+ */
+
+#undef PyObject_Malloc
+void *
+PyObject_Malloc(size_t nbytes)
+{
+ block *bp;
+ poolp pool;
+ poolp next;
+ uint size;
+
+#ifdef WITH_VALGRIND
+ if (UNLIKELY(running_on_valgrind == -1))
+ running_on_valgrind = RUNNING_ON_VALGRIND;
+ if (UNLIKELY(running_on_valgrind))
+ goto redirect;
+#endif
+
+ /*
+ * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
+ * Most python internals blindly use a signed Py_ssize_t to track
+ * things without checking for overflows or negatives.
+ * As size_t is unsigned, checking for nbytes < 0 is not required.
+ */
+ if (nbytes > PY_SSIZE_T_MAX)
+ return NULL;
+
+ /*
+ * This implicitly redirects malloc(0).
+ */
+ if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) {
+ LOCK();
+ /*
+ * Most frequent paths first
+ */
+ size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT;
+ pool = usedpools[size + size];
+ if (pool != pool->nextpool) {
+ /*
+ * There is a used pool for this size class.
+ * Pick up the head block of its free list.
+ */
+ ++pool->ref.count;
+ bp = pool->freeblock;
+ assert(bp != NULL);
+ if ((pool->freeblock = *(block **)bp) != NULL) {
+ UNLOCK();
+ return (void *)bp;
+ }
+ /*
+ * Reached the end of the free list, try to extend it.
+ */
+ if (pool->nextoffset <= pool->maxnextoffset) {
+ /* There is room for another block. */
+ pool->freeblock = (block*)pool +
+ pool->nextoffset;
+ pool->nextoffset += INDEX2SIZE(size);
+ *(block **)(pool->freeblock) = NULL;
+ UNLOCK();
+ return (void *)bp;
+ }
+ /* Pool is full, unlink from used pools. */
+ next = pool->nextpool;
+ pool = pool->prevpool;
+ next->prevpool = pool;
+ pool->nextpool = next;
+ UNLOCK();
+ return (void *)bp;
+ }
+
+ /* There isn't a pool of the right size class immediately
+ * available: use a free pool.
+ */
+ if (usable_arenas == NULL) {
+ /* No arena has a free pool: allocate a new arena. */
+#ifdef WITH_MEMORY_LIMITS
+ if (narenas_currently_allocated >= MAX_ARENAS) {
+ UNLOCK();
+ goto redirect;
+ }
+#endif
+ usable_arenas = new_arena();
+ if (usable_arenas == NULL) {
+ UNLOCK();
+ goto redirect;
+ }
+ usable_arenas->nextarena =
+ usable_arenas->prevarena = NULL;
+ }
+ assert(usable_arenas->address != 0);
+
+ /* Try to get a cached free pool. */
+ pool = usable_arenas->freepools;
+ if (pool != NULL) {
+ /* Unlink from cached pools. */
+ usable_arenas->freepools = pool->nextpool;
+
+ /* This arena already had the smallest nfreepools
+ * value, so decreasing nfreepools doesn't change
+ * that, and we don't need to rearrange the
+ * usable_arenas list. However, if the arena has
+ * become wholly allocated, we need to remove its
+ * arena_object from usable_arenas.
+ */
+ --usable_arenas->nfreepools;
+ if (usable_arenas->nfreepools == 0) {
+ /* Wholly allocated: remove. */
+ assert(usable_arenas->freepools == NULL);
+ assert(usable_arenas->nextarena == NULL ||
+ usable_arenas->nextarena->prevarena ==
+ usable_arenas);
+
+ usable_arenas = usable_arenas->nextarena;
+ if (usable_arenas != NULL) {
+ usable_arenas->prevarena = NULL;
+ assert(usable_arenas->address != 0);
+ }
+ }
+ else {
+ /* nfreepools > 0: it must be that freepools
+ * isn't NULL, or that we haven't yet carved
+ * off all the arena's pools for the first
+ * time.
+ */
+ assert(usable_arenas->freepools != NULL ||
+ usable_arenas->pool_address <=
+ (block*)usable_arenas->address +
+ ARENA_SIZE - POOL_SIZE);
+ }
+ init_pool:
+ /* Frontlink to used pools. */
+ next = usedpools[size + size]; /* == prev */
+ pool->nextpool = next;
+ pool->prevpool = next;
+ next->nextpool = pool;
+ next->prevpool = pool;
+ pool->ref.count = 1;
+ if (pool->szidx == size) {
+ /* Luckily, this pool last contained blocks
+ * of the same size class, so its header
+ * and free list are already initialized.
+ */
+ bp = pool->freeblock;
+ pool->freeblock = *(block **)bp;
+ UNLOCK();
+ return (void *)bp;
+ }
+ /*
+ * Initialize the pool header, set up the free list to
+ * contain just the second block, and return the first
+ * block.
+ */
+ pool->szidx = size;
+ size = INDEX2SIZE(size);
+ bp = (block *)pool + POOL_OVERHEAD;
+ pool->nextoffset = POOL_OVERHEAD + (size << 1);
+ pool->maxnextoffset = POOL_SIZE - size;
+ pool->freeblock = bp + size;
+ *(block **)(pool->freeblock) = NULL;
+ UNLOCK();
+ return (void *)bp;
+ }
+
+ /* Carve off a new pool. */
+ assert(usable_arenas->nfreepools > 0);
+ assert(usable_arenas->freepools == NULL);
+ pool = (poolp)usable_arenas->pool_address;
+ assert((block*)pool <= (block*)usable_arenas->address +
+ ARENA_SIZE - POOL_SIZE);
+ pool->arenaindex = usable_arenas - arenas;
+ assert(&arenas[pool->arenaindex] == usable_arenas);
+ pool->szidx = DUMMY_SIZE_IDX;
+ usable_arenas->pool_address += POOL_SIZE;
+ --usable_arenas->nfreepools;
+
+ if (usable_arenas->nfreepools == 0) {
+ assert(usable_arenas->nextarena == NULL ||
+ usable_arenas->nextarena->prevarena ==
+ usable_arenas);
+ /* Unlink the arena: it is completely allocated. */
+ usable_arenas = usable_arenas->nextarena;
+ if (usable_arenas != NULL) {
+ usable_arenas->prevarena = NULL;
+ assert(usable_arenas->address != 0);
+ }
+ }
+
+ goto init_pool;
+ }
+
+ /* The small block allocator ends here. */
+
+redirect:
+ /* Redirect the original request to the underlying (libc) allocator.
+ * We jump here on bigger requests, on error in the code above (as a
+ * last chance to serve the request) or when the max memory limit
+ * has been reached.
+ */
+ if (nbytes == 0)
+ nbytes = 1;
+ return (void *)malloc(nbytes);
+}
+
+/* free */
+
+#undef PyObject_Free
+ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
+void
+PyObject_Free(void *p)
+{
+ poolp pool;
+ block *lastfree;
+ poolp next, prev;
+ uint size;
+#ifndef Py_USING_MEMORY_DEBUGGER
+ uint arenaindex_temp;
+#endif
+
+ if (p == NULL) /* free(NULL) has no effect */
+ return;
+
+#ifdef WITH_VALGRIND
+ if (UNLIKELY(running_on_valgrind > 0))
+ goto redirect;
+#endif
+
+ pool = POOL_ADDR(p);
+ if (Py_ADDRESS_IN_RANGE(p, pool)) {
+ /* We allocated this address. */
+ LOCK();
+ /* Link p to the start of the pool's freeblock list. Since
+ * the pool had at least the p block outstanding, the pool
+ * wasn't empty (so it's already in a usedpools[] list, or
+ * was full and is in no list -- it's not in the freeblocks
+ * list in any case).
+ */
+ assert(pool->ref.count > 0); /* else it was empty */
+ *(block **)p = lastfree = pool->freeblock;
+ pool->freeblock = (block *)p;
+ if (lastfree) {
+ struct arena_object* ao;
+ uint nf; /* ao->nfreepools */
+
+ /* freeblock wasn't NULL, so the pool wasn't full,
+ * and the pool is in a usedpools[] list.
+ */
+ if (--pool->ref.count != 0) {
+ /* pool isn't empty: leave it in usedpools */
+ UNLOCK();
+ return;
+ }
+ /* Pool is now empty: unlink from usedpools, and
+ * link to the front of freepools. This ensures that
+ * previously freed pools will be allocated later
+ * (being not referenced, they are perhaps paged out).
+ */
+ next = pool->nextpool;
+ prev = pool->prevpool;
+ next->prevpool = prev;
+ prev->nextpool = next;
+
+ /* Link the pool to freepools. This is a singly-linked
+ * list, and pool->prevpool isn't used there.
+ */
+ ao = &arenas[pool->arenaindex];
+ pool->nextpool = ao->freepools;
+ ao->freepools = pool;
+ nf = ++ao->nfreepools;
+
+ /* All the rest is arena management. We just freed
+ * a pool, and there are 4 cases for arena mgmt:
+ * 1. If all the pools are free, return the arena to
+ * the system free().
+ * 2. If this is the only free pool in the arena,
+ * add the arena back to the `usable_arenas` list.
+ * 3. If the "next" arena has a smaller count of free
+ * pools, we have to "slide this arena right" to
+ * restore that usable_arenas is sorted in order of
+ * nfreepools.
+ * 4. Else there's nothing more to do.
+ */
+ if (nf == ao->ntotalpools) {
+ /* Case 1. First unlink ao from usable_arenas.
+ */
+ assert(ao->prevarena == NULL ||
+ ao->prevarena->address != 0);
+ assert(ao ->nextarena == NULL ||
+ ao->nextarena->address != 0);
+
+ /* Fix the pointer in the prevarena, or the
+ * usable_arenas pointer.
+ */
+ if (ao->prevarena == NULL) {
+ usable_arenas = ao->nextarena;
+ assert(usable_arenas == NULL ||
+ usable_arenas->address != 0);
+ }
+ else {
+ assert(ao->prevarena->nextarena == ao);
+ ao->prevarena->nextarena =
+ ao->nextarena;
+ }
+ /* Fix the pointer in the nextarena. */
+ if (ao->nextarena != NULL) {
+ assert(ao->nextarena->prevarena == ao);
+ ao->nextarena->prevarena =
+ ao->prevarena;
+ }
+ /* Record that this arena_object slot is
+ * available to be reused.
+ */
+ ao->nextarena = unused_arena_objects;
+ unused_arena_objects = ao;
+
+ /* Free the entire arena. */
+#ifdef ARENAS_USE_MMAP
+ munmap((void *)ao->address, ARENA_SIZE);
+#else
+ free((void *)ao->address);
+#endif
+ ao->address = 0; /* mark unassociated */
+ --narenas_currently_allocated;
+
+ UNLOCK();
+ return;
+ }
+ if (nf == 1) {
+ /* Case 2. Put ao at the head of
+ * usable_arenas. Note that because
+ * ao->nfreepools was 0 before, ao isn't
+ * currently on the usable_arenas list.
+ */
+ ao->nextarena = usable_arenas;
+ ao->prevarena = NULL;
+ if (usable_arenas)
+ usable_arenas->prevarena = ao;
+ usable_arenas = ao;
+ assert(usable_arenas->address != 0);
+
+ UNLOCK();
+ return;
+ }
+ /* If this arena is now out of order, we need to keep
+ * the list sorted. The list is kept sorted so that
+ * the "most full" arenas are used first, which allows
+ * the nearly empty arenas to be completely freed. In
+ * a few un-scientific tests, it seems like this
+ * approach allowed a lot more memory to be freed.
+ */
+ if (ao->nextarena == NULL ||
+ nf <= ao->nextarena->nfreepools) {
+ /* Case 4. Nothing to do. */
+ UNLOCK();
+ return;
+ }
+ /* Case 3: We have to move the arena towards the end
+ * of the list, because it has more free pools than
+ * the arena to its right.
+ * First unlink ao from usable_arenas.
+ */
+ if (ao->prevarena != NULL) {
+ /* ao isn't at the head of the list */
+ assert(ao->prevarena->nextarena == ao);
+ ao->prevarena->nextarena = ao->nextarena;
+ }
+ else {
+ /* ao is at the head of the list */
+ assert(usable_arenas == ao);
+ usable_arenas = ao->nextarena;
+ }
+ ao->nextarena->prevarena = ao->prevarena;
+
+ /* Locate the new insertion point by iterating over
+ * the list, using our nextarena pointer.
+ */
+ while (ao->nextarena != NULL &&
+ nf > ao->nextarena->nfreepools) {
+ ao->prevarena = ao->nextarena;
+ ao->nextarena = ao->nextarena->nextarena;
+ }
+
+ /* Insert ao at this point. */
+ assert(ao->nextarena == NULL ||
+ ao->prevarena == ao->nextarena->prevarena);
+ assert(ao->prevarena->nextarena == ao->nextarena);
+
+ ao->prevarena->nextarena = ao;
+ if (ao->nextarena != NULL)
+ ao->nextarena->prevarena = ao;
+
+ /* Verify that the swaps worked. */
+ assert(ao->nextarena == NULL ||
+ nf <= ao->nextarena->nfreepools);
+ assert(ao->prevarena == NULL ||
+ nf > ao->prevarena->nfreepools);
+ assert(ao->nextarena == NULL ||
+ ao->nextarena->prevarena == ao);
+ assert((usable_arenas == ao &&
+ ao->prevarena == NULL) ||
+ ao->prevarena->nextarena == ao);
+
+ UNLOCK();
+ return;
+ }
+ /* Pool was full, so doesn't currently live in any list:
+ * link it to the front of the appropriate usedpools[] list.
+ * This mimics LRU pool usage for new allocations and
+ * targets optimal filling when several pools contain
+ * blocks of the same size class.
+ */
+ --pool->ref.count;
+ assert(pool->ref.count > 0); /* else the pool is empty */
+ size = pool->szidx;
+ next = usedpools[size + size];
+ prev = next->prevpool;
+ /* insert pool before next: prev <-> pool <-> next */
+ pool->nextpool = next;
+ pool->prevpool = prev;
+ next->prevpool = pool;
+ prev->nextpool = pool;
+ UNLOCK();
+ return;
+ }
+
+#ifdef WITH_VALGRIND
+redirect:
+#endif
+ /* We didn't allocate this address. */
+ free(p);
+}
+
+/* realloc. If p is NULL, this acts like malloc(nbytes). Else if nbytes==0,
+ * then as the Python docs promise, we do not treat this like free(p), and
+ * return a non-NULL result.
+ */
+
+#undef PyObject_Realloc
+ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
+void *
+PyObject_Realloc(void *p, size_t nbytes)
+{
+ void *bp;
+ poolp pool;
+ size_t size;
+#ifndef Py_USING_MEMORY_DEBUGGER
+ uint arenaindex_temp;
+#endif
+
+ if (p == NULL)
+ return PyObject_Malloc(nbytes);
+
+ /*
+ * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes.
+ * Most python internals blindly use a signed Py_ssize_t to track
+ * things without checking for overflows or negatives.
+ * As size_t is unsigned, checking for nbytes < 0 is not required.
+ */
+ if (nbytes > PY_SSIZE_T_MAX)
+ return NULL;
+
+#ifdef WITH_VALGRIND
+ /* Treat running_on_valgrind == -1 the same as 0 */
+ if (UNLIKELY(running_on_valgrind > 0))
+ goto redirect;
+#endif
+
+ pool = POOL_ADDR(p);
+ if (Py_ADDRESS_IN_RANGE(p, pool)) {
+ /* We're in charge of this block */
+ size = INDEX2SIZE(pool->szidx);
+ if (nbytes <= size) {
+ /* The block is staying the same or shrinking. If
+ * it's shrinking, there's a tradeoff: it costs
+ * cycles to copy the block to a smaller size class,
+ * but it wastes memory not to copy it. The
+ * compromise here is to copy on shrink only if at
+ * least 25% of size can be shaved off.
+ */
+ if (4 * nbytes > 3 * size) {
+ /* It's the same,
+ * or shrinking and new/old > 3/4.
+ */
+ return p;
+ }
+ size = nbytes;
+ }
+ bp = PyObject_Malloc(nbytes);
+ if (bp != NULL) {
+ memcpy(bp, p, size);
+ PyObject_Free(p);
+ }
+ return bp;
+ }
+#ifdef WITH_VALGRIND
+ redirect:
+#endif
+ /* We're not managing this block. If nbytes <=
+ * SMALL_REQUEST_THRESHOLD, it's tempting to try to take over this
+ * block. However, if we do, we need to copy the valid data from
+ * the C-managed block to one of our blocks, and there's no portable
+ * way to know how much of the memory space starting at p is valid.
+ * As bug 1185883 pointed out the hard way, it's possible that the
+ * C-managed block is "at the end" of allocated VM space, so that
+ * a memory fault can occur if we try to copy nbytes bytes starting
+ * at p. Instead we punt: let C continue to manage this block.
+ */
+ if (nbytes)
+ return realloc(p, nbytes);
+ /* C doesn't define the result of realloc(p, 0) (it may or may not
+ * return NULL then), but Python's docs promise that nbytes==0 never
+ * returns NULL. We don't pass 0 to realloc(), to avoid that endcase
+ * to begin with. Even then, we can't be sure that realloc() won't
+ * return NULL.
+ */
+ bp = realloc(p, 1);
+ return bp ? bp : p;
+}
+
+#else /* ! WITH_PYMALLOC */
+
+/*==========================================================================*/
+/* pymalloc not enabled: Redirect the entry points to malloc. These will
+ * only be used by extensions that are compiled with pymalloc enabled. */
+
+void *
+PyObject_Malloc(size_t n)
+{
+ return PyMem_MALLOC(n);
+}
+
+void *
+PyObject_Realloc(void *p, size_t n)
+{
+ return PyMem_REALLOC(p, n);
+}
+
+void
+PyObject_Free(void *p)
+{
+ PyMem_FREE(p);
+}
+#endif /* WITH_PYMALLOC */
+
+#ifdef PYMALLOC_DEBUG
+/*==========================================================================*/
+/* A x-platform debugging allocator. This doesn't manage memory directly,
+ * it wraps a real allocator, adding extra debugging info to the memory blocks.
+ */
+
+/* Special bytes broadcast into debug memory blocks at appropriate times.
+ * Strings of these are unlikely to be valid addresses, floats, ints or
+ * 7-bit ASCII.
+ */
+#undef CLEANBYTE
+#undef DEADBYTE
+#undef FORBIDDENBYTE
+#define CLEANBYTE 0xCB /* clean (newly allocated) memory */
+#define DEADBYTE 0xDB /* dead (newly freed) memory */
+#define FORBIDDENBYTE 0xFB /* untouchable bytes at each end of a block */
+
+/* We tag each block with an API ID in order to tag API violations */
+#define _PYMALLOC_MEM_ID 'm' /* the PyMem_Malloc() API */
+#define _PYMALLOC_OBJ_ID 'o' /* The PyObject_Malloc() API */
+
+static size_t serialno = 0; /* incremented on each debug {m,re}alloc */
+
+/* serialno is always incremented via calling this routine. The point is
+ * to supply a single place to set a breakpoint.
+ */
+static void
+bumpserialno(void)
+{
+ ++serialno;
+}
+
+#define SST SIZEOF_SIZE_T
+
+/* Read sizeof(size_t) bytes at p as a big-endian size_t. */
+static size_t
+read_size_t(const void *p)
+{
+ const uchar *q = (const uchar *)p;
+ size_t result = *q++;
+ int i;
+
+ for (i = SST; --i > 0; ++q)
+ result = (result << 8) | *q;
+ return result;
+}
+
+/* Write n as a big-endian size_t, MSB at address p, LSB at
+ * p + sizeof(size_t) - 1.
+ */
+static void
+write_size_t(void *p, size_t n)
+{
+ uchar *q = (uchar *)p + SST - 1;
+ int i;
+
+ for (i = SST; --i >= 0; --q) {
+ *q = (uchar)(n & 0xff);
+ n >>= 8;
+ }
+}
+
+#ifdef Py_DEBUG
+/* Is target in the list? The list is traversed via the nextpool pointers.
+ * The list may be NULL-terminated, or circular. Return 1 if target is in
+ * list, else 0.
+ */
+static int
+pool_is_in_list(const poolp target, poolp list)
+{
+ poolp origlist = list;
+ assert(target != NULL);
+ if (list == NULL)
+ return 0;
+ do {
+ if (target == list)
+ return 1;
+ list = list->nextpool;
+ } while (list != NULL && list != origlist);
+ return 0;
+}
+
+#else
+#define pool_is_in_list(X, Y) 1
+
+#endif /* Py_DEBUG */
+
+/* Let S = sizeof(size_t). The debug malloc asks for 4*S extra bytes and
+ fills them with useful stuff, here calling the underlying malloc's result p:
+
+p[0: S]
+ Number of bytes originally asked for. This is a size_t, big-endian (easier
+ to read in a memory dump).
+p[S: 2*S]
+ Copies of FORBIDDENBYTE. Used to catch under- writes and reads.
+p[2*S: 2*S+n]
+ The requested memory, filled with copies of CLEANBYTE.
+ Used to catch reference to uninitialized memory.
+ &p[2*S] is returned. Note that this is 8-byte aligned if pymalloc
+ handled the request itself.
+p[2*S+n: 2*S+n+S]
+ Copies of FORBIDDENBYTE. Used to catch over- writes and reads.
+p[2*S+n+S: 2*S+n+2*S]
+ A serial number, incremented by 1 on each call to _PyObject_DebugMalloc
+ and _PyObject_DebugRealloc.
+ This is a big-endian size_t.
+ If "bad memory" is detected later, the serial number gives an
+ excellent way to set a breakpoint on the next run, to capture the
+ instant at which this block was passed out.
+*/
+
+/* debug replacements for the PyMem_* memory API */
+void *
+_PyMem_DebugMalloc(size_t nbytes)
+{
+ return _PyObject_DebugMallocApi(_PYMALLOC_MEM_ID, nbytes);
+}
+void *
+_PyMem_DebugRealloc(void *p, size_t nbytes)
+{
+ return _PyObject_DebugReallocApi(_PYMALLOC_MEM_ID, p, nbytes);
+}
+void
+_PyMem_DebugFree(void *p)
+{
+ _PyObject_DebugFreeApi(_PYMALLOC_MEM_ID, p);
+}
+
+/* debug replacements for the PyObject_* memory API */
+void *
+_PyObject_DebugMalloc(size_t nbytes)
+{
+ return _PyObject_DebugMallocApi(_PYMALLOC_OBJ_ID, nbytes);
+}
+void *
+_PyObject_DebugRealloc(void *p, size_t nbytes)
+{
+ return _PyObject_DebugReallocApi(_PYMALLOC_OBJ_ID, p, nbytes);
+}
+void
+_PyObject_DebugFree(void *p)
+{
+ _PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p);
+}
+void
+_PyObject_DebugCheckAddress(const void *p)
+{
+ _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p);
+}
+
+
+/* generic debug memory api, with an "id" to identify the API in use */
+void *
+_PyObject_DebugMallocApi(char id, size_t nbytes)
+{
+ uchar *p; /* base address of malloc'ed block */
+ uchar *tail; /* p + 2*SST + nbytes == pointer to tail pad bytes */
+ size_t total; /* nbytes + 4*SST */
+
+ bumpserialno();
+ total = nbytes + 4*SST;
+ if (total < nbytes)
+ /* overflow: can't represent total as a size_t */
+ return NULL;
+
+ p = (uchar *)PyObject_Malloc(total);
+ if (p == NULL)
+ return NULL;
+
+ /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */
+ write_size_t(p, nbytes);
+ p[SST] = (uchar)id;
+ memset(p + SST + 1 , FORBIDDENBYTE, SST-1);
+
+ if (nbytes > 0)
+ memset(p + 2*SST, CLEANBYTE, nbytes);
+
+ /* at tail, write pad (SST bytes) and serialno (SST bytes) */
+ tail = p + 2*SST + nbytes;
+ memset(tail, FORBIDDENBYTE, SST);
+ write_size_t(tail + SST, serialno);
+
+ return p + 2*SST;
+}
+
+/* The debug free first checks the 2*SST bytes on each end for sanity (in
+ particular, that the FORBIDDENBYTEs with the api ID are still intact).
+ Then fills the original bytes with DEADBYTE.
+ Then calls the underlying free.
+*/
+void
+_PyObject_DebugFreeApi(char api, void *p)
+{
+ uchar *q = (uchar *)p - 2*SST; /* address returned from malloc */
+ size_t nbytes;
+
+ if (p == NULL)
+ return;
+ _PyObject_DebugCheckAddressApi(api, p);
+ nbytes = read_size_t(q);
+ nbytes += 4*SST;
+ if (nbytes > 0)
+ memset(q, DEADBYTE, nbytes);
+ PyObject_Free(q);
+}
+
+void *
+_PyObject_DebugReallocApi(char api, void *p, size_t nbytes)
+{
+ uchar *q = (uchar *)p;
+ uchar *tail;
+ size_t total; /* nbytes + 4*SST */
+ size_t original_nbytes;
+ int i;
+
+ if (p == NULL)
+ return _PyObject_DebugMallocApi(api, nbytes);
+
+ _PyObject_DebugCheckAddressApi(api, p);
+ bumpserialno();
+ original_nbytes = read_size_t(q - 2*SST);
+ total = nbytes + 4*SST;
+ if (total < nbytes)
+ /* overflow: can't represent total as a size_t */
+ return NULL;
+
+ if (nbytes < original_nbytes) {
+ /* shrinking: mark old extra memory dead */
+ memset(q + nbytes, DEADBYTE, original_nbytes - nbytes + 2*SST);
+ }
+
+ /* Resize and add decorations. We may get a new pointer here, in which
+ * case we didn't get the chance to mark the old memory with DEADBYTE,
+ * but we live with that.
+ */
+ q = (uchar *)PyObject_Realloc(q - 2*SST, total);
+ if (q == NULL)
+ return NULL;
+
+ write_size_t(q, nbytes);
+ assert(q[SST] == (uchar)api);
+ for (i = 1; i < SST; ++i)
+ assert(q[SST + i] == FORBIDDENBYTE);
+ q += 2*SST;
+ tail = q + nbytes;
+ memset(tail, FORBIDDENBYTE, SST);
+ write_size_t(tail + SST, serialno);
+
+ if (nbytes > original_nbytes) {
+ /* growing: mark new extra memory clean */
+ memset(q + original_nbytes, CLEANBYTE,
+ nbytes - original_nbytes);
+ }
+
+ return q;
+}
+
+/* Check the forbidden bytes on both ends of the memory allocated for p.
+ * If anything is wrong, print info to stderr via _PyObject_DebugDumpAddress,
+ * and call Py_FatalError to kill the program.
+ * The API id, is also checked.
+ */
+ void
+_PyObject_DebugCheckAddressApi(char api, const void *p)
+{
+ const uchar *q = (const uchar *)p;
+ char msgbuf[64];
+ char *msg;
+ size_t nbytes;
+ const uchar *tail;
+ int i;
+ char id;
+
+ if (p == NULL) {
+ msg = "didn't expect a NULL pointer";
+ goto error;
+ }
+
+ /* Check the API id */
+ id = (char)q[-SST];
+ if (id != api) {
+ msg = msgbuf;
+ snprintf(msg, sizeof(msgbuf), "bad ID: Allocated using API '%c', verified using API '%c'", id, api);
+ msgbuf[sizeof(msgbuf)-1] = 0;
+ goto error;
+ }
+
+ /* Check the stuff at the start of p first: if there's underwrite
+ * corruption, the number-of-bytes field may be nuts, and checking
+ * the tail could lead to a segfault then.
+ */
+ for (i = SST-1; i >= 1; --i) {
+ if (*(q-i) != FORBIDDENBYTE) {
+ msg = "bad leading pad byte";
+ goto error;
+ }
+ }
+
+ nbytes = read_size_t(q - 2*SST);
+ tail = q + nbytes;
+ for (i = 0; i < SST; ++i) {
+ if (tail[i] != FORBIDDENBYTE) {
+ msg = "bad trailing pad byte";
+ goto error;
+ }
+ }
+
+ return;
+
+error:
+ _PyObject_DebugDumpAddress(p);
+ Py_FatalError(msg);
+}
+
+/* Display info to stderr about the memory block at p. */
+void
+_PyObject_DebugDumpAddress(const void *p)
+{
+ const uchar *q = (const uchar *)p;
+ const uchar *tail;
+ size_t nbytes, serial;
+ int i;
+ int ok;
+ char id;
+
+ fprintf(stderr, "Debug memory block at address p=%p:", p);
+ if (p == NULL) {
+ fprintf(stderr, "\n");
+ return;
+ }
+ id = (char)q[-SST];
+ fprintf(stderr, " API '%c'\n", id);
+
+ nbytes = read_size_t(q - 2*SST);
+ fprintf(stderr, " %" PY_FORMAT_SIZE_T "u bytes originally "
+ "requested\n", nbytes);
+
+ /* In case this is nuts, check the leading pad bytes first. */
+ fprintf(stderr, " The %d pad bytes at p-%d are ", SST-1, SST-1);
+ ok = 1;
+ for (i = 1; i <= SST-1; ++i) {
+ if (*(q-i) != FORBIDDENBYTE) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok)
+ fputs("FORBIDDENBYTE, as expected.\n", stderr);
+ else {
+ fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+ FORBIDDENBYTE);
+ for (i = SST-1; i >= 1; --i) {
+ const uchar byte = *(q-i);
+ fprintf(stderr, " at p-%d: 0x%02x", i, byte);
+ if (byte != FORBIDDENBYTE)
+ fputs(" *** OUCH", stderr);
+ fputc('\n', stderr);
+ }
+
+ fputs(" Because memory is corrupted at the start, the "
+ "count of bytes requested\n"
+ " may be bogus, and checking the trailing pad "
+ "bytes may segfault.\n", stderr);
+ }
+
+ tail = q + nbytes;
+ fprintf(stderr, " The %d pad bytes at tail=%p are ", SST, tail);
+ ok = 1;
+ for (i = 0; i < SST; ++i) {
+ if (tail[i] != FORBIDDENBYTE) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok)
+ fputs("FORBIDDENBYTE, as expected.\n", stderr);
+ else {
+ fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n",
+ FORBIDDENBYTE);
+ for (i = 0; i < SST; ++i) {
+ const uchar byte = tail[i];
+ fprintf(stderr, " at tail+%d: 0x%02x",
+ i, byte);
+ if (byte != FORBIDDENBYTE)
+ fputs(" *** OUCH", stderr);
+ fputc('\n', stderr);
+ }
+ }
+
+ serial = read_size_t(tail + SST);
+ fprintf(stderr, " The block was made by call #%" PY_FORMAT_SIZE_T
+ "u to debug malloc/realloc.\n", serial);
+
+ if (nbytes > 0) {
+ i = 0;
+ fputs(" Data at p:", stderr);
+ /* print up to 8 bytes at the start */
+ while (q < tail && i < 8) {
+ fprintf(stderr, " %02x", *q);
+ ++i;
+ ++q;
+ }
+ /* and up to 8 at the end */
+ if (q < tail) {
+ if (tail - q > 8) {
+ fputs(" ...", stderr);
+ q = tail - 8;
+ }
+ while (q < tail) {
+ fprintf(stderr, " %02x", *q);
+ ++q;
+ }
+ }
+ fputc('\n', stderr);
+ }
+}
+
+static size_t
+printone(const char* msg, size_t value)
+{
+ int i, k;
+ char buf[100];
+ size_t origvalue = value;
+
+ fputs(msg, stderr);
+ for (i = (int)strlen(msg); i < 35; ++i)
+ fputc(' ', stderr);
+ fputc('=', stderr);
+
+ /* Write the value with commas. */
+ i = 22;
+ buf[i--] = '\0';
+ buf[i--] = '\n';
+ k = 3;
+ do {
+ size_t nextvalue = value / 10;
+ unsigned int digit = (unsigned int)(value - nextvalue * 10);
+ value = nextvalue;
+ buf[i--] = (char)(digit + '0');
+ --k;
+ if (k == 0 && value && i >= 0) {
+ k = 3;
+ buf[i--] = ',';
+ }
+ } while (value && i >= 0);
+
+ while (i >= 0)
+ buf[i--] = ' ';
+ fputs(buf, stderr);
+
+ return origvalue;
+}
+
+/* Print summary info to stderr about the state of pymalloc's structures.
+ * In Py_DEBUG mode, also perform some expensive internal consistency
+ * checks.
+ */
+void
+_PyObject_DebugMallocStats(void)
+{
+ uint i;
+ const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
+ /* # of pools, allocated blocks, and free blocks per class index */
+ size_t numpools[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+ size_t numblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+ size_t numfreeblocks[SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT];
+ /* total # of allocated bytes in used and full pools */
+ size_t allocated_bytes = 0;
+ /* total # of available bytes in used pools */
+ size_t available_bytes = 0;
+ /* # of free pools + pools not yet carved out of current arena */
+ uint numfreepools = 0;
+ /* # of bytes for arena alignment padding */
+ size_t arena_alignment = 0;
+ /* # of bytes in used and full pools used for pool_headers */
+ size_t pool_header_bytes = 0;
+ /* # of bytes in used and full pools wasted due to quantization,
+ * i.e. the necessarily leftover space at the ends of used and
+ * full pools.
+ */
+ size_t quantization = 0;
+ /* # of arenas actually allocated. */
+ size_t narenas = 0;
+ /* running total -- should equal narenas * ARENA_SIZE */
+ size_t total;
+ char buf[128];
+
+ fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
+ SMALL_REQUEST_THRESHOLD, numclasses);
+
+ for (i = 0; i < numclasses; ++i)
+ numpools[i] = numblocks[i] = numfreeblocks[i] = 0;
+
+ /* Because full pools aren't linked to from anything, it's easiest
+ * to march over all the arenas. If we're lucky, most of the memory
+ * will be living in full pools -- would be a shame to miss them.
+ */
+ for (i = 0; i < maxarenas; ++i) {
+ uint j;
+ uptr base = arenas[i].address;
+
+ /* Skip arenas which are not allocated. */
+ if (arenas[i].address == (uptr)NULL)
+ continue;
+ narenas += 1;
+
+ numfreepools += arenas[i].nfreepools;
+
+ /* round up to pool alignment */
+ if (base & (uptr)POOL_SIZE_MASK) {
+ arena_alignment += POOL_SIZE;
+ base &= ~(uptr)POOL_SIZE_MASK;
+ base += POOL_SIZE;
+ }
+
+ /* visit every pool in the arena */
+ assert(base <= (uptr) arenas[i].pool_address);
+ for (j = 0;
+ base < (uptr) arenas[i].pool_address;
+ ++j, base += POOL_SIZE) {
+ poolp p = (poolp)base;
+ const uint sz = p->szidx;
+ uint freeblocks;
+
+ if (p->ref.count == 0) {
+ /* currently unused */
+ assert(pool_is_in_list(p, arenas[i].freepools));
+ continue;
+ }
+ ++numpools[sz];
+ numblocks[sz] += p->ref.count;
+ freeblocks = NUMBLOCKS(sz) - p->ref.count;
+ numfreeblocks[sz] += freeblocks;
+#ifdef Py_DEBUG
+ if (freeblocks > 0)
+ assert(pool_is_in_list(p, usedpools[sz + sz]));
+#endif
+ }
+ }
+ assert(narenas == narenas_currently_allocated);
+
+ fputc('\n', stderr);
+ fputs("class size num pools blocks in use avail blocks\n"
+ "----- ---- --------- ------------- ------------\n",
+ stderr);
+
+ for (i = 0; i < numclasses; ++i) {
+ size_t p = numpools[i];
+ size_t b = numblocks[i];
+ size_t f = numfreeblocks[i];
+ uint size = INDEX2SIZE(i);
+ if (p == 0) {
+ assert(b == 0 && f == 0);
+ continue;
+ }
+ fprintf(stderr, "%5u %6u "
+ "%11" PY_FORMAT_SIZE_T "u "
+ "%15" PY_FORMAT_SIZE_T "u "
+ "%13" PY_FORMAT_SIZE_T "u\n",
+ i, size, p, b, f);
+ allocated_bytes += b * size;
+ available_bytes += f * size;
+ pool_header_bytes += p * POOL_OVERHEAD;
+ quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
+ }
+ fputc('\n', stderr);
+ (void)printone("# times object malloc called", serialno);
+
+ (void)printone("# arenas allocated total", ntimes_arena_allocated);
+ (void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
+ (void)printone("# arenas highwater mark", narenas_highwater);
+ (void)printone("# arenas allocated current", narenas);
+
+ PyOS_snprintf(buf, sizeof(buf),
+ "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena",
+ narenas, ARENA_SIZE);
+ (void)printone(buf, narenas * ARENA_SIZE);
+
+ fputc('\n', stderr);
+
+ total = printone("# bytes in allocated blocks", allocated_bytes);
+ total += printone("# bytes in available blocks", available_bytes);
+
+ PyOS_snprintf(buf, sizeof(buf),
+ "%u unused pools * %d bytes", numfreepools, POOL_SIZE);
+ total += printone(buf, (size_t)numfreepools * POOL_SIZE);
+
+ total += printone("# bytes lost to pool headers", pool_header_bytes);
+ total += printone("# bytes lost to quantization", quantization);
+ total += printone("# bytes lost to arena alignment", arena_alignment);
+ (void)printone("Total", total);
+}
+
+#endif /* PYMALLOC_DEBUG */
+
+#ifdef Py_USING_MEMORY_DEBUGGER
+/* Make this function last so gcc won't inline it since the definition is
+ * after the reference.
+ */
+int
+Py_ADDRESS_IN_RANGE(void *P, poolp pool)
+{
+ uint arenaindex_temp = pool->arenaindex;
+
+ return arenaindex_temp < maxarenas &&
+ (uptr)P - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE &&
+ arenas[arenaindex_temp].address != 0;
+}
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/rangeobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/rangeobject.c
new file mode 100644
index 0000000000..ae8cb67adb
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/rangeobject.c
@@ -0,0 +1,347 @@
+/* Range object implementation */
+
+#include "Python.h"
+
+typedef struct {
+ PyObject_HEAD
+ long start;
+ long step;
+ long len;
+} rangeobject;
+
+/* Return number of items in range (lo, hi, step). step != 0
+ * required. The result always fits in an unsigned long.
+ */
+static unsigned long
+get_len_of_range(long lo, long hi, long step)
+{
+ /* -------------------------------------------------------------
+ If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty.
+ Else for step > 0, if n values are in the range, the last one is
+ lo + (n-1)*step, which must be <= hi-1. Rearranging,
+ n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
+ the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
+ the RHS is non-negative and so truncation is the same as the
+ floor. Letting M be the largest positive long, the worst case
+ for the RHS numerator is hi=M, lo=-M-1, and then
+ hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
+ precision to compute the RHS exactly. The analysis for step < 0
+ is similar.
+ ---------------------------------------------------------------*/
+ assert(step != 0);
+ if (step > 0 && lo < hi)
+ return 1UL + (hi - 1UL - lo) / step;
+ else if (step < 0 && lo > hi)
+ return 1UL + (lo - 1UL - hi) / (0UL - step);
+ else
+ return 0UL;
+}
+
+/* Return a stop value suitable for reconstructing the xrange from
+ * a (start, stop, step) triple. Used in range_repr and range_reduce.
+ * Computes start + len * step, clipped to the range [LONG_MIN, LONG_MAX].
+ */
+static long
+get_stop_for_range(rangeobject *r)
+{
+ long last;
+
+ if (r->len == 0)
+ return r->start;
+
+ /* The tricky bit is avoiding overflow. We first compute the last entry in
+ the xrange, start + (len - 1) * step, which is guaranteed to lie within
+ the range of a long, and then add step to it. See the range_reverse
+ comments for an explanation of the casts below.
+ */
+ last = (long)(r->start + (unsigned long)(r->len - 1) * r->step);
+ if (r->step > 0)
+ return last > LONG_MAX - r->step ? LONG_MAX : last + r->step;
+ else
+ return last < LONG_MIN - r->step ? LONG_MIN : last + r->step;
+}
+
+static PyObject *
+range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
+{
+ rangeobject *obj;
+ long ilow = 0, ihigh = 0, istep = 1;
+ unsigned long n;
+
+ if (!_PyArg_NoKeywords("xrange()", kw))
+ return NULL;
+
+ if (PyTuple_Size(args) <= 1) {
+ if (!PyArg_ParseTuple(args,
+ "l;xrange() requires 1-3 int arguments",
+ &ihigh))
+ return NULL;
+ }
+ else {
+ if (!PyArg_ParseTuple(args,
+ "ll|l;xrange() requires 1-3 int arguments",
+ &ilow, &ihigh, &istep))
+ return NULL;
+ }
+ if (istep == 0) {
+ PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero");
+ return NULL;
+ }
+ n = get_len_of_range(ilow, ihigh, istep);
+ if (n > (unsigned long)LONG_MAX || (long)n > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "xrange() result has too many items");
+ return NULL;
+ }
+
+ obj = PyObject_New(rangeobject, &PyRange_Type);
+ if (obj == NULL)
+ return NULL;
+ obj->start = ilow;
+ obj->len = (long)n;
+ obj->step = istep;
+ return (PyObject *) obj;
+}
+
+PyDoc_STRVAR(range_doc,
+"xrange(stop) -> xrange object\n\
+xrange(start, stop[, step]) -> xrange object\n\
+\n\
+Like range(), but instead of returning a list, returns an object that\n\
+generates the numbers in the range on demand. For looping, this is \n\
+slightly faster than range() and more memory efficient.");
+
+static PyObject *
+range_item(rangeobject *r, Py_ssize_t i)
+{
+ if (i < 0 || i >= r->len) {
+ PyErr_SetString(PyExc_IndexError,
+ "xrange object index out of range");
+ return NULL;
+ }
+ /* do calculation entirely using unsigned longs, to avoid
+ undefined behaviour due to signed overflow. */
+ return PyInt_FromLong((long)(r->start + (unsigned long)i * r->step));
+}
+
+static Py_ssize_t
+range_length(rangeobject *r)
+{
+ return (Py_ssize_t)(r->len);
+}
+
+static PyObject *
+range_repr(rangeobject *r)
+{
+ PyObject *rtn;
+
+ if (r->start == 0 && r->step == 1)
+ rtn = PyString_FromFormat("xrange(%ld)",
+ get_stop_for_range(r));
+
+ else if (r->step == 1)
+ rtn = PyString_FromFormat("xrange(%ld, %ld)",
+ r->start,
+ get_stop_for_range(r));
+
+ else
+ rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)",
+ r->start,
+ get_stop_for_range(r),
+ r->step);
+ return rtn;
+}
+
+/* Pickling support */
+static PyObject *
+range_reduce(rangeobject *r, PyObject *args)
+{
+ return Py_BuildValue("(O(lll))", Py_TYPE(r),
+ r->start,
+ get_stop_for_range(r),
+ r->step);
+}
+
+static PySequenceMethods range_as_sequence = {
+ (lenfunc)range_length, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)range_item, /* sq_item */
+ 0, /* sq_slice */
+};
+
+static PyObject * range_iter(PyObject *seq);
+static PyObject * range_reverse(PyObject *seq);
+
+PyDoc_STRVAR(reverse_doc,
+"Returns a reverse iterator.");
+
+static PyMethodDef range_methods[] = {
+ {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+ {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyRange_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* Number of items for varobject */
+ "xrange", /* Name of this type */
+ sizeof(rangeobject), /* Basic object size */
+ 0, /* Item size for varobject */
+ (destructor)PyObject_Del, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)range_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &range_as_sequence, /* 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 */
+ range_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ range_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ range_methods, /* tp_methods */
+ 0, /* 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 */
+ range_new, /* tp_new */
+};
+
+/*********************** Xrange Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ long index;
+ long start;
+ long step;
+ long len;
+} rangeiterobject;
+
+static PyObject *
+rangeiter_next(rangeiterobject *r)
+{
+ if (r->index < r->len)
+ return PyInt_FromLong(r->start + (r->index++) * r->step);
+ return NULL;
+}
+
+static PyObject *
+rangeiter_len(rangeiterobject *r)
+{
+ return PyInt_FromLong(r->len - r->index);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef rangeiter_methods[] = {
+ {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject Pyrangeiter_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "rangeiterator", /* tp_name */
+ sizeof(rangeiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)PyObject_Del, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)rangeiter_next, /* tp_iternext */
+ rangeiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+range_iter(PyObject *seq)
+{
+ rangeiterobject *it;
+
+ if (!PyRange_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+ if (it == NULL)
+ return NULL;
+ it->index = 0;
+ it->start = ((rangeobject *)seq)->start;
+ it->step = ((rangeobject *)seq)->step;
+ it->len = ((rangeobject *)seq)->len;
+ return (PyObject *)it;
+}
+
+static PyObject *
+range_reverse(PyObject *seq)
+{
+ rangeiterobject *it;
+ long start, step, len;
+
+ if (!PyRange_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_New(rangeiterobject, &Pyrangeiter_Type);
+ if (it == NULL)
+ return NULL;
+
+ start = ((rangeobject *)seq)->start;
+ step = ((rangeobject *)seq)->step;
+ len = ((rangeobject *)seq)->len;
+
+ it->index = 0;
+ it->len = len;
+ /* the casts below guard against signed overflow by turning it
+ into unsigned overflow instead. The correctness of this
+ code still depends on conversion from unsigned long to long
+ wrapping modulo ULONG_MAX+1, which isn't guaranteed (see
+ C99 6.3.1.3p3) but seems to hold in practice for all
+ platforms we're likely to meet.
+
+ If step == LONG_MIN then we still end up with LONG_MIN
+ after negation; but this works out, since we've still got
+ the correct value modulo ULONG_MAX+1, and the range_item
+ calculation is also done modulo ULONG_MAX+1.
+ */
+ it->start = (long)(start + (unsigned long)(len-1) * step);
+ it->step = (long)(0UL-step);
+
+ return (PyObject *)it;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/setobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/setobject.c
new file mode 100644
index 0000000000..6428530817
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/setobject.c
@@ -0,0 +1,2514 @@
+
+/* set object implementation
+ Written and maintained by Raymond D. Hettinger <python@rcn.com>
+ Derived from Lib/sets.py and Objects/dictobject.c.
+
+ Copyright (c) 2003-2007 Python Software Foundation.
+ All rights reserved.
+*/
+
+#include "Python.h"
+#include "structmember.h"
+
+/* Set a key error with the specified argument, wrapping it in a
+ * tuple automatically so that tuple keys are not unpacked as the
+ * exception arguments. */
+static void
+set_key_error(PyObject *arg)
+{
+ PyObject *tup;
+ tup = PyTuple_Pack(1, arg);
+ if (!tup)
+ return; /* caller will expect error to be set anyway */
+ PyErr_SetObject(PyExc_KeyError, tup);
+ Py_DECREF(tup);
+}
+
+/* This must be >= 1. */
+#define PERTURB_SHIFT 5
+
+/* Object used as dummy key to fill deleted entries */
+static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */
+
+#ifdef Py_REF_DEBUG
+PyObject *
+_PySet_Dummy(void)
+{
+ return dummy;
+}
+#endif
+
+#define INIT_NONZERO_SET_SLOTS(so) do { \
+ (so)->table = (so)->smalltable; \
+ (so)->mask = PySet_MINSIZE - 1; \
+ (so)->hash = -1; \
+ } while(0)
+
+#define EMPTY_TO_MINSIZE(so) do { \
+ memset((so)->smalltable, 0, sizeof((so)->smalltable)); \
+ (so)->used = (so)->fill = 0; \
+ INIT_NONZERO_SET_SLOTS(so); \
+ } while(0)
+
+/* Reuse scheme to save calls to malloc, free, and memset */
+#ifndef PySet_MAXFREELIST
+#define PySet_MAXFREELIST 80
+#endif
+static PySetObject *free_list[PySet_MAXFREELIST];
+static int numfree = 0;
+
+/*
+The basic lookup function used by all operations.
+This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
+Open addressing is preferred over chaining since the link overhead for
+chaining would be substantial (100% with typical malloc overhead).
+
+The initial probe index is computed as hash mod the table size. Subsequent
+probe indices are computed as explained in Objects/dictobject.c.
+
+All arithmetic on hash should ignore overflow.
+
+Unlike the dictionary implementation, the lookkey functions can return
+NULL if the rich comparison returns an error.
+*/
+
+static setentry *
+set_lookkey(PySetObject *so, PyObject *key, register long hash)
+{
+ register Py_ssize_t i;
+ register size_t perturb;
+ register setentry *freeslot;
+ register size_t mask = so->mask;
+ setentry *table = so->table;
+ register setentry *entry;
+ register int cmp;
+ PyObject *startkey;
+
+ i = hash & mask;
+ entry = &table[i];
+ if (entry->key == NULL || entry->key == key)
+ return entry;
+
+ if (entry->key == dummy)
+ freeslot = entry;
+ else {
+ if (entry->hash == hash) {
+ startkey = entry->key;
+ Py_INCREF(startkey);
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ Py_DECREF(startkey);
+ if (cmp < 0)
+ return NULL;
+ if (table == so->table && entry->key == startkey) {
+ if (cmp > 0)
+ return entry;
+ }
+ else {
+ /* The compare did major nasty stuff to the
+ * set: start over.
+ */
+ return set_lookkey(so, key, hash);
+ }
+ }
+ freeslot = NULL;
+ }
+
+ /* In the loop, key == dummy is by far (factor of 100s) the
+ least likely outcome, so test for that last. */
+ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ entry = &table[i & mask];
+ if (entry->key == NULL) {
+ if (freeslot != NULL)
+ entry = freeslot;
+ break;
+ }
+ if (entry->key == key)
+ break;
+ if (entry->hash == hash && entry->key != dummy) {
+ startkey = entry->key;
+ Py_INCREF(startkey);
+ cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+ Py_DECREF(startkey);
+ if (cmp < 0)
+ return NULL;
+ if (table == so->table && entry->key == startkey) {
+ if (cmp > 0)
+ break;
+ }
+ else {
+ /* The compare did major nasty stuff to the
+ * set: start over.
+ */
+ return set_lookkey(so, key, hash);
+ }
+ }
+ else if (entry->key == dummy && freeslot == NULL)
+ freeslot = entry;
+ }
+ return entry;
+}
+
+/*
+ * Hacked up version of set_lookkey which can assume keys are always strings;
+ * This means we can always use _PyString_Eq directly and not have to check to
+ * see if the comparison altered the table.
+ */
+static setentry *
+set_lookkey_string(PySetObject *so, PyObject *key, register long hash)
+{
+ register Py_ssize_t i;
+ register size_t perturb;
+ register setentry *freeslot;
+ register size_t mask = so->mask;
+ setentry *table = so->table;
+ register setentry *entry;
+
+ /* Make sure this function doesn't have to handle non-string keys,
+ including subclasses of str; e.g., one reason to subclass
+ strings is to override __eq__, and for speed we don't cater to
+ that here. */
+ if (!PyString_CheckExact(key)) {
+ so->lookup = set_lookkey;
+ return set_lookkey(so, key, hash);
+ }
+ i = hash & mask;
+ entry = &table[i];
+ if (entry->key == NULL || entry->key == key)
+ return entry;
+ if (entry->key == dummy)
+ freeslot = entry;
+ else {
+ if (entry->hash == hash && _PyString_Eq(entry->key, key))
+ return entry;
+ freeslot = NULL;
+ }
+
+ /* In the loop, key == dummy is by far (factor of 100s) the
+ least likely outcome, so test for that last. */
+ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ entry = &table[i & mask];
+ if (entry->key == NULL)
+ return freeslot == NULL ? entry : freeslot;
+ if (entry->key == key
+ || (entry->hash == hash
+ && entry->key != dummy
+ && _PyString_Eq(entry->key, key)))
+ return entry;
+ if (entry->key == dummy && freeslot == NULL)
+ freeslot = entry;
+ }
+ assert(0); /* NOT REACHED */
+ return 0;
+}
+
+/*
+Internal routine to insert a new key into the table.
+Used by the public insert routine.
+Eats a reference to key.
+*/
+static int
+set_insert_key(register PySetObject *so, PyObject *key, long hash)
+{
+ register setentry *entry;
+
+ assert(so->lookup != NULL);
+ entry = so->lookup(so, key, hash);
+ if (entry == NULL)
+ return -1;
+ if (entry->key == NULL) {
+ /* UNUSED */
+ so->fill++;
+ entry->key = key;
+ entry->hash = hash;
+ so->used++;
+ } else if (entry->key == dummy) {
+ /* DUMMY */
+ entry->key = key;
+ entry->hash = hash;
+ so->used++;
+ Py_DECREF(dummy);
+ } else {
+ /* ACTIVE */
+ Py_DECREF(key);
+ }
+ return 0;
+}
+
+/*
+Internal routine used by set_table_resize() to insert an item which is
+known to be absent from the set. This routine also assumes that
+the set contains no deleted entries. Besides the performance benefit,
+using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
+Note that no refcounts are changed by this routine; if needed, the caller
+is responsible for incref'ing `key`.
+*/
+static void
+set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+{
+ register size_t i;
+ register size_t perturb;
+ register size_t mask = (size_t)so->mask;
+ setentry *table = so->table;
+ register setentry *entry;
+
+ i = hash & mask;
+ entry = &table[i];
+ for (perturb = hash; entry->key != NULL; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ entry = &table[i & mask];
+ }
+ so->fill++;
+ entry->key = key;
+ entry->hash = hash;
+ so->used++;
+}
+
+/*
+Restructure the table by allocating a new table and reinserting all
+keys again. When entries have been deleted, the new table may
+actually be smaller than the old one.
+*/
+static int
+set_table_resize(PySetObject *so, Py_ssize_t minused)
+{
+ Py_ssize_t newsize;
+ setentry *oldtable, *newtable, *entry;
+ Py_ssize_t i;
+ int is_oldtable_malloced;
+ setentry small_copy[PySet_MINSIZE];
+
+ assert(minused >= 0);
+
+ /* Find the smallest table size > minused. */
+ for (newsize = PySet_MINSIZE;
+ newsize <= minused && newsize > 0;
+ newsize <<= 1)
+ ;
+ if (newsize <= 0) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ /* Get space for a new table. */
+ oldtable = so->table;
+ assert(oldtable != NULL);
+ is_oldtable_malloced = oldtable != so->smalltable;
+
+ if (newsize == PySet_MINSIZE) {
+ /* A large table is shrinking, or we can't get any smaller. */
+ newtable = so->smalltable;
+ if (newtable == oldtable) {
+ if (so->fill == so->used) {
+ /* No dummies, so no point doing anything. */
+ return 0;
+ }
+ /* We're not going to resize it, but rebuild the
+ table anyway to purge old dummy entries.
+ Subtle: This is *necessary* if fill==size,
+ as set_lookkey needs at least one virgin slot to
+ terminate failing searches. If fill < size, it's
+ merely desirable, as dummies slow searches. */
+ assert(so->fill > so->used);
+ memcpy(small_copy, oldtable, sizeof(small_copy));
+ oldtable = small_copy;
+ }
+ }
+ else {
+ newtable = PyMem_NEW(setentry, newsize);
+ if (newtable == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ }
+
+ /* Make the set empty, using the new table. */
+ assert(newtable != oldtable);
+ so->table = newtable;
+ so->mask = newsize - 1;
+ memset(newtable, 0, sizeof(setentry) * newsize);
+ so->used = 0;
+ i = so->fill;
+ so->fill = 0;
+
+ /* Copy the data over; this is refcount-neutral for active entries;
+ dummy entries aren't copied over, of course */
+ for (entry = oldtable; i > 0; entry++) {
+ if (entry->key == NULL) {
+ /* UNUSED */
+ ;
+ } else if (entry->key == dummy) {
+ /* DUMMY */
+ --i;
+ assert(entry->key == dummy);
+ Py_DECREF(entry->key);
+ } else {
+ /* ACTIVE */
+ --i;
+ set_insert_clean(so, entry->key, entry->hash);
+ }
+ }
+
+ if (is_oldtable_malloced)
+ PyMem_DEL(oldtable);
+ return 0;
+}
+
+/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */
+
+static int
+set_add_entry(register PySetObject *so, setentry *entry)
+{
+ register Py_ssize_t n_used;
+ PyObject *key = entry->key;
+ long hash = entry->hash;
+
+ assert(so->fill <= so->mask); /* at least one empty slot */
+ n_used = so->used;
+ Py_INCREF(key);
+ if (set_insert_key(so, key, hash) == -1) {
+ Py_DECREF(key);
+ return -1;
+ }
+ if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+ return 0;
+ return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static int
+set_add_key(register PySetObject *so, PyObject *key)
+{
+ register long hash;
+ register Py_ssize_t n_used;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ assert(so->fill <= so->mask); /* at least one empty slot */
+ n_used = so->used;
+ Py_INCREF(key);
+ if (set_insert_key(so, key, hash) == -1) {
+ Py_DECREF(key);
+ return -1;
+ }
+ if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
+ return 0;
+ return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+#define DISCARD_NOTFOUND 0
+#define DISCARD_FOUND 1
+
+static int
+set_discard_entry(PySetObject *so, setentry *oldentry)
+{ register setentry *entry;
+ PyObject *old_key;
+
+ entry = (so->lookup)(so, oldentry->key, oldentry->hash);
+ if (entry == NULL)
+ return -1;
+ if (entry->key == NULL || entry->key == dummy)
+ return DISCARD_NOTFOUND;
+ old_key = entry->key;
+ Py_INCREF(dummy);
+ entry->key = dummy;
+ so->used--;
+ Py_DECREF(old_key);
+ return DISCARD_FOUND;
+}
+
+static int
+set_discard_key(PySetObject *so, PyObject *key)
+{
+ register long hash;
+ register setentry *entry;
+ PyObject *old_key;
+
+ assert (PyAnySet_Check(so));
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ entry = (so->lookup)(so, key, hash);
+ if (entry == NULL)
+ return -1;
+ if (entry->key == NULL || entry->key == dummy)
+ return DISCARD_NOTFOUND;
+ old_key = entry->key;
+ Py_INCREF(dummy);
+ entry->key = dummy;
+ so->used--;
+ Py_DECREF(old_key);
+ return DISCARD_FOUND;
+}
+
+static int
+set_clear_internal(PySetObject *so)
+{
+ setentry *entry, *table;
+ int table_is_malloced;
+ Py_ssize_t fill;
+ setentry small_copy[PySet_MINSIZE];
+#ifdef Py_DEBUG
+ Py_ssize_t i, n;
+ assert (PyAnySet_Check(so));
+
+ n = so->mask + 1;
+ i = 0;
+#endif
+
+ table = so->table;
+ assert(table != NULL);
+ table_is_malloced = table != so->smalltable;
+
+ /* This is delicate. During the process of clearing the set,
+ * decrefs can cause the set to mutate. To avoid fatal confusion
+ * (voice of experience), we have to make the set empty before
+ * clearing the slots, and never refer to anything via so->ref while
+ * clearing.
+ */
+ fill = so->fill;
+ if (table_is_malloced)
+ EMPTY_TO_MINSIZE(so);
+
+ else if (fill > 0) {
+ /* It's a small table with something that needs to be cleared.
+ * Afraid the only safe way is to copy the set entries into
+ * another small table first.
+ */
+ memcpy(small_copy, table, sizeof(small_copy));
+ table = small_copy;
+ EMPTY_TO_MINSIZE(so);
+ }
+ /* else it's a small table that's already empty */
+
+ /* Now we can finally clear things. If C had refcounts, we could
+ * assert that the refcount on table is 1 now, i.e. that this function
+ * has unique access to it, so decref side-effects can't alter it.
+ */
+ for (entry = table; fill > 0; ++entry) {
+#ifdef Py_DEBUG
+ assert(i < n);
+ ++i;
+#endif
+ if (entry->key) {
+ --fill;
+ Py_DECREF(entry->key);
+ }
+#ifdef Py_DEBUG
+ else
+ assert(entry->key == NULL);
+#endif
+ }
+
+ if (table_is_malloced)
+ PyMem_DEL(table);
+ return 0;
+}
+
+/*
+ * Iterate over a set table. Use like so:
+ *
+ * Py_ssize_t pos;
+ * setentry *entry;
+ * pos = 0; # important! pos should not otherwise be changed by you
+ * while (set_next(yourset, &pos, &entry)) {
+ * Refer to borrowed reference in entry->key.
+ * }
+ *
+ * CAUTION: In general, it isn't safe to use set_next in a loop that
+ * mutates the table.
+ */
+static int
+set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
+{
+ Py_ssize_t i;
+ Py_ssize_t mask;
+ register setentry *table;
+
+ assert (PyAnySet_Check(so));
+ i = *pos_ptr;
+ assert(i >= 0);
+ table = so->table;
+ mask = so->mask;
+ while (i <= mask && (table[i].key == NULL || table[i].key == dummy))
+ i++;
+ *pos_ptr = i+1;
+ if (i > mask)
+ return 0;
+ assert(table[i].key != NULL);
+ *entry_ptr = &table[i];
+ return 1;
+}
+
+static void
+set_dealloc(PySetObject *so)
+{
+ register setentry *entry;
+ Py_ssize_t fill = so->fill;
+ PyObject_GC_UnTrack(so);
+ Py_TRASHCAN_SAFE_BEGIN(so)
+ if (so->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) so);
+
+ for (entry = so->table; fill > 0; entry++) {
+ if (entry->key) {
+ --fill;
+ Py_DECREF(entry->key);
+ }
+ }
+ if (so->table != so->smalltable)
+ PyMem_DEL(so->table);
+ if (numfree < PySet_MAXFREELIST && PyAnySet_CheckExact(so))
+ free_list[numfree++] = so;
+ else
+ Py_TYPE(so)->tp_free(so);
+ Py_TRASHCAN_SAFE_END(so)
+}
+
+static int
+set_tp_print(PySetObject *so, FILE *fp, int flags)
+{
+ setentry *entry;
+ Py_ssize_t pos=0;
+ char *emit = ""; /* No separator emitted on first pass */
+ char *separator = ", ";
+ int status = Py_ReprEnter((PyObject*)so);
+
+ if (status != 0) {
+ if (status < 0)
+ return status;
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "%s(...)", so->ob_type->tp_name);
+ Py_END_ALLOW_THREADS
+ return 0;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "%s([", so->ob_type->tp_name);
+ Py_END_ALLOW_THREADS
+ while (set_next(so, &pos, &entry)) {
+ Py_BEGIN_ALLOW_THREADS
+ fputs(emit, fp);
+ Py_END_ALLOW_THREADS
+ emit = separator;
+ if (PyObject_Print(entry->key, fp, 0) != 0) {
+ Py_ReprLeave((PyObject*)so);
+ return -1;
+ }
+ }
+ Py_BEGIN_ALLOW_THREADS
+ fputs("])", fp);
+ Py_END_ALLOW_THREADS
+ Py_ReprLeave((PyObject*)so);
+ return 0;
+}
+
+static PyObject *
+set_repr(PySetObject *so)
+{
+ PyObject *keys, *result=NULL, *listrepr;
+ int status = Py_ReprEnter((PyObject*)so);
+
+ if (status != 0) {
+ if (status < 0)
+ return NULL;
+ return PyString_FromFormat("%s(...)", so->ob_type->tp_name);
+ }
+
+ keys = PySequence_List((PyObject *)so);
+ if (keys == NULL)
+ goto done;
+ listrepr = PyObject_Repr(keys);
+ Py_DECREF(keys);
+ if (listrepr == NULL)
+ goto done;
+
+ result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
+ PyString_AS_STRING(listrepr));
+ Py_DECREF(listrepr);
+done:
+ Py_ReprLeave((PyObject*)so);
+ return result;
+}
+
+static Py_ssize_t
+set_len(PyObject *so)
+{
+ return ((PySetObject *)so)->used;
+}
+
+static int
+set_merge(PySetObject *so, PyObject *otherset)
+{
+ PySetObject *other;
+ PyObject *key;
+ long hash;
+ register Py_ssize_t i;
+ register setentry *entry;
+
+ assert (PyAnySet_Check(so));
+ assert (PyAnySet_Check(otherset));
+
+ other = (PySetObject*)otherset;
+ if (other == so || other->used == 0)
+ /* a.update(a) or a.update({}); nothing to do */
+ return 0;
+ /* Do one big resize at the start, rather than
+ * incrementally resizing as we insert new keys. Expect
+ * that there will be no (or few) overlapping keys.
+ */
+ if ((so->fill + other->used)*3 >= (so->mask+1)*2) {
+ if (set_table_resize(so, (so->used + other->used)*2) != 0)
+ return -1;
+ }
+ for (i = 0; i <= other->mask; i++) {
+ entry = &other->table[i];
+ key = entry->key;
+ hash = entry->hash;
+ if (key != NULL &&
+ key != dummy) {
+ Py_INCREF(key);
+ if (set_insert_key(so, key, hash) == -1) {
+ Py_DECREF(key);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+set_contains_key(PySetObject *so, PyObject *key)
+{
+ long hash;
+ setentry *entry;
+
+ if (!PyString_CheckExact(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1) {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ entry = (so->lookup)(so, key, hash);
+ if (entry == NULL)
+ return -1;
+ key = entry->key;
+ return key != NULL && key != dummy;
+}
+
+static int
+set_contains_entry(PySetObject *so, setentry *entry)
+{
+ PyObject *key;
+ setentry *lu_entry;
+
+ lu_entry = (so->lookup)(so, entry->key, entry->hash);
+ if (lu_entry == NULL)
+ return -1;
+ key = lu_entry->key;
+ return key != NULL && key != dummy;
+}
+
+static PyObject *
+set_pop(PySetObject *so)
+{
+ register Py_ssize_t i = 0;
+ register setentry *entry;
+ PyObject *key;
+
+ assert (PyAnySet_Check(so));
+ if (so->used == 0) {
+ PyErr_SetString(PyExc_KeyError, "pop from an empty set");
+ return NULL;
+ }
+
+ /* Set entry to "the first" unused or dummy set entry. We abuse
+ * the hash field of slot 0 to hold a search finger:
+ * If slot 0 has a value, use slot 0.
+ * Else slot 0 is being used to hold a search finger,
+ * and we use its hash value as the first index to look.
+ */
+ entry = &so->table[0];
+ if (entry->key == NULL || entry->key == dummy) {
+ i = entry->hash;
+ /* The hash field may be a real hash value, or it may be a
+ * legit search finger, or it may be a once-legit search
+ * finger that's out of bounds now because it wrapped around
+ * or the table shrunk -- simply make sure it's in bounds now.
+ */
+ if (i > so->mask || i < 1)
+ i = 1; /* skip slot 0 */
+ while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
+ i++;
+ if (i > so->mask)
+ i = 1;
+ }
+ }
+ key = entry->key;
+ Py_INCREF(dummy);
+ entry->key = dummy;
+ so->used--;
+ so->table[0].hash = i + 1; /* next place to start */
+ return key;
+}
+
+PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
+Raises KeyError if the set is empty.");
+
+static int
+set_traverse(PySetObject *so, visitproc visit, void *arg)
+{
+ Py_ssize_t pos = 0;
+ setentry *entry;
+
+ while (set_next(so, &pos, &entry))
+ Py_VISIT(entry->key);
+ return 0;
+}
+
+static long
+frozenset_hash(PyObject *self)
+{
+ PySetObject *so = (PySetObject *)self;
+ long h, hash = 1927868237L;
+ setentry *entry;
+ Py_ssize_t pos = 0;
+
+ if (so->hash != -1)
+ return so->hash;
+
+ hash *= PySet_GET_SIZE(self) + 1;
+ while (set_next(so, &pos, &entry)) {
+ /* Work to increase the bit dispersion for closely spaced hash
+ values. The is important because some use cases have many
+ combinations of a small number of elements with nearby
+ hashes so that many distinct combinations collapse to only
+ a handful of distinct hash values. */
+ h = entry->hash;
+ hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u;
+ }
+ hash = hash * 69069L + 907133923L;
+ if (hash == -1)
+ hash = 590923713L;
+ so->hash = hash;
+ return hash;
+}
+
+/***** Set iterator type ***********************************************/
+
+typedef struct {
+ PyObject_HEAD
+ PySetObject *si_set; /* Set to NULL when iterator is exhausted */
+ Py_ssize_t si_used;
+ Py_ssize_t si_pos;
+ Py_ssize_t len;
+} setiterobject;
+
+static void
+setiter_dealloc(setiterobject *si)
+{
+ Py_XDECREF(si->si_set);
+ PyObject_GC_Del(si);
+}
+
+static int
+setiter_traverse(setiterobject *si, visitproc visit, void *arg)
+{
+ Py_VISIT(si->si_set);
+ return 0;
+}
+
+static PyObject *
+setiter_len(setiterobject *si)
+{
+ Py_ssize_t len = 0;
+ if (si->si_set != NULL && si->si_used == si->si_set->used)
+ len = si->len;
+ return PyInt_FromLong(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef setiter_methods[] = {
+ {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *setiter_iternext(setiterobject *si)
+{
+ PyObject *key;
+ register Py_ssize_t i, mask;
+ register setentry *entry;
+ PySetObject *so = si->si_set;
+
+ if (so == NULL)
+ return NULL;
+ assert (PyAnySet_Check(so));
+
+ if (si->si_used != so->used) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Set changed size during iteration");
+ si->si_used = -1; /* Make this state sticky */
+ return NULL;
+ }
+
+ i = si->si_pos;
+ assert(i>=0);
+ entry = so->table;
+ mask = so->mask;
+ while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
+ i++;
+ si->si_pos = i+1;
+ if (i > mask)
+ goto fail;
+ si->len--;
+ key = entry[i].key;
+ Py_INCREF(key);
+ return key;
+
+fail:
+ Py_DECREF(so);
+ si->si_set = NULL;
+ return NULL;
+}
+
+static PyTypeObject PySetIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "setiterator", /* tp_name */
+ sizeof(setiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)setiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)setiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)setiter_iternext, /* tp_iternext */
+ setiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+set_iter(PySetObject *so)
+{
+ setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
+ if (si == NULL)
+ return NULL;
+ Py_INCREF(so);
+ si->si_set = so;
+ si->si_used = so->used;
+ si->si_pos = 0;
+ si->len = so->used;
+ _PyObject_GC_TRACK(si);
+ return (PyObject *)si;
+}
+
+static int
+set_update_internal(PySetObject *so, PyObject *other)
+{
+ PyObject *key, *it;
+
+ if (PyAnySet_Check(other))
+ return set_merge(so, other);
+
+ if (PyDict_CheckExact(other)) {
+ PyObject *value;
+ Py_ssize_t pos = 0;
+ long hash;
+ Py_ssize_t dictsize = PyDict_Size(other);
+
+ /* Do one big resize at the start, rather than
+ * incrementally resizing as we insert new keys. Expect
+ * that there will be no (or few) overlapping keys.
+ */
+ if (dictsize == -1)
+ return -1;
+ if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {
+ if (set_table_resize(so, (so->used + dictsize)*2) != 0)
+ return -1;
+ }
+ while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+ setentry an_entry;
+
+ an_entry.hash = hash;
+ an_entry.key = key;
+ if (set_add_entry(so, &an_entry) == -1)
+ return -1;
+ }
+ return 0;
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return -1;
+
+ while ((key = PyIter_Next(it)) != NULL) {
+ if (set_add_key(so, key) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(key);
+ return -1;
+ }
+ Py_DECREF(key);
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+}
+
+static PyObject *
+set_update(PySetObject *so, PyObject *args)
+{
+ Py_ssize_t i;
+
+ for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ PyObject *other = PyTuple_GET_ITEM(args, i);
+ if (set_update_internal(so, other) == -1)
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(update_doc,
+"Update a set with the union of itself and others.");
+
+static PyObject *
+make_new_set(PyTypeObject *type, PyObject *iterable)
+{
+ register PySetObject *so = NULL;
+
+ if (dummy == NULL) { /* Auto-initialize dummy */
+ dummy = PyString_FromString("<dummy key>");
+ if (dummy == NULL)
+ return NULL;
+ }
+
+ /* create PySetObject structure */
+ if (numfree &&
+ (type == &PySet_Type || type == &PyFrozenSet_Type)) {
+ so = free_list[--numfree];
+ assert (so != NULL && PyAnySet_CheckExact(so));
+ Py_TYPE(so) = type;
+ _Py_NewReference((PyObject *)so);
+ EMPTY_TO_MINSIZE(so);
+ PyObject_GC_Track(so);
+ } else {
+ so = (PySetObject *)type->tp_alloc(type, 0);
+ if (so == NULL)
+ return NULL;
+ /* tp_alloc has already zeroed the structure */
+ assert(so->table == NULL && so->fill == 0 && so->used == 0);
+ INIT_NONZERO_SET_SLOTS(so);
+ }
+
+ so->lookup = set_lookkey_string;
+ so->weakreflist = NULL;
+
+ if (iterable != NULL) {
+ if (set_update_internal(so, iterable) == -1) {
+ Py_DECREF(so);
+ return NULL;
+ }
+ }
+
+ return (PyObject *)so;
+}
+
+/* The empty frozenset is a singleton */
+static PyObject *emptyfrozenset = NULL;
+
+static PyObject *
+frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *iterable = NULL, *result;
+
+ if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
+ return NULL;
+
+ if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
+ return NULL;
+
+ if (type != &PyFrozenSet_Type)
+ return make_new_set(type, iterable);
+
+ if (iterable != NULL) {
+ /* frozenset(f) is idempotent */
+ if (PyFrozenSet_CheckExact(iterable)) {
+ Py_INCREF(iterable);
+ return iterable;
+ }
+ result = make_new_set(type, iterable);
+ if (result == NULL || PySet_GET_SIZE(result))
+ return result;
+ Py_DECREF(result);
+ }
+ /* The empty frozenset is a singleton */
+ if (emptyfrozenset == NULL)
+ emptyfrozenset = make_new_set(type, NULL);
+ Py_XINCREF(emptyfrozenset);
+ return emptyfrozenset;
+}
+
+void
+PySet_Fini(void)
+{
+ PySetObject *so;
+
+ while (numfree) {
+ numfree--;
+ so = free_list[numfree];
+ PyObject_GC_Del(so);
+ }
+ Py_CLEAR(dummy);
+ Py_CLEAR(emptyfrozenset);
+}
+
+static PyObject *
+set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
+ return NULL;
+
+ return make_new_set(type, NULL);
+}
+
+/* set_swap_bodies() switches the contents of any two sets by moving their
+ internal data pointers and, if needed, copying the internal smalltables.
+ Semantically equivalent to:
+
+ t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
+
+ The function always succeeds and it leaves both objects in a stable state.
+ Useful for creating temporary frozensets from sets for membership testing
+ in __contains__(), discard(), and remove(). Also useful for operations
+ that update in-place (by allowing an intermediate result to be swapped
+ into one of the original inputs).
+*/
+
+static void
+set_swap_bodies(PySetObject *a, PySetObject *b)
+{
+ Py_ssize_t t;
+ setentry *u;
+ setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+ setentry tab[PySet_MINSIZE];
+ long h;
+
+ t = a->fill; a->fill = b->fill; b->fill = t;
+ t = a->used; a->used = b->used; b->used = t;
+ t = a->mask; a->mask = b->mask; b->mask = t;
+
+ u = a->table;
+ if (a->table == a->smalltable)
+ u = b->smalltable;
+ a->table = b->table;
+ if (b->table == b->smalltable)
+ a->table = a->smalltable;
+ b->table = u;
+
+ f = a->lookup; a->lookup = b->lookup; b->lookup = f;
+
+ if (a->table == a->smalltable || b->table == b->smalltable) {
+ memcpy(tab, a->smalltable, sizeof(tab));
+ memcpy(a->smalltable, b->smalltable, sizeof(tab));
+ memcpy(b->smalltable, tab, sizeof(tab));
+ }
+
+ if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
+ PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
+ h = a->hash; a->hash = b->hash; b->hash = h;
+ } else {
+ a->hash = -1;
+ b->hash = -1;
+ }
+}
+
+static PyObject *
+set_copy(PySetObject *so)
+{
+ return make_new_set(Py_TYPE(so), (PyObject *)so);
+}
+
+static PyObject *
+frozenset_copy(PySetObject *so)
+{
+ if (PyFrozenSet_CheckExact(so)) {
+ Py_INCREF(so);
+ return (PyObject *)so;
+ }
+ return set_copy(so);
+}
+
+PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
+
+static PyObject *
+set_clear(PySetObject *so)
+{
+ set_clear_internal(so);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
+
+static PyObject *
+set_union(PySetObject *so, PyObject *args)
+{
+ PySetObject *result;
+ PyObject *other;
+ Py_ssize_t i;
+
+ result = (PySetObject *)set_copy(so);
+ if (result == NULL)
+ return NULL;
+
+ for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ other = PyTuple_GET_ITEM(args, i);
+ if ((PyObject *)so == other)
+ continue;
+ if (set_update_internal(result, other) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return (PyObject *)result;
+}
+
+PyDoc_STRVAR(union_doc,
+ "Return the union of sets as a new set.\n\
+\n\
+(i.e. all elements that are in either set.)");
+
+static PyObject *
+set_or(PySetObject *so, PyObject *other)
+{
+ PySetObject *result;
+
+ if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ result = (PySetObject *)set_copy(so);
+ if (result == NULL)
+ return NULL;
+ if ((PyObject *)so == other)
+ return (PyObject *)result;
+ if (set_update_internal(result, other) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ return (PyObject *)result;
+}
+
+static PyObject *
+set_ior(PySetObject *so, PyObject *other)
+{
+ if (!PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (set_update_internal(so, other) == -1)
+ return NULL;
+ Py_INCREF(so);
+ return (PyObject *)so;
+}
+
+static PyObject *
+set_intersection(PySetObject *so, PyObject *other)
+{
+ PySetObject *result;
+ PyObject *key, *it, *tmp;
+
+ if ((PyObject *)so == other)
+ return set_copy(so);
+
+ result = (PySetObject *)make_new_set(Py_TYPE(so), NULL);
+ if (result == NULL)
+ return NULL;
+
+ if (PyAnySet_Check(other)) {
+ Py_ssize_t pos = 0;
+ setentry *entry;
+
+ if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+ tmp = (PyObject *)so;
+ so = (PySetObject *)other;
+ other = tmp;
+ }
+
+ while (set_next((PySetObject *)other, &pos, &entry)) {
+ int rv = set_contains_entry(so, entry);
+ if (rv == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (rv) {
+ if (set_add_entry(result, entry) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ }
+ return (PyObject *)result;
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ while ((key = PyIter_Next(it)) != NULL) {
+ int rv;
+ setentry entry;
+ long hash = PyObject_Hash(key);
+
+ if (hash == -1) {
+ Py_DECREF(it);
+ Py_DECREF(result);
+ Py_DECREF(key);
+ return NULL;
+ }
+ entry.hash = hash;
+ entry.key = key;
+ rv = set_contains_entry(so, &entry);
+ if (rv == -1) {
+ Py_DECREF(it);
+ Py_DECREF(result);
+ Py_DECREF(key);
+ return NULL;
+ }
+ if (rv) {
+ if (set_add_entry(result, &entry) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(result);
+ Py_DECREF(key);
+ return NULL;
+ }
+ }
+ Py_DECREF(key);
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ return (PyObject *)result;
+}
+
+static PyObject *
+set_intersection_multi(PySetObject *so, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *result = (PyObject *)so;
+
+ if (PyTuple_GET_SIZE(args) == 0)
+ return set_copy(so);
+
+ Py_INCREF(so);
+ for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ PyObject *other = PyTuple_GET_ITEM(args, i);
+ PyObject *newresult = set_intersection((PySetObject *)result, other);
+ if (newresult == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_DECREF(result);
+ result = newresult;
+ }
+ return result;
+}
+
+PyDoc_STRVAR(intersection_doc,
+"Return the intersection of two or more sets as a new set.\n\
+\n\
+(i.e. elements that are common to all of the sets.)");
+
+static PyObject *
+set_intersection_update(PySetObject *so, PyObject *other)
+{
+ PyObject *tmp;
+
+ tmp = set_intersection(so, other);
+ if (tmp == NULL)
+ return NULL;
+ set_swap_bodies(so, (PySetObject *)tmp);
+ Py_DECREF(tmp);
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+set_intersection_update_multi(PySetObject *so, PyObject *args)
+{
+ PyObject *tmp;
+
+ tmp = set_intersection_multi(so, args);
+ if (tmp == NULL)
+ return NULL;
+ set_swap_bodies(so, (PySetObject *)tmp);
+ Py_DECREF(tmp);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(intersection_update_doc,
+"Update a set with the intersection of itself and another.");
+
+static PyObject *
+set_and(PySetObject *so, PyObject *other)
+{
+ if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return set_intersection(so, other);
+}
+
+static PyObject *
+set_iand(PySetObject *so, PyObject *other)
+{
+ PyObject *result;
+
+ if (!PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ result = set_intersection_update(so, other);
+ if (result == NULL)
+ return NULL;
+ Py_DECREF(result);
+ Py_INCREF(so);
+ return (PyObject *)so;
+}
+
+static PyObject *
+set_isdisjoint(PySetObject *so, PyObject *other)
+{
+ PyObject *key, *it, *tmp;
+
+ if ((PyObject *)so == other) {
+ if (PySet_GET_SIZE(so) == 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+
+ if (PyAnySet_CheckExact(other)) {
+ Py_ssize_t pos = 0;
+ setentry *entry;
+
+ if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
+ tmp = (PyObject *)so;
+ so = (PySetObject *)other;
+ other = tmp;
+ }
+ while (set_next((PySetObject *)other, &pos, &entry)) {
+ int rv = set_contains_entry(so, entry);
+ if (rv == -1)
+ return NULL;
+ if (rv)
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return NULL;
+
+ while ((key = PyIter_Next(it)) != NULL) {
+ int rv;
+ setentry entry;
+ long hash = PyObject_Hash(key);
+
+ if (hash == -1) {
+ Py_DECREF(key);
+ Py_DECREF(it);
+ return NULL;
+ }
+ entry.hash = hash;
+ entry.key = key;
+ rv = set_contains_entry(so, &entry);
+ Py_DECREF(key);
+ if (rv == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+ if (rv) {
+ Py_DECREF(it);
+ Py_RETURN_FALSE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL;
+ Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if two sets have a null intersection.");
+
+static int
+set_difference_update_internal(PySetObject *so, PyObject *other)
+{
+ if ((PyObject *)so == other)
+ return set_clear_internal(so);
+
+ if (PyAnySet_Check(other)) {
+ setentry *entry;
+ Py_ssize_t pos = 0;
+
+ while (set_next((PySetObject *)other, &pos, &entry))
+ if (set_discard_entry(so, entry) == -1)
+ return -1;
+ } else {
+ PyObject *key, *it;
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return -1;
+
+ while ((key = PyIter_Next(it)) != NULL) {
+ if (set_discard_key(so, key) == -1) {
+ Py_DECREF(it);
+ Py_DECREF(key);
+ return -1;
+ }
+ Py_DECREF(key);
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return -1;
+ }
+ /* If more than 1/5 are dummies, then resize them away. */
+ if ((so->fill - so->used) * 5 < so->mask)
+ return 0;
+ return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
+}
+
+static PyObject *
+set_difference_update(PySetObject *so, PyObject *args)
+{
+ Py_ssize_t i;
+
+ for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ PyObject *other = PyTuple_GET_ITEM(args, i);
+ if (set_difference_update_internal(so, other) == -1)
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(difference_update_doc,
+"Remove all elements of another set from this set.");
+
+static PyObject *
+set_difference(PySetObject *so, PyObject *other)
+{
+ PyObject *result;
+ setentry *entry;
+ Py_ssize_t pos = 0;
+
+ if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
+ result = set_copy(so);
+ if (result == NULL)
+ return NULL;
+ if (set_difference_update_internal((PySetObject *)result, other) != -1)
+ return result;
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ result = make_new_set(Py_TYPE(so), NULL);
+ if (result == NULL)
+ return NULL;
+
+ if (PyDict_CheckExact(other)) {
+ while (set_next(so, &pos, &entry)) {
+ setentry entrycopy;
+ entrycopy.hash = entry->hash;
+ entrycopy.key = entry->key;
+ if (!_PyDict_Contains(other, entry->key, entry->hash)) {
+ if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ }
+ return result;
+ }
+
+ while (set_next(so, &pos, &entry)) {
+ int rv = set_contains_entry((PySetObject *)other, entry);
+ if (rv == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (!rv) {
+ if (set_add_entry((PySetObject *)result, entry) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ }
+ return result;
+}
+
+static PyObject *
+set_difference_multi(PySetObject *so, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *result, *other;
+
+ if (PyTuple_GET_SIZE(args) == 0)
+ return set_copy(so);
+
+ other = PyTuple_GET_ITEM(args, 0);
+ result = set_difference(so, other);
+ if (result == NULL)
+ return NULL;
+
+ for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ other = PyTuple_GET_ITEM(args, i);
+ if (set_difference_update_internal((PySetObject *)result, other) == -1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+PyDoc_STRVAR(difference_doc,
+"Return the difference of two or more sets as a new set.\n\
+\n\
+(i.e. all elements that are in this set but not the others.)");
+static PyObject *
+set_sub(PySetObject *so, PyObject *other)
+{
+ if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return set_difference(so, other);
+}
+
+static PyObject *
+set_isub(PySetObject *so, PyObject *other)
+{
+ if (!PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (set_difference_update_internal(so, other) == -1)
+ return NULL;
+ Py_INCREF(so);
+ return (PyObject *)so;
+}
+
+static PyObject *
+set_symmetric_difference_update(PySetObject *so, PyObject *other)
+{
+ PySetObject *otherset;
+ PyObject *key;
+ Py_ssize_t pos = 0;
+ setentry *entry;
+
+ if ((PyObject *)so == other)
+ return set_clear(so);
+
+ if (PyDict_CheckExact(other)) {
+ PyObject *value;
+ int rv;
+ long hash;
+ while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+ setentry an_entry;
+
+ Py_INCREF(key);
+ an_entry.hash = hash;
+ an_entry.key = key;
+
+ rv = set_discard_entry(so, &an_entry);
+ if (rv == -1) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ if (rv == DISCARD_NOTFOUND) {
+ if (set_add_entry(so, &an_entry) == -1) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ }
+ Py_DECREF(key);
+ }
+ Py_RETURN_NONE;
+ }
+
+ if (PyAnySet_Check(other)) {
+ Py_INCREF(other);
+ otherset = (PySetObject *)other;
+ } else {
+ otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+ if (otherset == NULL)
+ return NULL;
+ }
+
+ while (set_next(otherset, &pos, &entry)) {
+ int rv = set_discard_entry(so, entry);
+ if (rv == -1) {
+ Py_DECREF(otherset);
+ return NULL;
+ }
+ if (rv == DISCARD_NOTFOUND) {
+ if (set_add_entry(so, entry) == -1) {
+ Py_DECREF(otherset);
+ return NULL;
+ }
+ }
+ }
+ Py_DECREF(otherset);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(symmetric_difference_update_doc,
+"Update a set with the symmetric difference of itself and another.");
+
+static PyObject *
+set_symmetric_difference(PySetObject *so, PyObject *other)
+{
+ PyObject *rv;
+ PySetObject *otherset;
+
+ otherset = (PySetObject *)make_new_set(Py_TYPE(so), other);
+ if (otherset == NULL)
+ return NULL;
+ rv = set_symmetric_difference_update(otherset, (PyObject *)so);
+ if (rv == NULL)
+ return NULL;
+ Py_DECREF(rv);
+ return (PyObject *)otherset;
+}
+
+PyDoc_STRVAR(symmetric_difference_doc,
+"Return the symmetric difference of two sets as a new set.\n\
+\n\
+(i.e. all elements that are in exactly one of the sets.)");
+
+static PyObject *
+set_xor(PySetObject *so, PyObject *other)
+{
+ if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return set_symmetric_difference(so, other);
+}
+
+static PyObject *
+set_ixor(PySetObject *so, PyObject *other)
+{
+ PyObject *result;
+
+ if (!PyAnySet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ result = set_symmetric_difference_update(so, other);
+ if (result == NULL)
+ return NULL;
+ Py_DECREF(result);
+ Py_INCREF(so);
+ return (PyObject *)so;
+}
+
+static PyObject *
+set_issubset(PySetObject *so, PyObject *other)
+{
+ setentry *entry;
+ Py_ssize_t pos = 0;
+
+ if (!PyAnySet_Check(other)) {
+ PyObject *tmp, *result;
+ tmp = make_new_set(&PySet_Type, other);
+ if (tmp == NULL)
+ return NULL;
+ result = set_issubset(so, tmp);
+ Py_DECREF(tmp);
+ return result;
+ }
+ if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
+ Py_RETURN_FALSE;
+
+ while (set_next(so, &pos, &entry)) {
+ int rv = set_contains_entry((PySetObject *)other, entry);
+ if (rv == -1)
+ return NULL;
+ if (!rv)
+ Py_RETURN_FALSE;
+ }
+ Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
+
+static PyObject *
+set_issuperset(PySetObject *so, PyObject *other)
+{
+ PyObject *tmp, *result;
+
+ if (!PyAnySet_Check(other)) {
+ tmp = make_new_set(&PySet_Type, other);
+ if (tmp == NULL)
+ return NULL;
+ result = set_issuperset(so, tmp);
+ Py_DECREF(tmp);
+ return result;
+ }
+ return set_issubset((PySetObject *)other, (PyObject *)so);
+}
+
+PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
+
+static PyObject *
+set_richcompare(PySetObject *v, PyObject *w, int op)
+{
+ PyObject *r1, *r2;
+
+ if(!PyAnySet_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ switch (op) {
+ case Py_EQ:
+ if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
+ Py_RETURN_FALSE;
+ if (v->hash != -1 &&
+ ((PySetObject *)w)->hash != -1 &&
+ v->hash != ((PySetObject *)w)->hash)
+ Py_RETURN_FALSE;
+ return set_issubset(v, w);
+ case Py_NE:
+ r1 = set_richcompare(v, w, Py_EQ);
+ if (r1 == NULL)
+ return NULL;
+ r2 = PyBool_FromLong(PyObject_Not(r1));
+ Py_DECREF(r1);
+ return r2;
+ case Py_LE:
+ return set_issubset(v, w);
+ case Py_GE:
+ return set_issuperset(v, w);
+ case Py_LT:
+ if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
+ Py_RETURN_FALSE;
+ return set_issubset(v, w);
+ case Py_GT:
+ if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
+ Py_RETURN_FALSE;
+ return set_issuperset(v, w);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static int
+set_nocmp(PyObject *self, PyObject *other)
+{
+ PyErr_SetString(PyExc_TypeError, "cannot compare sets using cmp()");
+ return -1;
+}
+
+static PyObject *
+set_add(PySetObject *so, PyObject *key)
+{
+ if (set_add_key(so, key) == -1)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(add_doc,
+"Add an element to a set.\n\
+\n\
+This has no effect if the element is already present.");
+
+static int
+set_contains(PySetObject *so, PyObject *key)
+{
+ PyObject *tmpkey;
+ int rv;
+
+ rv = set_contains_key(so, key);
+ if (rv == -1) {
+ if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+ return -1;
+ PyErr_Clear();
+ tmpkey = make_new_set(&PyFrozenSet_Type, key);
+ if (tmpkey == NULL)
+ return -1;
+ rv = set_contains_key(so, tmpkey);
+ Py_DECREF(tmpkey);
+ }
+ return rv;
+}
+
+static PyObject *
+set_direct_contains(PySetObject *so, PyObject *key)
+{
+ long result;
+
+ result = set_contains(so, key);
+ if (result == -1)
+ return NULL;
+ return PyBool_FromLong(result);
+}
+
+PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
+
+static PyObject *
+set_remove(PySetObject *so, PyObject *key)
+{
+ PyObject *tmpkey;
+ int rv;
+
+ rv = set_discard_key(so, key);
+ if (rv == -1) {
+ if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+ return NULL;
+ PyErr_Clear();
+ tmpkey = make_new_set(&PyFrozenSet_Type, key);
+ if (tmpkey == NULL)
+ return NULL;
+ rv = set_discard_key(so, tmpkey);
+ Py_DECREF(tmpkey);
+ if (rv == -1)
+ return NULL;
+ }
+
+ if (rv == DISCARD_NOTFOUND) {
+ set_key_error(key);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(remove_doc,
+"Remove an element from a set; it must be a member.\n\
+\n\
+If the element is not a member, raise a KeyError.");
+
+static PyObject *
+set_discard(PySetObject *so, PyObject *key)
+{
+ PyObject *tmpkey;
+ int rv;
+
+ rv = set_discard_key(so, key);
+ if (rv == -1) {
+ if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
+ return NULL;
+ PyErr_Clear();
+ tmpkey = make_new_set(&PyFrozenSet_Type, key);
+ if (tmpkey == NULL)
+ return NULL;
+ rv = set_discard_key(so, tmpkey);
+ Py_DECREF(tmpkey);
+ if (rv == -1)
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(discard_doc,
+"Remove an element from a set if it is a member.\n\
+\n\
+If the element is not a member, do nothing.");
+
+static PyObject *
+set_reduce(PySetObject *so)
+{
+ PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
+
+ keys = PySequence_List((PyObject *)so);
+ if (keys == NULL)
+ goto done;
+ args = PyTuple_Pack(1, keys);
+ if (args == NULL)
+ goto done;
+ dict = PyObject_GetAttrString((PyObject *)so, "__dict__");
+ if (dict == NULL) {
+ PyErr_Clear();
+ dict = Py_None;
+ Py_INCREF(dict);
+ }
+ result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
+done:
+ Py_XDECREF(args);
+ Py_XDECREF(keys);
+ Py_XDECREF(dict);
+ return result;
+}
+
+PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
+
+static PyObject *
+set_sizeof(PySetObject *so)
+{
+ Py_ssize_t res;
+
+ res = sizeof(PySetObject);
+ if (so->table != so->smalltable)
+ res = res + (so->mask + 1) * sizeof(setentry);
+ return PyInt_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
+static int
+set_init(PySetObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *iterable = NULL;
+
+ if (!PyAnySet_Check(self))
+ return -1;
+ if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
+ return -1;
+ if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
+ return -1;
+ set_clear_internal(self);
+ self->hash = -1;
+ if (iterable == NULL)
+ return 0;
+ return set_update_internal(self, iterable);
+}
+
+static PySequenceMethods set_as_sequence = {
+ set_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)set_contains, /* sq_contains */
+};
+
+/* set object ********************************************************/
+
+#ifdef Py_DEBUG
+static PyObject *test_c_api(PySetObject *so);
+
+PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
+All is well if assertions don't fail.");
+#endif
+
+static PyMethodDef set_methods[] = {
+ {"add", (PyCFunction)set_add, METH_O,
+ add_doc},
+ {"clear", (PyCFunction)set_clear, METH_NOARGS,
+ clear_doc},
+ {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
+ contains_doc},
+ {"copy", (PyCFunction)set_copy, METH_NOARGS,
+ copy_doc},
+ {"discard", (PyCFunction)set_discard, METH_O,
+ discard_doc},
+ {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
+ difference_doc},
+ {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
+ difference_update_doc},
+ {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
+ intersection_doc},
+ {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
+ intersection_update_doc},
+ {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
+ isdisjoint_doc},
+ {"issubset", (PyCFunction)set_issubset, METH_O,
+ issubset_doc},
+ {"issuperset", (PyCFunction)set_issuperset, METH_O,
+ issuperset_doc},
+ {"pop", (PyCFunction)set_pop, METH_NOARGS,
+ pop_doc},
+ {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
+ reduce_doc},
+ {"remove", (PyCFunction)set_remove, METH_O,
+ remove_doc},
+ {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
+ sizeof_doc},
+ {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
+ symmetric_difference_doc},
+ {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
+ symmetric_difference_update_doc},
+#ifdef Py_DEBUG
+ {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
+ test_c_api_doc},
+#endif
+ {"union", (PyCFunction)set_union, METH_VARARGS,
+ union_doc},
+ {"update", (PyCFunction)set_update, METH_VARARGS,
+ update_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyNumberMethods set_as_number = {
+ 0, /*nb_add*/
+ (binaryfunc)set_sub, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ 0, /*nb_remainder*/
+ 0, /*nb_divmod*/
+ 0, /*nb_power*/
+ 0, /*nb_negative*/
+ 0, /*nb_positive*/
+ 0, /*nb_absolute*/
+ 0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ (binaryfunc)set_and, /*nb_and*/
+ (binaryfunc)set_xor, /*nb_xor*/
+ (binaryfunc)set_or, /*nb_or*/
+ 0, /*nb_coerce*/
+ 0, /*nb_int*/
+ 0, /*nb_long*/
+ 0, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
+ 0, /*nb_inplace_add*/
+ (binaryfunc)set_isub, /*nb_inplace_subtract*/
+ 0, /*nb_inplace_multiply*/
+ 0, /*nb_inplace_divide*/
+ 0, /*nb_inplace_remainder*/
+ 0, /*nb_inplace_power*/
+ 0, /*nb_inplace_lshift*/
+ 0, /*nb_inplace_rshift*/
+ (binaryfunc)set_iand, /*nb_inplace_and*/
+ (binaryfunc)set_ixor, /*nb_inplace_xor*/
+ (binaryfunc)set_ior, /*nb_inplace_or*/
+};
+
+PyDoc_STRVAR(set_doc,
+"set() -> new empty set object\n\
+set(iterable) -> new set object\n\
+\n\
+Build an unordered collection of unique elements.");
+
+PyTypeObject PySet_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "set", /* tp_name */
+ sizeof(PySetObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)set_dealloc, /* tp_dealloc */
+ (printfunc)set_tp_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ set_nocmp, /* tp_compare */
+ (reprfunc)set_repr, /* tp_repr */
+ &set_as_number, /* tp_as_number */
+ &set_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ set_doc, /* tp_doc */
+ (traverseproc)set_traverse, /* tp_traverse */
+ (inquiry)set_clear_internal, /* tp_clear */
+ (richcmpfunc)set_richcompare, /* tp_richcompare */
+ offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)set_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ set_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)set_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ set_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/* frozenset object ********************************************************/
+
+
+static PyMethodDef frozenset_methods[] = {
+ {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
+ contains_doc},
+ {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
+ copy_doc},
+ {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
+ difference_doc},
+ {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
+ intersection_doc},
+ {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
+ isdisjoint_doc},
+ {"issubset", (PyCFunction)set_issubset, METH_O,
+ issubset_doc},
+ {"issuperset", (PyCFunction)set_issuperset, METH_O,
+ issuperset_doc},
+ {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
+ reduce_doc},
+ {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
+ sizeof_doc},
+ {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
+ symmetric_difference_doc},
+ {"union", (PyCFunction)set_union, METH_VARARGS,
+ union_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyNumberMethods frozenset_as_number = {
+ 0, /*nb_add*/
+ (binaryfunc)set_sub, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ 0, /*nb_remainder*/
+ 0, /*nb_divmod*/
+ 0, /*nb_power*/
+ 0, /*nb_negative*/
+ 0, /*nb_positive*/
+ 0, /*nb_absolute*/
+ 0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ (binaryfunc)set_and, /*nb_and*/
+ (binaryfunc)set_xor, /*nb_xor*/
+ (binaryfunc)set_or, /*nb_or*/
+};
+
+PyDoc_STRVAR(frozenset_doc,
+"frozenset() -> empty frozenset object\n\
+frozenset(iterable) -> frozenset object\n\
+\n\
+Build an immutable unordered collection of unique elements.");
+
+PyTypeObject PyFrozenSet_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "frozenset", /* tp_name */
+ sizeof(PySetObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)set_dealloc, /* tp_dealloc */
+ (printfunc)set_tp_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ set_nocmp, /* tp_compare */
+ (reprfunc)set_repr, /* tp_repr */
+ &frozenset_as_number, /* tp_as_number */
+ &set_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ frozenset_hash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ frozenset_doc, /* tp_doc */
+ (traverseproc)set_traverse, /* tp_traverse */
+ (inquiry)set_clear_internal, /* tp_clear */
+ (richcmpfunc)set_richcompare, /* tp_richcompare */
+ offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)set_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ frozenset_methods, /* tp_methods */
+ 0, /* 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 */
+ PyType_GenericAlloc, /* tp_alloc */
+ frozenset_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+
+/***** C API functions *************************************************/
+
+PyObject *
+PySet_New(PyObject *iterable)
+{
+ return make_new_set(&PySet_Type, iterable);
+}
+
+PyObject *
+PyFrozenSet_New(PyObject *iterable)
+{
+ return make_new_set(&PyFrozenSet_Type, iterable);
+}
+
+Py_ssize_t
+PySet_Size(PyObject *anyset)
+{
+ if (!PyAnySet_Check(anyset)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return PySet_GET_SIZE(anyset);
+}
+
+int
+PySet_Clear(PyObject *set)
+{
+ if (!PySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return set_clear_internal((PySetObject *)set);
+}
+
+int
+PySet_Contains(PyObject *anyset, PyObject *key)
+{
+ if (!PyAnySet_Check(anyset)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return set_contains_key((PySetObject *)anyset, key);
+}
+
+int
+PySet_Discard(PyObject *set, PyObject *key)
+{
+ if (!PySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return set_discard_key((PySetObject *)set, key);
+}
+
+int
+PySet_Add(PyObject *anyset, PyObject *key)
+{
+ if (!PySet_Check(anyset) &&
+ (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return set_add_key((PySetObject *)anyset, key);
+}
+
+int
+_PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key)
+{
+ setentry *entry_ptr;
+
+ if (!PyAnySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (set_next((PySetObject *)set, pos, &entry_ptr) == 0)
+ return 0;
+ *key = entry_ptr->key;
+ return 1;
+}
+
+int
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+{
+ setentry *entry;
+
+ if (!PyAnySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (set_next((PySetObject *)set, pos, &entry) == 0)
+ return 0;
+ *key = entry->key;
+ *hash = entry->hash;
+ return 1;
+}
+
+PyObject *
+PySet_Pop(PyObject *set)
+{
+ if (!PySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return set_pop((PySetObject *)set);
+}
+
+int
+_PySet_Update(PyObject *set, PyObject *iterable)
+{
+ if (!PySet_Check(set)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ return set_update_internal((PySetObject *)set, iterable);
+}
+
+#ifdef Py_DEBUG
+
+/* Test code to be called with any three element set.
+ Returns True and original set is restored. */
+
+#define assertRaises(call_return_value, exception) \
+ do { \
+ assert(call_return_value); \
+ assert(PyErr_ExceptionMatches(exception)); \
+ PyErr_Clear(); \
+ } while(0)
+
+static PyObject *
+test_c_api(PySetObject *so)
+{
+ Py_ssize_t count;
+ char *s;
+ Py_ssize_t i;
+ PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
+ PyObject *ob = (PyObject *)so;
+ PyObject *str;
+
+ /* Verify preconditions */
+ assert(PyAnySet_Check(ob));
+ assert(PyAnySet_CheckExact(ob));
+ assert(!PyFrozenSet_CheckExact(ob));
+
+ /* so.clear(); so |= set("abc"); */
+ str = PyString_FromString("abc");
+ if (str == NULL)
+ return NULL;
+ set_clear_internal(so);
+ if (set_update_internal(so, str) == -1) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ Py_DECREF(str);
+
+ /* Exercise type/size checks */
+ assert(PySet_Size(ob) == 3);
+ assert(PySet_GET_SIZE(ob) == 3);
+
+ /* Raise TypeError for non-iterable constructor arguments */
+ assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
+ assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
+
+ /* Raise TypeError for unhashable key */
+ dup = PySet_New(ob);
+ assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
+ assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
+ assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
+
+ /* Exercise successful pop, contains, add, and discard */
+ elem = PySet_Pop(ob);
+ assert(PySet_Contains(ob, elem) == 0);
+ assert(PySet_GET_SIZE(ob) == 2);
+ assert(PySet_Add(ob, elem) == 0);
+ assert(PySet_Contains(ob, elem) == 1);
+ assert(PySet_GET_SIZE(ob) == 3);
+ assert(PySet_Discard(ob, elem) == 1);
+ assert(PySet_GET_SIZE(ob) == 2);
+ assert(PySet_Discard(ob, elem) == 0);
+ assert(PySet_GET_SIZE(ob) == 2);
+
+ /* Exercise clear */
+ dup2 = PySet_New(dup);
+ assert(PySet_Clear(dup2) == 0);
+ assert(PySet_Size(dup2) == 0);
+ Py_DECREF(dup2);
+
+ /* Raise SystemError on clear or update of frozen set */
+ f = PyFrozenSet_New(dup);
+ assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
+ assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
+ assert(PySet_Add(f, elem) == 0);
+ Py_INCREF(f);
+ assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
+ Py_DECREF(f);
+ Py_DECREF(f);
+
+ /* Exercise direct iteration */
+ i = 0, count = 0;
+ while (_PySet_Next((PyObject *)dup, &i, &x)) {
+ s = PyString_AsString(x);
+ assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
+ count++;
+ }
+ assert(count == 3);
+
+ /* Exercise updates */
+ dup2 = PySet_New(NULL);
+ assert(_PySet_Update(dup2, dup) == 0);
+ assert(PySet_Size(dup2) == 3);
+ assert(_PySet_Update(dup2, dup) == 0);
+ assert(PySet_Size(dup2) == 3);
+ Py_DECREF(dup2);
+
+ /* Raise SystemError when self argument is not a set or frozenset. */
+ t = PyTuple_New(0);
+ assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
+ assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
+ Py_DECREF(t);
+
+ /* Raise SystemError when self argument is not a set. */
+ f = PyFrozenSet_New(dup);
+ assert(PySet_Size(f) == 3);
+ assert(PyFrozenSet_CheckExact(f));
+ assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
+ assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
+ Py_DECREF(f);
+
+ /* Raise KeyError when popping from an empty set */
+ assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
+ Py_DECREF(ob);
+ assert(PySet_GET_SIZE(ob) == 0);
+ assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
+
+ /* Restore the set from the copy using the PyNumber API */
+ assert(PyNumber_InPlaceOr(ob, dup) == ob);
+ Py_DECREF(ob);
+
+ /* Verify constructors accept NULL arguments */
+ f = PySet_New(NULL);
+ assert(f != NULL);
+ assert(PySet_GET_SIZE(f) == 0);
+ Py_DECREF(f);
+ f = PyFrozenSet_New(NULL);
+ assert(f != NULL);
+ assert(PyFrozenSet_CheckExact(f));
+ assert(PySet_GET_SIZE(f) == 0);
+ Py_DECREF(f);
+
+ Py_DECREF(elem);
+ Py_DECREF(dup);
+ Py_RETURN_TRUE;
+}
+
+#undef assertRaises
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/sliceobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/sliceobject.c
new file mode 100644
index 0000000000..00b579b1ba
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/sliceobject.c
@@ -0,0 +1,362 @@
+/*
+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(stop)\n\
+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 */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/README.txt b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/README.txt
new file mode 100644
index 0000000000..66e671fa74
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/README.txt
@@ -0,0 +1,40 @@
+bits shared by the stringobject and unicodeobject implementations (and
+possibly other modules, in a not too distant future).
+
+the stuff in here is included into relevant places; see the individual
+source files for details.
+
+--------------------------------------------------------------------
+the following defines used by the different modules:
+
+STRINGLIB_CHAR
+
+ the type used to hold a character (char or Py_UNICODE)
+
+STRINGLIB_EMPTY
+
+ a PyObject representing the empty string, only to be used if
+ STRINGLIB_MUTABLE is 0
+
+Py_ssize_t STRINGLIB_LEN(PyObject*)
+
+ returns the length of the given string object (which must be of the
+ right type)
+
+PyObject* STRINGLIB_NEW(STRINGLIB_CHAR*, Py_ssize_t)
+
+ creates a new string object
+
+STRINGLIB_CHAR* STRINGLIB_STR(PyObject*)
+
+ returns the pointer to the character data for the given string
+ object (which must be of the right type)
+
+int STRINGLIB_CHECK_EXACT(PyObject *)
+
+ returns true if the object is an instance of our type, not a subclass
+
+STRINGLIB_MUTABLE
+
+ must be 0 or 1 to tell the cpp macros in stringlib code if the object
+ being operated on is mutable or not
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/count.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/count.h
new file mode 100644
index 0000000000..216c269390
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/count.h
@@ -0,0 +1,30 @@
+/* stringlib: count implementation */
+
+#ifndef STRINGLIB_COUNT_H
+#define STRINGLIB_COUNT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_count(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t count;
+
+ if (str_len < 0)
+ return 0; /* start > len(str) */
+ if (sub_len == 0)
+ return (str_len < maxcount) ? str_len + 1 : maxcount;
+
+ count = fastsearch(str, str_len, sub, sub_len, maxcount, FAST_COUNT);
+
+ if (count < 0)
+ return 0; /* no match */
+
+ return count;
+}
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/ctype.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/ctype.h
new file mode 100644
index 0000000000..df2fede7e5
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/ctype.h
@@ -0,0 +1,109 @@
+/* NOTE: this API is -ONLY- for use with single byte character strings. */
+/* Do not use it with Unicode. */
+
+#include "bytes_methods.h"
+
+static PyObject*
+stringlib_isspace(PyObject *self)
+{
+ return _Py_bytes_isspace(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isalpha(PyObject *self)
+{
+ return _Py_bytes_isalpha(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isalnum(PyObject *self)
+{
+ return _Py_bytes_isalnum(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isdigit(PyObject *self)
+{
+ return _Py_bytes_isdigit(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_islower(PyObject *self)
+{
+ return _Py_bytes_islower(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_isupper(PyObject *self)
+{
+ return _Py_bytes_isupper(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+static PyObject*
+stringlib_istitle(PyObject *self)
+{
+ return _Py_bytes_istitle(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+}
+
+
+/* functions that return a new object partially translated by ctype funcs: */
+
+static PyObject*
+stringlib_lower(PyObject *self)
+{
+ PyObject* newobj;
+ newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+ if (!newobj)
+ return NULL;
+ _Py_bytes_lower(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ return newobj;
+}
+
+static PyObject*
+stringlib_upper(PyObject *self)
+{
+ PyObject* newobj;
+ newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+ if (!newobj)
+ return NULL;
+ _Py_bytes_upper(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ return newobj;
+}
+
+static PyObject*
+stringlib_title(PyObject *self)
+{
+ PyObject* newobj;
+ newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+ if (!newobj)
+ return NULL;
+ _Py_bytes_title(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ return newobj;
+}
+
+static PyObject*
+stringlib_capitalize(PyObject *self)
+{
+ PyObject* newobj;
+ newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+ if (!newobj)
+ return NULL;
+ _Py_bytes_capitalize(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ return newobj;
+}
+
+static PyObject*
+stringlib_swapcase(PyObject *self)
+{
+ PyObject* newobj;
+ newobj = STRINGLIB_NEW(NULL, STRINGLIB_LEN(self));
+ if (!newobj)
+ return NULL;
+ _Py_bytes_swapcase(STRINGLIB_STR(newobj), STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ return newobj;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/fastsearch.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/fastsearch.h
new file mode 100644
index 0000000000..6255b36e44
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/fastsearch.h
@@ -0,0 +1,160 @@
+/* stringlib: fastsearch implementation */
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#define STRINGLIB_FASTSEARCH_H
+
+/* fast search/count implementation, based on a mix between boyer-
+ moore and horspool, with a few more bells and whistles on the top.
+ for some more background, see: http://effbot.org/zone/stringlib.htm */
+
+/* note: fastsearch may access s[n], which isn't a problem when using
+ Python's ordinary string types, but may cause problems if you're
+ using this code in other contexts. also, the count mode returns -1
+ if there cannot possible be a match in the target string, and 0 if
+ it has actually checked for matches, but didn't find any. callers
+ beware! */
+
+#define FAST_COUNT 0
+#define FAST_SEARCH 1
+#define FAST_RSEARCH 2
+
+#if LONG_BIT >= 128
+#define STRINGLIB_BLOOM_WIDTH 128
+#elif LONG_BIT >= 64
+#define STRINGLIB_BLOOM_WIDTH 64
+#elif LONG_BIT >= 32
+#define STRINGLIB_BLOOM_WIDTH 32
+#else
+#error "LONG_BIT is smaller than 32"
+#endif
+
+#define STRINGLIB_BLOOM_ADD(mask, ch) \
+ ((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
+#define STRINGLIB_BLOOM(mask, ch) \
+ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
+
+Py_LOCAL_INLINE(Py_ssize_t)
+fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n,
+ const STRINGLIB_CHAR* p, Py_ssize_t m,
+ Py_ssize_t maxcount, int mode)
+{
+ unsigned long mask;
+ Py_ssize_t skip, count = 0;
+ Py_ssize_t i, j, mlast, w;
+
+ w = n - m;
+
+ if (w < 0 || (mode == FAST_COUNT && maxcount == 0))
+ return -1;
+
+ /* look for special cases */
+ if (m <= 1) {
+ if (m <= 0)
+ return -1;
+ /* use special case for 1-character strings */
+ if (mode == FAST_COUNT) {
+ for (i = 0; i < n; i++)
+ if (s[i] == p[0]) {
+ count++;
+ if (count == maxcount)
+ return maxcount;
+ }
+ return count;
+ } else if (mode == FAST_SEARCH) {
+ for (i = 0; i < n; i++)
+ if (s[i] == p[0])
+ return i;
+ } else { /* FAST_RSEARCH */
+ for (i = n - 1; i > -1; i--)
+ if (s[i] == p[0])
+ return i;
+ }
+ return -1;
+ }
+
+ mlast = m - 1;
+ skip = mlast - 1;
+ mask = 0;
+
+ if (mode != FAST_RSEARCH) {
+
+ /* create compressed boyer-moore delta 1 table */
+
+ /* process pattern[:-1] */
+ for (i = 0; i < mlast; i++) {
+ STRINGLIB_BLOOM_ADD(mask, p[i]);
+ if (p[i] == p[mlast])
+ skip = mlast - i - 1;
+ }
+ /* process pattern[-1] outside the loop */
+ STRINGLIB_BLOOM_ADD(mask, p[mlast]);
+
+ for (i = 0; i <= w; i++) {
+ /* note: using mlast in the skip path slows things down on x86 */
+ if (s[i+m-1] == p[m-1]) {
+ /* candidate match */
+ for (j = 0; j < mlast; j++)
+ if (s[i+j] != p[j])
+ break;
+ if (j == mlast) {
+ /* got a match! */
+ if (mode != FAST_COUNT)
+ return i;
+ count++;
+ if (count == maxcount)
+ return maxcount;
+ i = i + mlast;
+ continue;
+ }
+ /* miss: check if next character is part of pattern */
+ if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ i = i + m;
+ else
+ i = i + skip;
+ } else {
+ /* skip: check if next character is part of pattern */
+ if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ i = i + m;
+ }
+ }
+ } else { /* FAST_RSEARCH */
+
+ /* create compressed boyer-moore delta 1 table */
+
+ /* process pattern[0] outside the loop */
+ STRINGLIB_BLOOM_ADD(mask, p[0]);
+ /* process pattern[:0:-1] */
+ for (i = mlast; i > 0; i--) {
+ STRINGLIB_BLOOM_ADD(mask, p[i]);
+ if (p[i] == p[0])
+ skip = i - 1;
+ }
+
+ for (i = w; i >= 0; i--) {
+ if (s[i] == p[0]) {
+ /* candidate match */
+ for (j = mlast; j > 0; j--)
+ if (s[i+j] != p[j])
+ break;
+ if (j == 0)
+ /* got a match! */
+ return i;
+ /* miss: check if previous character is part of pattern */
+ if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+ i = i - m;
+ else
+ i = i - skip;
+ } else {
+ /* skip: check if previous character is part of pattern */
+ if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+ i = i - m;
+ }
+ }
+ }
+
+ if (mode != FAST_COUNT)
+ return -1;
+ return count;
+}
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/find.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/find.h
new file mode 100644
index 0000000000..a580e4bd2d
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/find.h
@@ -0,0 +1,175 @@
+/* stringlib: find/index implementation */
+
+#ifndef STRINGLIB_FIND_H
+#define STRINGLIB_FIND_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+ Py_ssize_t offset)
+{
+ Py_ssize_t pos;
+
+ if (str_len < 0)
+ return -1;
+ if (sub_len == 0)
+ return offset;
+
+ pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH);
+
+ if (pos >= 0)
+ pos += offset;
+
+ return pos;
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+ Py_ssize_t offset)
+{
+ Py_ssize_t pos;
+
+ if (str_len < 0)
+ return -1;
+ if (sub_len == 0)
+ return str_len + offset;
+
+ pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_RSEARCH);
+
+ if (pos >= 0)
+ pos += offset;
+
+ return pos;
+}
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ ADJUST_INDICES(start, end, str_len);
+ return stringlib_find(str + start, end - start, sub, sub_len, start);
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ ADJUST_INDICES(start, end, str_len);
+ return stringlib_rfind(str + start, end - start, sub, sub_len, start);
+}
+
+#ifdef STRINGLIB_WANT_CONTAINS_OBJ
+
+Py_LOCAL_INLINE(int)
+stringlib_contains_obj(PyObject* str, PyObject* sub)
+{
+ return stringlib_find(
+ STRINGLIB_STR(str), STRINGLIB_LEN(str),
+ STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
+ ) != -1;
+}
+
+#endif /* STRINGLIB_WANT_CONTAINS_OBJ */
+
+/*
+This function is a helper for the "find" family (find, rfind, index,
+rindex) and for count, startswith and endswith, because they all have
+the same behaviour for the arguments.
+
+It does not touch the variables received until it knows everything
+is ok.
+*/
+
+#define FORMAT_BUFFER_SIZE 50
+
+Py_LOCAL_INLINE(int)
+stringlib_parse_args_finds(const char * function_name, PyObject *args,
+ PyObject **subobj,
+ Py_ssize_t *start, Py_ssize_t *end)
+{
+ PyObject *tmp_subobj;
+ Py_ssize_t tmp_start = 0;
+ Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
+ PyObject *obj_start=Py_None, *obj_end=Py_None;
+ char format[FORMAT_BUFFER_SIZE] = "O|OO:";
+ size_t len = strlen(format);
+
+ strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);
+ format[FORMAT_BUFFER_SIZE - 1] = '\0';
+
+ if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end))
+ return 0;
+
+ /* To support None in "start" and "end" arguments, meaning
+ the same as if they were not passed.
+ */
+ if (obj_start != Py_None)
+ if (!_PyEval_SliceIndex(obj_start, &tmp_start))
+ return 0;
+ if (obj_end != Py_None)
+ if (!_PyEval_SliceIndex(obj_end, &tmp_end))
+ return 0;
+
+ *start = tmp_start;
+ *end = tmp_end;
+ *subobj = tmp_subobj;
+ return 1;
+}
+
+#undef FORMAT_BUFFER_SIZE
+
+#if STRINGLIB_IS_UNICODE
+
+/*
+Wraps stringlib_parse_args_finds() and additionally ensures that the
+first argument is a unicode object.
+
+Note that we receive a pointer to the pointer of the substring object,
+so when we create that object in this function we don't DECREF it,
+because it continues living in the caller functions (those functions,
+after finishing using the substring, must DECREF it).
+*/
+
+Py_LOCAL_INLINE(int)
+stringlib_parse_args_finds_unicode(const char * function_name, PyObject *args,
+ PyUnicodeObject **substring,
+ Py_ssize_t *start, Py_ssize_t *end)
+{
+ PyObject *tmp_substring;
+
+ if(stringlib_parse_args_finds(function_name, args, &tmp_substring,
+ start, end)) {
+ tmp_substring = PyUnicode_FromObject(tmp_substring);
+ if (!tmp_substring)
+ return 0;
+ *substring = (PyUnicodeObject *)tmp_substring;
+ return 1;
+ }
+ return 0;
+}
+
+#endif /* STRINGLIB_IS_UNICODE */
+
+#endif /* STRINGLIB_FIND_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/formatter.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/formatter.h
new file mode 100644
index 0000000000..f10a6a1665
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/formatter.h
@@ -0,0 +1,1539 @@
+/* implements the string, long, and float formatters. that is,
+ string.__format__, etc. */
+
+#include <locale.h>
+
+/* Before including this, you must include either:
+ stringlib/unicodedefs.h
+ stringlib/stringdefs.h
+
+ Also, you should define the names:
+ FORMAT_STRING
+ FORMAT_LONG
+ FORMAT_FLOAT
+ FORMAT_COMPLEX
+ to be whatever you want the public names of these functions to
+ be. These are the only non-static functions defined here.
+*/
+
+/* Raises an exception about an unknown presentation type for this
+ * type. */
+
+static void
+unknown_presentation_type(STRINGLIB_CHAR presentation_type,
+ const char* type_name)
+{
+#if STRINGLIB_IS_UNICODE
+ /* If STRINGLIB_CHAR is Py_UNICODE, %c might be out-of-range,
+ hence the two cases. If it is char, gcc complains that the
+ condition below is always true, hence the ifdef. */
+ if (presentation_type > 32 && presentation_type < 128)
+#endif
+ PyErr_Format(PyExc_ValueError,
+ "Unknown format code '%c' "
+ "for object of type '%.200s'",
+ (char)presentation_type,
+ type_name);
+#if STRINGLIB_IS_UNICODE
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Unknown format code '\\x%x' "
+ "for object of type '%.200s'",
+ (unsigned int)presentation_type,
+ type_name);
+#endif
+}
+
+static void
+invalid_comma_type(STRINGLIB_CHAR presentation_type)
+{
+#if STRINGLIB_IS_UNICODE
+ /* See comment in unknown_presentation_type */
+ if (presentation_type > 32 && presentation_type < 128)
+#endif
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify ',' with '%c'.",
+ (char)presentation_type);
+#if STRINGLIB_IS_UNICODE
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify ',' with '\\x%x'.",
+ (unsigned int)presentation_type);
+#endif
+}
+
+/*
+ get_integer consumes 0 or more decimal digit characters from an
+ input string, updates *result with the corresponding positive
+ integer, and returns the number of digits consumed.
+
+ returns -1 on error.
+*/
+static int
+get_integer(STRINGLIB_CHAR **ptr, STRINGLIB_CHAR *end,
+ Py_ssize_t *result)
+{
+ Py_ssize_t accumulator, digitval;
+ int numdigits;
+ accumulator = numdigits = 0;
+ for (;;(*ptr)++, numdigits++) {
+ if (*ptr >= end)
+ break;
+ digitval = STRINGLIB_TODECIMAL(**ptr);
+ if (digitval < 0)
+ break;
+ /*
+ Detect possible overflow before it happens:
+
+ accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
+ accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
+ */
+ if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
+ PyErr_Format(PyExc_ValueError,
+ "Too many decimal digits in format string");
+ return -1;
+ }
+ accumulator = accumulator * 10 + digitval;
+ }
+ *result = accumulator;
+ return numdigits;
+}
+
+/************************************************************************/
+/*********** standard format specifier parsing **************************/
+/************************************************************************/
+
+/* returns true if this character is a specifier alignment token */
+Py_LOCAL_INLINE(int)
+is_alignment_token(STRINGLIB_CHAR c)
+{
+ switch (c) {
+ case '<': case '>': case '=': case '^':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* returns true if this character is a sign element */
+Py_LOCAL_INLINE(int)
+is_sign_element(STRINGLIB_CHAR c)
+{
+ switch (c) {
+ case ' ': case '+': case '-':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+typedef struct {
+ STRINGLIB_CHAR fill_char;
+ STRINGLIB_CHAR align;
+ int alternate;
+ STRINGLIB_CHAR sign;
+ Py_ssize_t width;
+ int thousands_separators;
+ Py_ssize_t precision;
+ STRINGLIB_CHAR type;
+} InternalFormatSpec;
+
+
+#if 0
+/* Occassionally useful for debugging. Should normally be commented out. */
+static void
+DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
+{
+ printf("internal format spec: fill_char %d\n", format->fill_char);
+ printf("internal format spec: align %d\n", format->align);
+ printf("internal format spec: alternate %d\n", format->alternate);
+ printf("internal format spec: sign %d\n", format->sign);
+ printf("internal format spec: width %zd\n", format->width);
+ printf("internal format spec: thousands_separators %d\n",
+ format->thousands_separators);
+ printf("internal format spec: precision %zd\n", format->precision);
+ printf("internal format spec: type %c\n", format->type);
+ printf("\n");
+}
+#endif
+
+
+/*
+ ptr points to the start of the format_spec, end points just past its end.
+ fills in format with the parsed information.
+ returns 1 on success, 0 on failure.
+ if failure, sets the exception
+*/
+static int
+parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len,
+ InternalFormatSpec *format,
+ char default_type,
+ char default_align)
+{
+ STRINGLIB_CHAR *ptr = format_spec;
+ STRINGLIB_CHAR *end = format_spec + format_spec_len;
+
+ /* end-ptr is used throughout this code to specify the length of
+ the input string */
+
+ Py_ssize_t consumed;
+ int align_specified = 0;
+ int fill_char_specified = 0;
+
+ format->fill_char = ' ';
+ format->align = default_align;
+ format->alternate = 0;
+ format->sign = '\0';
+ format->width = -1;
+ format->thousands_separators = 0;
+ format->precision = -1;
+ format->type = default_type;
+
+ /* If the second char is an alignment token,
+ then parse the fill char */
+ if (end-ptr >= 2 && is_alignment_token(ptr[1])) {
+ format->align = ptr[1];
+ format->fill_char = ptr[0];
+ fill_char_specified = 1;
+ align_specified = 1;
+ ptr += 2;
+ }
+ else if (end-ptr >= 1 && is_alignment_token(ptr[0])) {
+ format->align = ptr[0];
+ align_specified = 1;
+ ++ptr;
+ }
+
+ /* Parse the various sign options */
+ if (end-ptr >= 1 && is_sign_element(ptr[0])) {
+ format->sign = ptr[0];
+ ++ptr;
+ }
+
+ /* If the next character is #, we're in alternate mode. This only
+ applies to integers. */
+ if (end-ptr >= 1 && ptr[0] == '#') {
+ format->alternate = 1;
+ ++ptr;
+ }
+
+ /* The special case for 0-padding (backwards compat) */
+ if (!fill_char_specified && end-ptr >= 1 && ptr[0] == '0') {
+ format->fill_char = '0';
+ if (!align_specified) {
+ format->align = '=';
+ }
+ ++ptr;
+ }
+
+ consumed = get_integer(&ptr, end, &format->width);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
+
+ /* If consumed is 0, we didn't consume any characters for the
+ width. In that case, reset the width to -1, because
+ get_integer() will have set it to zero. -1 is how we record
+ that the width wasn't specified. */
+ if (consumed == 0)
+ format->width = -1;
+
+ /* Comma signifies add thousands separators */
+ if (end-ptr && ptr[0] == ',') {
+ format->thousands_separators = 1;
+ ++ptr;
+ }
+
+ /* Parse field precision */
+ if (end-ptr && ptr[0] == '.') {
+ ++ptr;
+
+ consumed = get_integer(&ptr, end, &format->precision);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
+
+ /* Not having a precision after a dot is an error. */
+ if (consumed == 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Format specifier missing precision");
+ return 0;
+ }
+
+ }
+
+ /* Finally, parse the type field. */
+
+ if (end-ptr > 1) {
+ /* More than one char remain, invalid conversion spec. */
+ PyErr_Format(PyExc_ValueError, "Invalid conversion specification");
+ return 0;
+ }
+
+ if (end-ptr == 1) {
+ format->type = ptr[0];
+ ++ptr;
+ }
+
+ /* Do as much validating as we can, just by looking at the format
+ specifier. Do not take into account what type of formatting
+ we're doing (int, float, string). */
+
+ if (format->thousands_separators) {
+ switch (format->type) {
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'E':
+ case 'G':
+ case '%':
+ case 'F':
+ case '\0':
+ /* These are allowed. See PEP 378.*/
+ break;
+ default:
+ invalid_comma_type(format->type);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/* Calculate the padding needed. */
+static void
+calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align,
+ Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
+ Py_ssize_t *n_total)
+{
+ if (width >= 0) {
+ if (nchars > width)
+ *n_total = nchars;
+ else
+ *n_total = width;
+ }
+ else {
+ /* not specified, use all of the chars and no more */
+ *n_total = nchars;
+ }
+
+ /* Figure out how much leading space we need, based on the
+ aligning */
+ if (align == '>')
+ *n_lpadding = *n_total - nchars;
+ else if (align == '^')
+ *n_lpadding = (*n_total - nchars) / 2;
+ else if (align == '<' || align == '=')
+ *n_lpadding = 0;
+ else {
+ /* We should never have an unspecified alignment. */
+ *n_lpadding = 0;
+ assert(0);
+ }
+
+ *n_rpadding = *n_total - nchars - *n_lpadding;
+}
+
+/* Do the padding, and return a pointer to where the caller-supplied
+ content goes. */
+static STRINGLIB_CHAR *
+fill_padding(STRINGLIB_CHAR *p, Py_ssize_t nchars, STRINGLIB_CHAR fill_char,
+ Py_ssize_t n_lpadding, Py_ssize_t n_rpadding)
+{
+ /* Pad on left. */
+ if (n_lpadding)
+ STRINGLIB_FILL(p, fill_char, n_lpadding);
+
+ /* Pad on right. */
+ if (n_rpadding)
+ STRINGLIB_FILL(p + nchars + n_lpadding, fill_char, n_rpadding);
+
+ /* Pointer to the user content. */
+ return p + n_lpadding;
+}
+
+#if defined FORMAT_FLOAT || defined FORMAT_LONG || defined FORMAT_COMPLEX
+/************************************************************************/
+/*********** common routines for numeric formatting *********************/
+/************************************************************************/
+
+/* Locale type codes. */
+#define LT_CURRENT_LOCALE 0
+#define LT_DEFAULT_LOCALE 1
+#define LT_NO_LOCALE 2
+
+/* Locale info needed for formatting integers and the part of floats
+ before and including the decimal. Note that locales only support
+ 8-bit chars, not unicode. */
+typedef struct {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+} LocaleInfo;
+
+/* describes the layout for an integer, see the comment in
+ calc_number_widths() for details */
+typedef struct {
+ Py_ssize_t n_lpadding;
+ Py_ssize_t n_prefix;
+ Py_ssize_t n_spadding;
+ Py_ssize_t n_rpadding;
+ char sign;
+ Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */
+ Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
+ any grouping chars. */
+ Py_ssize_t n_decimal; /* 0 if only an integer */
+ Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
+ excluding the decimal itself, if
+ present. */
+
+ /* These 2 are not the widths of fields, but are needed by
+ STRINGLIB_GROUPING. */
+ Py_ssize_t n_digits; /* The number of digits before a decimal
+ or exponent. */
+ Py_ssize_t n_min_width; /* The min_width we used when we computed
+ the n_grouped_digits width. */
+} NumberFieldWidths;
+
+
+/* Given a number of the form:
+ digits[remainder]
+ where ptr points to the start and end points to the end, find where
+ the integer part ends. This could be a decimal, an exponent, both,
+ or neither.
+ If a decimal point is present, set *has_decimal and increment
+ remainder beyond it.
+ Results are undefined (but shouldn't crash) for improperly
+ formatted strings.
+*/
+static void
+parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len,
+ Py_ssize_t *n_remainder, int *has_decimal)
+{
+ STRINGLIB_CHAR *end = ptr + len;
+ STRINGLIB_CHAR *remainder;
+
+ while (ptr<end && isdigit(*ptr))
+ ++ptr;
+ remainder = ptr;
+
+ /* Does remainder start with a decimal point? */
+ *has_decimal = ptr<end && *remainder == '.';
+
+ /* Skip the decimal point. */
+ if (*has_decimal)
+ remainder++;
+
+ *n_remainder = end - remainder;
+}
+
+/* not all fields of format are used. for example, precision is
+ unused. should this take discrete params in order to be more clear
+ about what it does? or is passing a single format parameter easier
+ and more efficient enough to justify a little obfuscation? */
+static Py_ssize_t
+calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
+ STRINGLIB_CHAR sign_char, STRINGLIB_CHAR *number,
+ Py_ssize_t n_number, Py_ssize_t n_remainder,
+ int has_decimal, const LocaleInfo *locale,
+ const InternalFormatSpec *format)
+{
+ Py_ssize_t n_non_digit_non_padding;
+ Py_ssize_t n_padding;
+
+ spec->n_digits = n_number - n_remainder - (has_decimal?1:0);
+ spec->n_lpadding = 0;
+ spec->n_prefix = n_prefix;
+ spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0;
+ spec->n_remainder = n_remainder;
+ spec->n_spadding = 0;
+ spec->n_rpadding = 0;
+ spec->sign = '\0';
+ spec->n_sign = 0;
+
+ /* the output will look like:
+ | |
+ | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
+ | |
+
+ sign is computed from format->sign and the actual
+ sign of the number
+
+ prefix is given (it's for the '0x' prefix)
+
+ digits is already known
+
+ the total width is either given, or computed from the
+ actual digits
+
+ only one of lpadding, spadding, and rpadding can be non-zero,
+ and it's calculated from the width and other fields
+ */
+
+ /* compute the various parts we're going to write */
+ switch (format->sign) {
+ case '+':
+ /* always put a + or - */
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : '+');
+ break;
+ case ' ':
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : ' ');
+ break;
+ default:
+ /* Not specified, or the default (-) */
+ if (sign_char == '-') {
+ spec->n_sign = 1;
+ spec->sign = '-';
+ }
+ }
+
+ /* The number of chars used for non-digits and non-padding. */
+ n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
+ spec->n_remainder;
+
+ /* min_width can go negative, that's okay. format->width == -1 means
+ we don't care. */
+ if (format->fill_char == '0' && format->align == '=')
+ spec->n_min_width = format->width - n_non_digit_non_padding;
+ else
+ spec->n_min_width = 0;
+
+ if (spec->n_digits == 0)
+ /* This case only occurs when using 'c' formatting, we need
+ to special case it because the grouping code always wants
+ to have at least one character. */
+ spec->n_grouped_digits = 0;
+ else
+ spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL,
+ spec->n_digits,
+ spec->n_min_width,
+ locale->grouping,
+ locale->thousands_sep);
+
+ /* Given the desired width and the total of digit and non-digit
+ space we consume, see if we need any padding. format->width can
+ be negative (meaning no padding), but this code still works in
+ that case. */
+ n_padding = format->width -
+ (n_non_digit_non_padding + spec->n_grouped_digits);
+ if (n_padding > 0) {
+ /* Some padding is needed. Determine if it's left, space, or right. */
+ switch (format->align) {
+ case '<':
+ spec->n_rpadding = n_padding;
+ break;
+ case '^':
+ spec->n_lpadding = n_padding / 2;
+ spec->n_rpadding = n_padding - spec->n_lpadding;
+ break;
+ case '=':
+ spec->n_spadding = n_padding;
+ break;
+ case '>':
+ spec->n_lpadding = n_padding;
+ break;
+ default:
+ /* Shouldn't get here, but treat it as '>' */
+ spec->n_lpadding = n_padding;
+ assert(0);
+ break;
+ }
+ }
+ return spec->n_lpadding + spec->n_sign + spec->n_prefix +
+ spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
+ spec->n_remainder + spec->n_rpadding;
+}
+
+/* Fill in the digit parts of a numbers's string representation,
+ as determined in calc_number_widths().
+ No error checking, since we know the buffer is the correct size. */
+static void
+fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec,
+ STRINGLIB_CHAR *digits, Py_ssize_t n_digits,
+ STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char,
+ LocaleInfo *locale, int toupper)
+{
+ /* Used to keep track of digits, decimal, and remainder. */
+ STRINGLIB_CHAR *p = digits;
+
+#ifndef NDEBUG
+ Py_ssize_t r;
+#endif
+
+ if (spec->n_lpadding) {
+ STRINGLIB_FILL(buf, fill_char, spec->n_lpadding);
+ buf += spec->n_lpadding;
+ }
+ if (spec->n_sign == 1) {
+ *buf++ = spec->sign;
+ }
+ if (spec->n_prefix) {
+ memmove(buf,
+ prefix,
+ spec->n_prefix * sizeof(STRINGLIB_CHAR));
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_prefix; ++t)
+ buf[t] = STRINGLIB_TOUPPER(buf[t]);
+ }
+ buf += spec->n_prefix;
+ }
+ if (spec->n_spadding) {
+ STRINGLIB_FILL(buf, fill_char, spec->n_spadding);
+ buf += spec->n_spadding;
+ }
+
+ /* Only for type 'c' special case, it has no digits. */
+ if (spec->n_digits != 0) {
+ /* Fill the digits with InsertThousandsGrouping. */
+#ifndef NDEBUG
+ r =
+#endif
+ STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits,
+ spec->n_digits, spec->n_min_width,
+ locale->grouping, locale->thousands_sep);
+#ifndef NDEBUG
+ assert(r == spec->n_grouped_digits);
+#endif
+ p += spec->n_digits;
+ }
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_grouped_digits; ++t)
+ buf[t] = STRINGLIB_TOUPPER(buf[t]);
+ }
+ buf += spec->n_grouped_digits;
+
+ if (spec->n_decimal) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_decimal; ++t)
+ buf[t] = locale->decimal_point[t];
+ buf += spec->n_decimal;
+ p += 1;
+ }
+
+ if (spec->n_remainder) {
+ memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR));
+ buf += spec->n_remainder;
+ p += spec->n_remainder;
+ }
+
+ if (spec->n_rpadding) {
+ STRINGLIB_FILL(buf, fill_char, spec->n_rpadding);
+ buf += spec->n_rpadding;
+ }
+}
+
+static char no_grouping[1] = {CHAR_MAX};
+
+/* Find the decimal point character(s?), thousands_separator(s?), and
+ grouping description, either for the current locale if type is
+ LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
+ none if LT_NO_LOCALE. */
+static void
+get_locale_info(int type, LocaleInfo *locale_info)
+{
+ switch (type) {
+ case LT_CURRENT_LOCALE: {
+ struct lconv *locale_data = localeconv();
+ locale_info->decimal_point = locale_data->decimal_point;
+ locale_info->thousands_sep = locale_data->thousands_sep;
+ locale_info->grouping = locale_data->grouping;
+ break;
+ }
+ case LT_DEFAULT_LOCALE:
+ locale_info->decimal_point = ".";
+ locale_info->thousands_sep = ",";
+ locale_info->grouping = "\3"; /* Group every 3 characters. The
+ (implicit) trailing 0 means repeat
+ infinitely. */
+ break;
+ case LT_NO_LOCALE:
+ locale_info->decimal_point = ".";
+ locale_info->thousands_sep = "";
+ locale_info->grouping = no_grouping;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+#endif /* FORMAT_FLOAT || FORMAT_LONG || FORMAT_COMPLEX */
+
+/************************************************************************/
+/*********** string formatting ******************************************/
+/************************************************************************/
+
+static PyObject *
+format_string_internal(PyObject *value, const InternalFormatSpec *format)
+{
+ Py_ssize_t lpad;
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+ STRINGLIB_CHAR *p;
+ Py_ssize_t len = STRINGLIB_LEN(value);
+ PyObject *result = NULL;
+
+ /* sign is not allowed on strings */
+ if (format->sign != '\0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Sign not allowed in string format specifier");
+ goto done;
+ }
+
+ /* alternate is not allowed on strings */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed in string format "
+ "specifier");
+ goto done;
+ }
+
+ /* '=' alignment not allowed on strings */
+ if (format->align == '=') {
+ PyErr_SetString(PyExc_ValueError,
+ "'=' alignment not allowed "
+ "in string format specifier");
+ goto done;
+ }
+
+ /* if precision is specified, output no more that format.precision
+ characters */
+ if (format->precision >= 0 && len >= format->precision) {
+ len = format->precision;
+ }
+
+ calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
+
+ /* allocate the resulting string */
+ result = STRINGLIB_NEW(NULL, total);
+ if (result == NULL)
+ goto done;
+
+ /* Write into that space. First the padding. */
+ p = fill_padding(STRINGLIB_STR(result), len,
+ format->fill_char, lpad, rpad);
+
+ /* Then the source string. */
+ memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR));
+
+done:
+ return result;
+}
+
+
+/************************************************************************/
+/*********** long formatting ********************************************/
+/************************************************************************/
+
+#if defined FORMAT_LONG || defined FORMAT_INT
+typedef PyObject*
+(*IntOrLongToString)(PyObject *value, int base);
+
+static PyObject *
+format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
+ IntOrLongToString tostring)
+{
+ PyObject *result = NULL;
+ PyObject *tmp = NULL;
+ STRINGLIB_CHAR *pnumeric_chars;
+ STRINGLIB_CHAR numeric_char;
+ STRINGLIB_CHAR sign_char = '\0';
+ Py_ssize_t n_digits; /* count of digits need from the computed
+ string */
+ Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
+ produces non-digits */
+ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
+ Py_ssize_t n_total;
+ STRINGLIB_CHAR *prefix = NULL;
+ NumberFieldWidths spec;
+ long x;
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale;
+
+ /* no precision allowed on integers */
+ if (format->precision != -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Precision not allowed in integer format specifier");
+ goto done;
+ }
+
+ /* special case for character formatting */
+ if (format->type == 'c') {
+ /* error to specify a sign */
+ if (format->sign != '\0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Sign not allowed with integer"
+ " format specifier 'c'");
+ goto done;
+ }
+
+ /* Error to specify a comma. */
+ if (format->thousands_separators) {
+ PyErr_SetString(PyExc_ValueError,
+ "Thousands separators not allowed with integer"
+ " format specifier 'c'");
+ goto done;
+ }
+
+ /* taken from unicodeobject.c formatchar() */
+ /* Integer input truncated to a character */
+/* XXX: won't work for int */
+ x = PyLong_AsLong(value);
+ if (x == -1 && PyErr_Occurred())
+ goto done;
+#ifdef Py_UNICODE_WIDE
+ if (x < 0 || x > 0x10ffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x110000) "
+ "(wide Python build)");
+ goto done;
+ }
+#else
+ if (x < 0 || x > 0xffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x10000) "
+ "(narrow Python build)");
+ goto done;
+ }
+#endif
+ numeric_char = (STRINGLIB_CHAR)x;
+ pnumeric_chars = &numeric_char;
+ n_digits = 1;
+
+ /* As a sort-of hack, we tell calc_number_widths that we only
+ have "remainder" characters. calc_number_widths thinks
+ these are characters that don't get formatted, only copied
+ into the output string. We do this for 'c' formatting,
+ because the characters are likely to be non-digits. */
+ n_remainder = 1;
+ }
+ else {
+ int base;
+ int leading_chars_to_skip = 0; /* Number of characters added by
+ PyNumber_ToBase that we want to
+ skip over. */
+
+ /* Compute the base and how many characters will be added by
+ PyNumber_ToBase */
+ switch (format->type) {
+ case 'b':
+ base = 2;
+ leading_chars_to_skip = 2; /* 0b */
+ break;
+ case 'o':
+ base = 8;
+ leading_chars_to_skip = 2; /* 0o */
+ break;
+ case 'x':
+ case 'X':
+ base = 16;
+ leading_chars_to_skip = 2; /* 0x */
+ break;
+ default: /* shouldn't be needed, but stops a compiler warning */
+ case 'd':
+ case 'n':
+ base = 10;
+ break;
+ }
+
+ /* The number of prefix chars is the same as the leading
+ chars to skip */
+ if (format->alternate)
+ n_prefix = leading_chars_to_skip;
+
+ /* Do the hard part, converting to a string in a given base */
+ tmp = tostring(value, base);
+ if (tmp == NULL)
+ goto done;
+
+ pnumeric_chars = STRINGLIB_STR(tmp);
+ n_digits = STRINGLIB_LEN(tmp);
+
+ prefix = pnumeric_chars;
+
+ /* Remember not to modify what pnumeric_chars points to. it
+ might be interned. Only modify it after we copy it into a
+ newly allocated output buffer. */
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (pnumeric_chars[0] == '-') {
+ sign_char = pnumeric_chars[0];
+ ++prefix;
+ ++leading_chars_to_skip;
+ }
+
+ /* Skip over the leading chars (0x, 0b, etc.) */
+ n_digits -= leading_chars_to_skip;
+ pnumeric_chars += leading_chars_to_skip;
+ }
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
+
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars,
+ n_digits, n_remainder, 0, &locale, format);
+
+ /* Allocate the memory. */
+ result = STRINGLIB_NEW(NULL, n_total);
+ if (!result)
+ goto done;
+
+ /* Populate the memory. */
+ fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits,
+ prefix, format->fill_char, &locale, format->type == 'X');
+
+done:
+ Py_XDECREF(tmp);
+ return result;
+}
+#endif /* defined FORMAT_LONG || defined FORMAT_INT */
+
+/************************************************************************/
+/*********** float formatting *******************************************/
+/************************************************************************/
+
+#ifdef FORMAT_FLOAT
+#if STRINGLIB_IS_UNICODE
+static void
+strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len)
+{
+ Py_ssize_t i;
+ for (i = 0; i < len; ++i)
+ buffer[i] = (Py_UNICODE)charbuffer[i];
+}
+#endif
+
+/* much of this is taken from unicodeobject.c */
+static PyObject *
+format_float_internal(PyObject *value,
+ const InternalFormatSpec *format)
+{
+ char *buf = NULL; /* buffer returned from PyOS_double_to_string */
+ Py_ssize_t n_digits;
+ Py_ssize_t n_remainder;
+ Py_ssize_t n_total;
+ int has_decimal;
+ double val;
+ Py_ssize_t precision;
+ Py_ssize_t default_precision = 6;
+ STRINGLIB_CHAR type = format->type;
+ int add_pct = 0;
+ STRINGLIB_CHAR *p;
+ NumberFieldWidths spec;
+ int flags = 0;
+ PyObject *result = NULL;
+ STRINGLIB_CHAR sign_char = '\0';
+ int float_type; /* Used to see if we have a nan, inf, or regular float. */
+
+#if STRINGLIB_IS_UNICODE
+ Py_UNICODE *unicode_tmp = NULL;
+#endif
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale;
+
+ if (format->precision > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "precision too big");
+ goto done;
+ }
+ precision = (int)format->precision;
+
+ /* Alternate is not allowed on floats. */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed in float format "
+ "specifier");
+ goto done;
+ }
+
+ if (type == '\0') {
+ /* Omitted type specifier. This is like 'g' but with at least one
+ digit after the decimal point, and different default precision.*/
+ type = 'g';
+ default_precision = PyFloat_STR_PRECISION;
+ flags |= Py_DTSF_ADD_DOT_0;
+ }
+
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
+
+ val = PyFloat_AsDouble(value);
+ if (val == -1.0 && PyErr_Occurred())
+ goto done;
+
+ if (type == '%') {
+ type = 'f';
+ val *= 100;
+ add_pct = 1;
+ }
+
+ if (precision < 0)
+ precision = default_precision;
+
+ /* Cast "type", because if we're in unicode we need to pass a
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ buf = PyOS_double_to_string(val, (char)type, precision, flags,
+ &float_type);
+ if (buf == NULL)
+ goto done;
+ n_digits = strlen(buf);
+
+ if (add_pct) {
+ /* We know that buf has a trailing zero (since we just called
+ strlen() on it), and we don't use that fact any more. So we
+ can just write over the trailing zero. */
+ buf[n_digits] = '%';
+ n_digits += 1;
+ }
+
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
+#if STRINGLIB_IS_UNICODE
+ unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE));
+ if (unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(unicode_tmp, buf, n_digits);
+ p = unicode_tmp;
+#else
+ p = buf;
+#endif
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (*p == '-') {
+ sign_char = *p;
+ ++p;
+ --n_digits;
+ }
+
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(p, n_digits, &n_remainder, &has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
+
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits,
+ n_remainder, has_decimal, &locale, format);
+
+ /* Allocate the memory. */
+ result = STRINGLIB_NEW(NULL, n_total);
+ if (result == NULL)
+ goto done;
+
+ /* Populate the memory. */
+ fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL,
+ format->fill_char, &locale, 0);
+
+done:
+ PyMem_Free(buf);
+#if STRINGLIB_IS_UNICODE
+ PyMem_Free(unicode_tmp);
+#endif
+ return result;
+}
+#endif /* FORMAT_FLOAT */
+
+/************************************************************************/
+/*********** complex formatting *****************************************/
+/************************************************************************/
+
+#ifdef FORMAT_COMPLEX
+
+static PyObject *
+format_complex_internal(PyObject *value,
+ const InternalFormatSpec *format)
+{
+ double re;
+ double im;
+ char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */
+ char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */
+
+ InternalFormatSpec tmp_format = *format;
+ Py_ssize_t n_re_digits;
+ Py_ssize_t n_im_digits;
+ Py_ssize_t n_re_remainder;
+ Py_ssize_t n_im_remainder;
+ Py_ssize_t n_re_total;
+ Py_ssize_t n_im_total;
+ int re_has_decimal;
+ int im_has_decimal;
+ Py_ssize_t precision;
+ Py_ssize_t default_precision = 6;
+ STRINGLIB_CHAR type = format->type;
+ STRINGLIB_CHAR *p_re;
+ STRINGLIB_CHAR *p_im;
+ NumberFieldWidths re_spec;
+ NumberFieldWidths im_spec;
+ int flags = 0;
+ PyObject *result = NULL;
+ STRINGLIB_CHAR *p;
+ STRINGLIB_CHAR re_sign_char = '\0';
+ STRINGLIB_CHAR im_sign_char = '\0';
+ int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
+ int im_float_type;
+ int add_parens = 0;
+ int skip_re = 0;
+ Py_ssize_t lpad;
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+
+#if STRINGLIB_IS_UNICODE
+ Py_UNICODE *re_unicode_tmp = NULL;
+ Py_UNICODE *im_unicode_tmp = NULL;
+#endif
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale;
+
+ if (format->precision > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "precision too big");
+ goto done;
+ }
+ precision = (int)format->precision;
+
+ /* Alternate is not allowed on complex. */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ /* Neither is zero pading. */
+ if (format->fill_char == '0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Zero padding is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ /* Neither is '=' alignment . */
+ if (format->align == '=') {
+ PyErr_SetString(PyExc_ValueError,
+ "'=' alignment flag is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ re = PyComplex_RealAsDouble(value);
+ if (re == -1.0 && PyErr_Occurred())
+ goto done;
+ im = PyComplex_ImagAsDouble(value);
+ if (im == -1.0 && PyErr_Occurred())
+ goto done;
+
+ if (type == '\0') {
+ /* Omitted type specifier. Should be like str(self). */
+ type = 'g';
+ default_precision = PyFloat_STR_PRECISION;
+ if (re == 0.0 && copysign(1.0, re) == 1.0)
+ skip_re = 1;
+ else
+ add_parens = 1;
+ }
+
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
+
+ if (precision < 0)
+ precision = default_precision;
+
+ /* Cast "type", because if we're in unicode we need to pass a
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
+ &re_float_type);
+ if (re_buf == NULL)
+ goto done;
+ im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
+ &im_float_type);
+ if (im_buf == NULL)
+ goto done;
+
+ n_re_digits = strlen(re_buf);
+ n_im_digits = strlen(im_buf);
+
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
+#if STRINGLIB_IS_UNICODE
+ re_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_re_digits)*sizeof(Py_UNICODE));
+ if (re_unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(re_unicode_tmp, re_buf, n_re_digits);
+ p_re = re_unicode_tmp;
+
+ im_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_im_digits)*sizeof(Py_UNICODE));
+ if (im_unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(im_unicode_tmp, im_buf, n_im_digits);
+ p_im = im_unicode_tmp;
+#else
+ p_re = re_buf;
+ p_im = im_buf;
+#endif
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (*p_re == '-') {
+ re_sign_char = *p_re;
+ ++p_re;
+ --n_re_digits;
+ }
+ if (*p_im == '-') {
+ im_sign_char = *p_im;
+ ++p_im;
+ --n_im_digits;
+ }
+
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(p_re, n_re_digits, &n_re_remainder, &re_has_decimal);
+ parse_number(p_im, n_im_digits, &n_im_remainder, &im_has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
+
+ /* Turn off any padding. We'll do it later after we've composed
+ the numbers without padding. */
+ tmp_format.fill_char = '\0';
+ tmp_format.align = '<';
+ tmp_format.width = -1;
+
+ /* Calculate how much memory we'll need. */
+ n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, p_re,
+ n_re_digits, n_re_remainder,
+ re_has_decimal, &locale, &tmp_format);
+
+ /* Same formatting, but always include a sign, unless the real part is
+ * going to be omitted, in which case we use whatever sign convention was
+ * requested by the original format. */
+ if (!skip_re)
+ tmp_format.sign = '+';
+ n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im,
+ n_im_digits, n_im_remainder,
+ im_has_decimal, &locale, &tmp_format);
+
+ if (skip_re)
+ n_re_total = 0;
+
+ /* Add 1 for the 'j', and optionally 2 for parens. */
+ calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
+ format->width, format->align, &lpad, &rpad, &total);
+
+ result = STRINGLIB_NEW(NULL, total);
+ if (result == NULL)
+ goto done;
+
+ /* Populate the memory. First, the padding. */
+ p = fill_padding(STRINGLIB_STR(result),
+ n_re_total + n_im_total + 1 + add_parens * 2,
+ format->fill_char, lpad, rpad);
+
+ if (add_parens)
+ *p++ = '(';
+
+ if (!skip_re) {
+ fill_number(p, &re_spec, p_re, n_re_digits, NULL, 0, &locale, 0);
+ p += n_re_total;
+ }
+ fill_number(p, &im_spec, p_im, n_im_digits, NULL, 0, &locale, 0);
+ p += n_im_total;
+ *p++ = 'j';
+
+ if (add_parens)
+ *p++ = ')';
+
+done:
+ PyMem_Free(re_buf);
+ PyMem_Free(im_buf);
+#if STRINGLIB_IS_UNICODE
+ PyMem_Free(re_unicode_tmp);
+ PyMem_Free(im_unicode_tmp);
+#endif
+ return result;
+}
+#endif /* FORMAT_COMPLEX */
+
+/************************************************************************/
+/*********** built in formatters ****************************************/
+/************************************************************************/
+PyObject *
+FORMAT_STRING(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ InternalFormatSpec format;
+ PyObject *result = NULL;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (format_spec_len == 0) {
+ result = STRINGLIB_TOSTR(obj);
+ goto done;
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec, format_spec_len,
+ &format, 's', '<'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case 's':
+ /* no type conversion needed, already a string. do the formatting */
+ result = format_string_internal(obj, &format);
+ break;
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, obj->ob_type->tp_name);
+ goto done;
+ }
+
+done:
+ return result;
+}
+
+#if defined FORMAT_LONG || defined FORMAT_INT
+static PyObject*
+format_int_or_long(PyObject* obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len,
+ IntOrLongToString tostring)
+{
+ PyObject *result = NULL;
+ PyObject *tmp = NULL;
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (format_spec_len == 0) {
+ result = STRINGLIB_TOSTR(obj);
+ goto done;
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec,
+ format_spec_len,
+ &format, 'd', '>'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'n':
+ /* no type conversion needed, already an int (or long). do
+ the formatting */
+ result = format_int_or_long_internal(obj, &format, tostring);
+ break;
+
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case '%':
+ /* convert to float */
+ tmp = PyNumber_Float(obj);
+ if (tmp == NULL)
+ goto done;
+ result = format_float_internal(tmp, &format);
+ break;
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, obj->ob_type->tp_name);
+ goto done;
+ }
+
+done:
+ Py_XDECREF(tmp);
+ return result;
+}
+#endif /* FORMAT_LONG || defined FORMAT_INT */
+
+#ifdef FORMAT_LONG
+/* Need to define long_format as a function that will convert a long
+ to a string. In 3.0, _PyLong_Format has the correct signature. In
+ 2.x, we need to fudge a few parameters */
+#if PY_VERSION_HEX >= 0x03000000
+#define long_format _PyLong_Format
+#else
+static PyObject*
+long_format(PyObject* value, int base)
+{
+ /* Convert to base, don't add trailing 'L', and use the new octal
+ format. We already know this is a long object */
+ assert(PyLong_Check(value));
+ /* convert to base, don't add 'L', and use the new octal format */
+ return _PyLong_Format(value, base, 0, 1);
+}
+#endif
+
+PyObject *
+FORMAT_LONG(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ return format_int_or_long(obj, format_spec, format_spec_len,
+ long_format);
+}
+#endif /* FORMAT_LONG */
+
+#ifdef FORMAT_INT
+/* this is only used for 2.x, not 3.0 */
+static PyObject*
+int_format(PyObject* value, int base)
+{
+ /* Convert to base, and use the new octal format. We already
+ know this is an int object */
+ assert(PyInt_Check(value));
+ return _PyInt_Format((PyIntObject*)value, base, 1);
+}
+
+PyObject *
+FORMAT_INT(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ return format_int_or_long(obj, format_spec, format_spec_len,
+ int_format);
+}
+#endif /* FORMAT_INT */
+
+#ifdef FORMAT_FLOAT
+PyObject *
+FORMAT_FLOAT(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ PyObject *result = NULL;
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (format_spec_len == 0) {
+ result = STRINGLIB_TOSTR(obj);
+ goto done;
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec,
+ format_spec_len,
+ &format, '\0', '>'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'n':
+ case '%':
+ /* no conversion, already a float. do the formatting */
+ result = format_float_internal(obj, &format);
+ break;
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, obj->ob_type->tp_name);
+ goto done;
+ }
+
+done:
+ return result;
+}
+#endif /* FORMAT_FLOAT */
+
+#ifdef FORMAT_COMPLEX
+PyObject *
+FORMAT_COMPLEX(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ PyObject *result = NULL;
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (format_spec_len == 0) {
+ result = STRINGLIB_TOSTR(obj);
+ goto done;
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec,
+ format_spec_len,
+ &format, '\0', '>'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'n':
+ /* no conversion, already a complex. do the formatting */
+ result = format_complex_internal(obj, &format);
+ break;
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, obj->ob_type->tp_name);
+ goto done;
+ }
+
+done:
+ return result;
+}
+#endif /* FORMAT_COMPLEX */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/partition.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/partition.h
new file mode 100644
index 0000000000..fc076405be
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/partition.h
@@ -0,0 +1,110 @@
+/* stringlib: partition implementation */
+
+#ifndef STRINGLIB_PARTITION_H
+#define STRINGLIB_PARTITION_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_partition(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ PyObject* sep_obj,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
+{
+ PyObject* out;
+ Py_ssize_t pos;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+
+ out = PyTuple_New(3);
+ if (!out)
+ return NULL;
+
+ pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH);
+
+ if (pos < 0) {
+#if STRINGLIB_MUTABLE
+ PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
+ PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
+ PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
+#else
+ Py_INCREF(str_obj);
+ PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
+ Py_INCREF(STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+ Py_INCREF(STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
+#endif
+ return out;
+ }
+
+ PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+ Py_INCREF(sep_obj);
+ PyTuple_SET_ITEM(out, 1, sep_obj);
+ pos += sep_len;
+ PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(out);
+ return NULL;
+ }
+
+ return out;
+}
+
+Py_LOCAL_INLINE(PyObject*)
+stringlib_rpartition(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ PyObject* sep_obj,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
+{
+ PyObject* out;
+ Py_ssize_t pos;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+
+ out = PyTuple_New(3);
+ if (!out)
+ return NULL;
+
+ pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
+
+ if (pos < 0) {
+#if STRINGLIB_MUTABLE
+ PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
+ PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
+ PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
+#else
+ Py_INCREF(STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
+ Py_INCREF(STRINGLIB_EMPTY);
+ PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
+ Py_INCREF(str_obj);
+ PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
+#endif
+ return out;
+ }
+
+ PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
+ Py_INCREF(sep_obj);
+ PyTuple_SET_ITEM(out, 1, sep_obj);
+ pos += sep_len;
+ PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(out);
+ return NULL;
+ }
+
+ return out;
+}
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/split.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/split.h
new file mode 100644
index 0000000000..13eb93eb53
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/split.h
@@ -0,0 +1,394 @@
+/* stringlib: split implementation */
+
+#ifndef STRINGLIB_SPLIT_H
+#define STRINGLIB_SPLIT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+/* Overallocate the initial list to reduce the number of reallocs for small
+ split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
+ resizes, to sizes 4, 8, then 16. Most observed string splits are for human
+ text (roughly 11 words per line) and field delimited data (usually 1-10
+ fields). For large strings the split algorithms are bandwidth limited
+ so increasing the preallocation likely will not improve things.*/
+
+#define MAX_PREALLOC 12
+
+/* 5 splits gives 6 elements */
+#define PREALLOC_SIZE(maxsplit) \
+ (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
+
+#define SPLIT_APPEND(data, left, right) \
+ sub = STRINGLIB_NEW((data) + (left), \
+ (right) - (left)); \
+ if (sub == NULL) \
+ goto onError; \
+ if (PyList_Append(list, sub)) { \
+ Py_DECREF(sub); \
+ goto onError; \
+ } \
+ else \
+ Py_DECREF(sub);
+
+#define SPLIT_ADD(data, left, right) { \
+ sub = STRINGLIB_NEW((data) + (left), \
+ (right) - (left)); \
+ if (sub == NULL) \
+ goto onError; \
+ if (count < MAX_PREALLOC) { \
+ PyList_SET_ITEM(list, count, sub); \
+ } else { \
+ if (PyList_Append(list, sub)) { \
+ Py_DECREF(sub); \
+ goto onError; \
+ } \
+ else \
+ Py_DECREF(sub); \
+ } \
+ count++; }
+
+
+/* Always force the list to the expected size. */
+#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_whitespace(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while (maxcount-- > 0) {
+ while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+ i++;
+ if (i == str_len) break;
+ j = i; i++;
+ while (i < str_len && !STRINGLIB_ISSPACE(str[i]))
+ i++;
+#ifndef STRINGLIB_MUTABLE
+ if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No whitespace in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ break;
+ }
+#endif
+ SPLIT_ADD(str, j, i);
+ }
+
+ if (i < str_len) {
+ /* Only occurs when maxcount was reached */
+ /* Skip any remaining whitespace and copy to end of string */
+ while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+ i++;
+ if (i != str_len)
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_char(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR ch,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while ((j < str_len) && (maxcount-- > 0)) {
+ for(; j < str_len; j++) {
+ /* I found that using memchr makes no difference */
+ if (str[j] == ch) {
+ SPLIT_ADD(str, i, j);
+ i = j = j + 1;
+ break;
+ }
+ }
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* ch not in str_obj, so just use str_obj as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ if (i <= str_len) {
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, pos, count=0;
+ PyObject *list, *sub;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+ else if (sep_len == 1)
+ return stringlib_split_char(str_obj, str, str_len, sep[0], maxcount);
+
+ list = PyList_New(PREALLOC_SIZE(maxcount));
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while (maxcount-- > 0) {
+ pos = fastsearch(str+i, str_len-i, sep, sep_len, -1, FAST_SEARCH);
+ if (pos < 0)
+ break;
+ j = i + pos;
+ SPLIT_ADD(str, i, j);
+ i = j + sep_len;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No match in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ {
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_whitespace(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = str_len - 1;
+ while (maxcount-- > 0) {
+ while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+ i--;
+ if (i < 0) break;
+ j = i; i--;
+ while (i >= 0 && !STRINGLIB_ISSPACE(str[i]))
+ i--;
+#ifndef STRINGLIB_MUTABLE
+ if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No whitespace in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ break;
+ }
+#endif
+ SPLIT_ADD(str, i + 1, j + 1);
+ }
+
+ if (i >= 0) {
+ /* Only occurs when maxcount was reached */
+ /* Skip any remaining whitespace and copy to beginning of string */
+ while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+ i--;
+ if (i >= 0)
+ SPLIT_ADD(str, 0, i + 1);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_char(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR ch,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = str_len - 1;
+ while ((i >= 0) && (maxcount-- > 0)) {
+ for(; i >= 0; i--) {
+ if (str[i] == ch) {
+ SPLIT_ADD(str, i + 1, j + 1);
+ j = i = i - 1;
+ break;
+ }
+ }
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* ch not in str_obj, so just use str_obj as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ if (j >= -1) {
+ SPLIT_ADD(str, 0, j + 1);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t j, pos, count=0;
+ PyObject *list, *sub;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+ else if (sep_len == 1)
+ return stringlib_rsplit_char(str_obj, str, str_len, sep[0], maxcount);
+
+ list = PyList_New(PREALLOC_SIZE(maxcount));
+ if (list == NULL)
+ return NULL;
+
+ j = str_len;
+ while (maxcount-- > 0) {
+ pos = fastsearch(str, j, sep, sep_len, -1, FAST_RSEARCH);
+ if (pos < 0)
+ break;
+ SPLIT_ADD(str, pos + sep_len, j);
+ j = pos;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No match in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ {
+ SPLIT_ADD(str, 0, j);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_splitlines(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ int keepends)
+{
+ /* This does not use the preallocated list because splitlines is
+ usually run with hundreds of newlines. The overhead of
+ switching between PyList_SET_ITEM and append causes about a
+ 2-3% slowdown for that common case. A smarter implementation
+ could move the if check out, so the SET_ITEMs are done first
+ and the appends only done when the prealloc buffer is full.
+ That's too much work for little gain.*/
+
+ register Py_ssize_t i;
+ register Py_ssize_t j;
+ PyObject *list = PyList_New(0);
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ for (i = j = 0; i < str_len; ) {
+ Py_ssize_t eol;
+
+ /* Find a line and append it */
+ while (i < str_len && !STRINGLIB_ISLINEBREAK(str[i]))
+ i++;
+
+ /* Skip the line break reading CRLF as one line break */
+ eol = i;
+ if (i < str_len) {
+ if (str[i] == '\r' && i + 1 < str_len && str[i+1] == '\n')
+ i += 2;
+ else
+ i++;
+ if (keepends)
+ eol = i;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No linebreak in str_obj, so just use it as list[0] */
+ if (PyList_Append(list, str_obj))
+ goto onError;
+ break;
+ }
+#endif
+ SPLIT_APPEND(str, j, eol);
+ j = i;
+ }
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/string_format.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/string_format.h
new file mode 100644
index 0000000000..77392a94ea
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/string_format.h
@@ -0,0 +1,1361 @@
+/*
+ string_format.h -- implementation of string.format().
+
+ It uses the Objects/stringlib conventions, so that it can be
+ compiled for both unicode and string objects.
+*/
+
+
+/* Defines for Python 2.6 compatibility */
+#if PY_VERSION_HEX < 0x03000000
+#define PyLong_FromSsize_t _PyLong_FromSsize_t
+#endif
+
+/* Defines for more efficiently reallocating the string buffer */
+#define INITIAL_SIZE_INCREMENT 100
+#define SIZE_MULTIPLIER 2
+#define MAX_SIZE_INCREMENT 3200
+
+
+/************************************************************************/
+/*********** Global data structures and forward declarations *********/
+/************************************************************************/
+
+/*
+ A SubString consists of the characters between two string or
+ unicode pointers.
+*/
+typedef struct {
+ STRINGLIB_CHAR *ptr;
+ STRINGLIB_CHAR *end;
+} SubString;
+
+
+typedef enum {
+ ANS_INIT,
+ ANS_AUTO,
+ ANS_MANUAL
+} AutoNumberState; /* Keep track if we're auto-numbering fields */
+
+/* Keeps track of our auto-numbering state, and which number field we're on */
+typedef struct {
+ AutoNumberState an_state;
+ int an_field_number;
+} AutoNumber;
+
+
+/* forward declaration for recursion */
+static PyObject *
+build_string(SubString *input, PyObject *args, PyObject *kwargs,
+ int recursion_depth, AutoNumber *auto_number);
+
+
+
+/************************************************************************/
+/************************** Utility functions ************************/
+/************************************************************************/
+
+static void
+AutoNumber_Init(AutoNumber *auto_number)
+{
+ auto_number->an_state = ANS_INIT;
+ auto_number->an_field_number = 0;
+}
+
+/* fill in a SubString from a pointer and length */
+Py_LOCAL_INLINE(void)
+SubString_init(SubString *str, STRINGLIB_CHAR *p, Py_ssize_t len)
+{
+ str->ptr = p;
+ if (p == NULL)
+ str->end = NULL;
+ else
+ str->end = str->ptr + len;
+}
+
+/* return a new string. if str->ptr is NULL, return None */
+Py_LOCAL_INLINE(PyObject *)
+SubString_new_object(SubString *str)
+{
+ if (str->ptr == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
+}
+
+/* return a new string. if str->ptr is NULL, return None */
+Py_LOCAL_INLINE(PyObject *)
+SubString_new_object_or_empty(SubString *str)
+{
+ if (str->ptr == NULL) {
+ return STRINGLIB_NEW(NULL, 0);
+ }
+ return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
+}
+
+/* Return 1 if an error has been detected switching between automatic
+ field numbering and manual field specification, else return 0. Set
+ ValueError on error. */
+static int
+autonumber_state_error(AutoNumberState state, int field_name_is_empty)
+{
+ if (state == ANS_MANUAL) {
+ if (field_name_is_empty) {
+ PyErr_SetString(PyExc_ValueError, "cannot switch from "
+ "manual field specification to "
+ "automatic field numbering");
+ return 1;
+ }
+ }
+ else {
+ if (!field_name_is_empty) {
+ PyErr_SetString(PyExc_ValueError, "cannot switch from "
+ "automatic field numbering to "
+ "manual field specification");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/************************************************************************/
+/*********** Output string management functions ****************/
+/************************************************************************/
+
+typedef struct {
+ STRINGLIB_CHAR *ptr;
+ STRINGLIB_CHAR *end;
+ PyObject *obj;
+ Py_ssize_t size_increment;
+} OutputString;
+
+/* initialize an OutputString object, reserving size characters */
+static int
+output_initialize(OutputString *output, Py_ssize_t size)
+{
+ output->obj = STRINGLIB_NEW(NULL, size);
+ if (output->obj == NULL)
+ return 0;
+
+ output->ptr = STRINGLIB_STR(output->obj);
+ output->end = STRINGLIB_LEN(output->obj) + output->ptr;
+ output->size_increment = INITIAL_SIZE_INCREMENT;
+
+ return 1;
+}
+
+/*
+ output_extend reallocates the output string buffer.
+ It returns a status: 0 for a failed reallocation,
+ 1 for success.
+*/
+
+static int
+output_extend(OutputString *output, Py_ssize_t count)
+{
+ STRINGLIB_CHAR *startptr = STRINGLIB_STR(output->obj);
+ Py_ssize_t curlen = output->ptr - startptr;
+ Py_ssize_t maxlen = curlen + count + output->size_increment;
+
+ if (STRINGLIB_RESIZE(&output->obj, maxlen) < 0)
+ return 0;
+ startptr = STRINGLIB_STR(output->obj);
+ output->ptr = startptr + curlen;
+ output->end = startptr + maxlen;
+ if (output->size_increment < MAX_SIZE_INCREMENT)
+ output->size_increment *= SIZE_MULTIPLIER;
+ return 1;
+}
+
+/*
+ output_data dumps characters into our output string
+ buffer.
+
+ In some cases, it has to reallocate the string.
+
+ It returns a status: 0 for a failed reallocation,
+ 1 for success.
+*/
+static int
+output_data(OutputString *output, const STRINGLIB_CHAR *s, Py_ssize_t count)
+{
+ if ((count > output->end - output->ptr) && !output_extend(output, count))
+ return 0;
+ memcpy(output->ptr, s, count * sizeof(STRINGLIB_CHAR));
+ output->ptr += count;
+ return 1;
+}
+
+/************************************************************************/
+/*********** Format string parsing -- integers and identifiers *********/
+/************************************************************************/
+
+static Py_ssize_t
+get_integer(const SubString *str)
+{
+ Py_ssize_t accumulator = 0;
+ Py_ssize_t digitval;
+ STRINGLIB_CHAR *p;
+
+ /* empty string is an error */
+ if (str->ptr >= str->end)
+ return -1;
+
+ for (p = str->ptr; p < str->end; p++) {
+ digitval = STRINGLIB_TODECIMAL(*p);
+ if (digitval < 0)
+ return -1;
+ /*
+ Detect possible overflow before it happens:
+
+ accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
+ accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
+ */
+ if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
+ PyErr_Format(PyExc_ValueError,
+ "Too many decimal digits in format string");
+ return -1;
+ }
+ accumulator = accumulator * 10 + digitval;
+ }
+ return accumulator;
+}
+
+/************************************************************************/
+/******** Functions to get field objects and specification strings ******/
+/************************************************************************/
+
+/* do the equivalent of obj.name */
+static PyObject *
+getattr(PyObject *obj, SubString *name)
+{
+ PyObject *newobj;
+ PyObject *str = SubString_new_object(name);
+ if (str == NULL)
+ return NULL;
+ newobj = PyObject_GetAttr(obj, str);
+ Py_DECREF(str);
+ return newobj;
+}
+
+/* do the equivalent of obj[idx], where obj is a sequence */
+static PyObject *
+getitem_sequence(PyObject *obj, Py_ssize_t idx)
+{
+ return PySequence_GetItem(obj, idx);
+}
+
+/* do the equivalent of obj[idx], where obj is not a sequence */
+static PyObject *
+getitem_idx(PyObject *obj, Py_ssize_t idx)
+{
+ PyObject *newobj;
+ PyObject *idx_obj = PyLong_FromSsize_t(idx);
+ if (idx_obj == NULL)
+ return NULL;
+ newobj = PyObject_GetItem(obj, idx_obj);
+ Py_DECREF(idx_obj);
+ return newobj;
+}
+
+/* do the equivalent of obj[name] */
+static PyObject *
+getitem_str(PyObject *obj, SubString *name)
+{
+ PyObject *newobj;
+ PyObject *str = SubString_new_object(name);
+ if (str == NULL)
+ return NULL;
+ newobj = PyObject_GetItem(obj, str);
+ Py_DECREF(str);
+ return newobj;
+}
+
+typedef struct {
+ /* the entire string we're parsing. we assume that someone else
+ is managing its lifetime, and that it will exist for the
+ lifetime of the iterator. can be empty */
+ SubString str;
+
+ /* pointer to where we are inside field_name */
+ STRINGLIB_CHAR *ptr;
+} FieldNameIterator;
+
+
+static int
+FieldNameIterator_init(FieldNameIterator *self, STRINGLIB_CHAR *ptr,
+ Py_ssize_t len)
+{
+ SubString_init(&self->str, ptr, len);
+ self->ptr = self->str.ptr;
+ return 1;
+}
+
+static int
+_FieldNameIterator_attr(FieldNameIterator *self, SubString *name)
+{
+ STRINGLIB_CHAR c;
+
+ name->ptr = self->ptr;
+
+ /* return everything until '.' or '[' */
+ while (self->ptr < self->str.end) {
+ switch (c = *self->ptr++) {
+ case '[':
+ case '.':
+ /* backup so that we this character will be seen next time */
+ self->ptr--;
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ /* end of string is okay */
+ name->end = self->ptr;
+ return 1;
+}
+
+static int
+_FieldNameIterator_item(FieldNameIterator *self, SubString *name)
+{
+ int bracket_seen = 0;
+ STRINGLIB_CHAR c;
+
+ name->ptr = self->ptr;
+
+ /* return everything until ']' */
+ while (self->ptr < self->str.end) {
+ switch (c = *self->ptr++) {
+ case ']':
+ bracket_seen = 1;
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ /* make sure we ended with a ']' */
+ if (!bracket_seen) {
+ PyErr_SetString(PyExc_ValueError, "Missing ']' in format string");
+ return 0;
+ }
+
+ /* end of string is okay */
+ /* don't include the ']' */
+ name->end = self->ptr-1;
+ return 1;
+}
+
+/* returns 0 on error, 1 on non-error termination, and 2 if it returns a value */
+static int
+FieldNameIterator_next(FieldNameIterator *self, int *is_attribute,
+ Py_ssize_t *name_idx, SubString *name)
+{
+ /* check at end of input */
+ if (self->ptr >= self->str.end)
+ return 1;
+
+ switch (*self->ptr++) {
+ case '.':
+ *is_attribute = 1;
+ if (_FieldNameIterator_attr(self, name) == 0)
+ return 0;
+ *name_idx = -1;
+ break;
+ case '[':
+ *is_attribute = 0;
+ if (_FieldNameIterator_item(self, name) == 0)
+ return 0;
+ *name_idx = get_integer(name);
+ if (*name_idx == -1 && PyErr_Occurred())
+ return 0;
+ break;
+ default:
+ /* Invalid character follows ']' */
+ PyErr_SetString(PyExc_ValueError, "Only '.' or '[' may "
+ "follow ']' in format field specifier");
+ return 0;
+ }
+
+ /* empty string is an error */
+ if (name->ptr == name->end) {
+ PyErr_SetString(PyExc_ValueError, "Empty attribute in format string");
+ return 0;
+ }
+
+ return 2;
+}
+
+
+/* input: field_name
+ output: 'first' points to the part before the first '[' or '.'
+ 'first_idx' is -1 if 'first' is not an integer, otherwise
+ it's the value of first converted to an integer
+ 'rest' is an iterator to return the rest
+*/
+static int
+field_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first,
+ Py_ssize_t *first_idx, FieldNameIterator *rest,
+ AutoNumber *auto_number)
+{
+ STRINGLIB_CHAR c;
+ STRINGLIB_CHAR *p = ptr;
+ STRINGLIB_CHAR *end = ptr + len;
+ int field_name_is_empty;
+ int using_numeric_index;
+
+ /* find the part up until the first '.' or '[' */
+ while (p < end) {
+ switch (c = *p++) {
+ case '[':
+ case '.':
+ /* backup so that we this character is available to the
+ "rest" iterator */
+ p--;
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+
+ /* set up the return values */
+ SubString_init(first, ptr, p - ptr);
+ FieldNameIterator_init(rest, p, end - p);
+
+ /* see if "first" is an integer, in which case it's used as an index */
+ *first_idx = get_integer(first);
+ if (*first_idx == -1 && PyErr_Occurred())
+ return 0;
+
+ field_name_is_empty = first->ptr >= first->end;
+
+ /* If the field name is omitted or if we have a numeric index
+ specified, then we're doing numeric indexing into args. */
+ using_numeric_index = field_name_is_empty || *first_idx != -1;
+
+ /* We always get here exactly one time for each field we're
+ processing. And we get here in field order (counting by left
+ braces). So this is the perfect place to handle automatic field
+ numbering if the field name is omitted. */
+
+ /* Check if we need to do the auto-numbering. It's not needed if
+ we're called from string.Format routines, because it's handled
+ in that class by itself. */
+ if (auto_number) {
+ /* Initialize our auto numbering state if this is the first
+ time we're either auto-numbering or manually numbering. */
+ if (auto_number->an_state == ANS_INIT && using_numeric_index)
+ auto_number->an_state = field_name_is_empty ?
+ ANS_AUTO : ANS_MANUAL;
+
+ /* Make sure our state is consistent with what we're doing
+ this time through. Only check if we're using a numeric
+ index. */
+ if (using_numeric_index)
+ if (autonumber_state_error(auto_number->an_state,
+ field_name_is_empty))
+ return 0;
+ /* Zero length field means we want to do auto-numbering of the
+ fields. */
+ if (field_name_is_empty)
+ *first_idx = (auto_number->an_field_number)++;
+ }
+
+ return 1;
+}
+
+
+/*
+ get_field_object returns the object inside {}, before the
+ format_spec. It handles getindex and getattr lookups and consumes
+ the entire input string.
+*/
+static PyObject *
+get_field_object(SubString *input, PyObject *args, PyObject *kwargs,
+ AutoNumber *auto_number)
+{
+ PyObject *obj = NULL;
+ int ok;
+ int is_attribute;
+ SubString name;
+ SubString first;
+ Py_ssize_t index;
+ FieldNameIterator rest;
+
+ if (!field_name_split(input->ptr, input->end - input->ptr, &first,
+ &index, &rest, auto_number)) {
+ goto error;
+ }
+
+ if (index == -1) {
+ /* look up in kwargs */
+ PyObject *key = SubString_new_object(&first);
+ if (key == NULL)
+ goto error;
+ if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
+ PyErr_SetObject(PyExc_KeyError, key);
+ Py_DECREF(key);
+ goto error;
+ }
+ Py_DECREF(key);
+ Py_INCREF(obj);
+ }
+ else {
+ /* look up in args */
+ obj = PySequence_GetItem(args, index);
+ if (obj == NULL)
+ goto error;
+ }
+
+ /* iterate over the rest of the field_name */
+ while ((ok = FieldNameIterator_next(&rest, &is_attribute, &index,
+ &name)) == 2) {
+ PyObject *tmp;
+
+ if (is_attribute)
+ /* getattr lookup "." */
+ tmp = getattr(obj, &name);
+ else
+ /* getitem lookup "[]" */
+ if (index == -1)
+ tmp = getitem_str(obj, &name);
+ else
+ if (PySequence_Check(obj))
+ tmp = getitem_sequence(obj, index);
+ else
+ /* not a sequence */
+ tmp = getitem_idx(obj, index);
+ if (tmp == NULL)
+ goto error;
+
+ /* assign to obj */
+ Py_DECREF(obj);
+ obj = tmp;
+ }
+ /* end of iterator, this is the non-error case */
+ if (ok == 1)
+ return obj;
+error:
+ Py_XDECREF(obj);
+ return NULL;
+}
+
+/************************************************************************/
+/***************** Field rendering functions **************************/
+/************************************************************************/
+
+/*
+ render_field() is the main function in this section. It takes the
+ field object and field specification string generated by
+ get_field_and_spec, and renders the field into the output string.
+
+ render_field calls fieldobj.__format__(format_spec) method, and
+ appends to the output.
+*/
+static int
+render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
+{
+ int ok = 0;
+ PyObject *result = NULL;
+ PyObject *format_spec_object = NULL;
+ PyObject *(*formatter)(PyObject *, STRINGLIB_CHAR *, Py_ssize_t) = NULL;
+ STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
+ format_spec->ptr : NULL;
+ Py_ssize_t format_spec_len = format_spec->ptr ?
+ format_spec->end - format_spec->ptr : 0;
+
+ /* If we know the type exactly, skip the lookup of __format__ and just
+ call the formatter directly. */
+#if STRINGLIB_IS_UNICODE
+ if (PyUnicode_CheckExact(fieldobj))
+ formatter = _PyUnicode_FormatAdvanced;
+ /* Unfortunately, there's a problem with checking for int, long,
+ and float here. If we're being included as unicode, their
+ formatters expect string format_spec args. For now, just skip
+ this optimization for unicode. This could be fixed, but it's a
+ hassle. */
+#else
+ if (PyString_CheckExact(fieldobj))
+ formatter = _PyBytes_FormatAdvanced;
+ else if (PyInt_CheckExact(fieldobj))
+ formatter =_PyInt_FormatAdvanced;
+ else if (PyLong_CheckExact(fieldobj))
+ formatter =_PyLong_FormatAdvanced;
+ else if (PyFloat_CheckExact(fieldobj))
+ formatter = _PyFloat_FormatAdvanced;
+#endif
+
+ if (formatter) {
+ /* we know exactly which formatter will be called when __format__ is
+ looked up, so call it directly, instead. */
+ result = formatter(fieldobj, format_spec_start, format_spec_len);
+ }
+ else {
+ /* We need to create an object out of the pointers we have, because
+ __format__ takes a string/unicode object for format_spec. */
+ format_spec_object = STRINGLIB_NEW(format_spec_start,
+ format_spec_len);
+ if (format_spec_object == NULL)
+ goto done;
+
+ result = PyObject_Format(fieldobj, format_spec_object);
+ }
+ if (result == NULL)
+ goto done;
+
+#if PY_VERSION_HEX >= 0x03000000
+ assert(PyUnicode_Check(result));
+#else
+ assert(PyString_Check(result) || PyUnicode_Check(result));
+
+ /* Convert result to our type. We could be str, and result could
+ be unicode */
+ {
+ PyObject *tmp = STRINGLIB_TOSTR(result);
+ if (tmp == NULL)
+ goto done;
+ Py_DECREF(result);
+ result = tmp;
+ }
+#endif
+
+ ok = output_data(output,
+ STRINGLIB_STR(result), STRINGLIB_LEN(result));
+done:
+ Py_XDECREF(format_spec_object);
+ Py_XDECREF(result);
+ return ok;
+}
+
+static int
+parse_field(SubString *str, SubString *field_name, SubString *format_spec,
+ STRINGLIB_CHAR *conversion)
+{
+ /* Note this function works if the field name is zero length,
+ which is good. Zero length field names are handled later, in
+ field_name_split. */
+
+ STRINGLIB_CHAR c = 0;
+
+ /* initialize these, as they may be empty */
+ *conversion = '\0';
+ SubString_init(format_spec, NULL, 0);
+
+ /* Search for the field name. it's terminated by the end of
+ the string, or a ':' or '!' */
+ field_name->ptr = str->ptr;
+ while (str->ptr < str->end) {
+ switch (c = *(str->ptr++)) {
+ case ':':
+ case '!':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+
+ if (c == '!' || c == ':') {
+ /* we have a format specifier and/or a conversion */
+ /* don't include the last character */
+ field_name->end = str->ptr-1;
+
+ /* the format specifier is the rest of the string */
+ format_spec->ptr = str->ptr;
+ format_spec->end = str->end;
+
+ /* see if there's a conversion specifier */
+ if (c == '!') {
+ /* there must be another character present */
+ if (format_spec->ptr >= format_spec->end) {
+ PyErr_SetString(PyExc_ValueError,
+ "end of format while looking for conversion "
+ "specifier");
+ return 0;
+ }
+ *conversion = *(format_spec->ptr++);
+
+ /* if there is another character, it must be a colon */
+ if (format_spec->ptr < format_spec->end) {
+ c = *(format_spec->ptr++);
+ if (c != ':') {
+ PyErr_SetString(PyExc_ValueError,
+ "expected ':' after format specifier");
+ return 0;
+ }
+ }
+ }
+ }
+ else
+ /* end of string, there's no format_spec or conversion */
+ field_name->end = str->ptr;
+
+ return 1;
+}
+
+/************************************************************************/
+/******* Output string allocation and escape-to-markup processing ******/
+/************************************************************************/
+
+/* MarkupIterator breaks the string into pieces of either literal
+ text, or things inside {} that need to be marked up. it is
+ designed to make it easy to wrap a Python iterator around it, for
+ use with the Formatter class */
+
+typedef struct {
+ SubString str;
+} MarkupIterator;
+
+static int
+MarkupIterator_init(MarkupIterator *self, STRINGLIB_CHAR *ptr, Py_ssize_t len)
+{
+ SubString_init(&self->str, ptr, len);
+ return 1;
+}
+
+/* returns 0 on error, 1 on non-error termination, and 2 if it got a
+ string (or something to be expanded) */
+static int
+MarkupIterator_next(MarkupIterator *self, SubString *literal,
+ int *field_present, SubString *field_name,
+ SubString *format_spec, STRINGLIB_CHAR *conversion,
+ int *format_spec_needs_expanding)
+{
+ int at_end;
+ STRINGLIB_CHAR c = 0;
+ STRINGLIB_CHAR *start;
+ int count;
+ Py_ssize_t len;
+ int markup_follows = 0;
+
+ /* initialize all of the output variables */
+ SubString_init(literal, NULL, 0);
+ SubString_init(field_name, NULL, 0);
+ SubString_init(format_spec, NULL, 0);
+ *conversion = '\0';
+ *format_spec_needs_expanding = 0;
+ *field_present = 0;
+
+ /* No more input, end of iterator. This is the normal exit
+ path. */
+ if (self->str.ptr >= self->str.end)
+ return 1;
+
+ start = self->str.ptr;
+
+ /* First read any literal text. Read until the end of string, an
+ escaped '{' or '}', or an unescaped '{'. In order to never
+ allocate memory and so I can just pass pointers around, if
+ there's an escaped '{' or '}' then we'll return the literal
+ including the brace, but no format object. The next time
+ through, we'll return the rest of the literal, skipping past
+ the second consecutive brace. */
+ while (self->str.ptr < self->str.end) {
+ switch (c = *(self->str.ptr++)) {
+ case '{':
+ case '}':
+ markup_follows = 1;
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+
+ at_end = self->str.ptr >= self->str.end;
+ len = self->str.ptr - start;
+
+ if ((c == '}') && (at_end || (c != *self->str.ptr))) {
+ PyErr_SetString(PyExc_ValueError, "Single '}' encountered "
+ "in format string");
+ return 0;
+ }
+ if (at_end && c == '{') {
+ PyErr_SetString(PyExc_ValueError, "Single '{' encountered "
+ "in format string");
+ return 0;
+ }
+ if (!at_end) {
+ if (c == *self->str.ptr) {
+ /* escaped } or {, skip it in the input. there is no
+ markup object following us, just this literal text */
+ self->str.ptr++;
+ markup_follows = 0;
+ }
+ else
+ len--;
+ }
+
+ /* record the literal text */
+ literal->ptr = start;
+ literal->end = start + len;
+
+ if (!markup_follows)
+ return 2;
+
+ /* this is markup, find the end of the string by counting nested
+ braces. note that this prohibits escaped braces, so that
+ format_specs cannot have braces in them. */
+ *field_present = 1;
+ count = 1;
+
+ start = self->str.ptr;
+
+ /* we know we can't have a zero length string, so don't worry
+ about that case */
+ while (self->str.ptr < self->str.end) {
+ switch (c = *(self->str.ptr++)) {
+ case '{':
+ /* the format spec needs to be recursively expanded.
+ this is an optimization, and not strictly needed */
+ *format_spec_needs_expanding = 1;
+ count++;
+ break;
+ case '}':
+ count--;
+ if (count <= 0) {
+ /* we're done. parse and get out */
+ SubString s;
+
+ SubString_init(&s, start, self->str.ptr - 1 - start);
+ if (parse_field(&s, field_name, format_spec, conversion) == 0)
+ return 0;
+
+ /* success */
+ return 2;
+ }
+ break;
+ }
+ }
+
+ /* end of string while searching for matching '}' */
+ PyErr_SetString(PyExc_ValueError, "unmatched '{' in format");
+ return 0;
+}
+
+
+/* do the !r or !s conversion on obj */
+static PyObject *
+do_conversion(PyObject *obj, STRINGLIB_CHAR conversion)
+{
+ /* XXX in pre-3.0, do we need to convert this to unicode, since it
+ might have returned a string? */
+ switch (conversion) {
+ case 'r':
+ return PyObject_Repr(obj);
+ case 's':
+ return STRINGLIB_TOSTR(obj);
+ default:
+ if (conversion > 32 && conversion < 127) {
+ /* It's the ASCII subrange; casting to char is safe
+ (assuming the execution character set is an ASCII
+ superset). */
+ PyErr_Format(PyExc_ValueError,
+ "Unknown conversion specifier %c",
+ (char)conversion);
+ } else
+ PyErr_Format(PyExc_ValueError,
+ "Unknown conversion specifier \\x%x",
+ (unsigned int)conversion);
+ return NULL;
+ }
+}
+
+/* given:
+
+ {field_name!conversion:format_spec}
+
+ compute the result and write it to output.
+ format_spec_needs_expanding is an optimization. if it's false,
+ just output the string directly, otherwise recursively expand the
+ format_spec string.
+
+ field_name is allowed to be zero length, in which case we
+ are doing auto field numbering.
+*/
+
+static int
+output_markup(SubString *field_name, SubString *format_spec,
+ int format_spec_needs_expanding, STRINGLIB_CHAR conversion,
+ OutputString *output, PyObject *args, PyObject *kwargs,
+ int recursion_depth, AutoNumber *auto_number)
+{
+ PyObject *tmp = NULL;
+ PyObject *fieldobj = NULL;
+ SubString expanded_format_spec;
+ SubString *actual_format_spec;
+ int result = 0;
+
+ /* convert field_name to an object */
+ fieldobj = get_field_object(field_name, args, kwargs, auto_number);
+ if (fieldobj == NULL)
+ goto done;
+
+ if (conversion != '\0') {
+ tmp = do_conversion(fieldobj, conversion);
+ if (tmp == NULL)
+ goto done;
+
+ /* do the assignment, transferring ownership: fieldobj = tmp */
+ Py_DECREF(fieldobj);
+ fieldobj = tmp;
+ tmp = NULL;
+ }
+
+ /* if needed, recurively compute the format_spec */
+ if (format_spec_needs_expanding) {
+ tmp = build_string(format_spec, args, kwargs, recursion_depth-1,
+ auto_number);
+ if (tmp == NULL)
+ goto done;
+
+ /* note that in the case we're expanding the format string,
+ tmp must be kept around until after the call to
+ render_field. */
+ SubString_init(&expanded_format_spec,
+ STRINGLIB_STR(tmp), STRINGLIB_LEN(tmp));
+ actual_format_spec = &expanded_format_spec;
+ }
+ else
+ actual_format_spec = format_spec;
+
+ if (render_field(fieldobj, actual_format_spec, output) == 0)
+ goto done;
+
+ result = 1;
+
+done:
+ Py_XDECREF(fieldobj);
+ Py_XDECREF(tmp);
+
+ return result;
+}
+
+/*
+ do_markup is the top-level loop for the format() method. It
+ searches through the format string for escapes to markup codes, and
+ calls other functions to move non-markup text to the output,
+ and to perform the markup to the output.
+*/
+static int
+do_markup(SubString *input, PyObject *args, PyObject *kwargs,
+ OutputString *output, int recursion_depth, AutoNumber *auto_number)
+{
+ MarkupIterator iter;
+ int format_spec_needs_expanding;
+ int result;
+ int field_present;
+ SubString literal;
+ SubString field_name;
+ SubString format_spec;
+ STRINGLIB_CHAR conversion;
+
+ MarkupIterator_init(&iter, input->ptr, input->end - input->ptr);
+ while ((result = MarkupIterator_next(&iter, &literal, &field_present,
+ &field_name, &format_spec,
+ &conversion,
+ &format_spec_needs_expanding)) == 2) {
+ if (!output_data(output, literal.ptr, literal.end - literal.ptr))
+ return 0;
+ if (field_present)
+ if (!output_markup(&field_name, &format_spec,
+ format_spec_needs_expanding, conversion, output,
+ args, kwargs, recursion_depth, auto_number))
+ return 0;
+ }
+ return result;
+}
+
+
+/*
+ build_string allocates the output string and then
+ calls do_markup to do the heavy lifting.
+*/
+static PyObject *
+build_string(SubString *input, PyObject *args, PyObject *kwargs,
+ int recursion_depth, AutoNumber *auto_number)
+{
+ OutputString output;
+ PyObject *result = NULL;
+ Py_ssize_t count;
+
+ output.obj = NULL; /* needed so cleanup code always works */
+
+ /* check the recursion level */
+ if (recursion_depth <= 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "Max string recursion exceeded");
+ goto done;
+ }
+
+ /* initial size is the length of the format string, plus the size
+ increment. seems like a reasonable default */
+ if (!output_initialize(&output,
+ input->end - input->ptr +
+ INITIAL_SIZE_INCREMENT))
+ goto done;
+
+ if (!do_markup(input, args, kwargs, &output, recursion_depth,
+ auto_number)) {
+ goto done;
+ }
+
+ count = output.ptr - STRINGLIB_STR(output.obj);
+ if (STRINGLIB_RESIZE(&output.obj, count) < 0) {
+ goto done;
+ }
+
+ /* transfer ownership to result */
+ result = output.obj;
+ output.obj = NULL;
+
+done:
+ Py_XDECREF(output.obj);
+ return result;
+}
+
+/************************************************************************/
+/*********** main routine ***********************************************/
+/************************************************************************/
+
+/* this is the main entry point */
+static PyObject *
+do_string_format(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ SubString input;
+
+ /* PEP 3101 says only 2 levels, so that
+ "{0:{1}}".format('abc', 's') # works
+ "{0:{1:{2}}}".format('abc', 's', '') # fails
+ */
+ int recursion_depth = 2;
+
+ AutoNumber auto_number;
+
+ AutoNumber_Init(&auto_number);
+ SubString_init(&input, STRINGLIB_STR(self), STRINGLIB_LEN(self));
+ return build_string(&input, args, kwargs, recursion_depth, &auto_number);
+}
+
+
+
+/************************************************************************/
+/*********** formatteriterator ******************************************/
+/************************************************************************/
+
+/* This is used to implement string.Formatter.vparse(). It exists so
+ Formatter can share code with the built in unicode.format() method.
+ It's really just a wrapper around MarkupIterator that is callable
+ from Python. */
+
+typedef struct {
+ PyObject_HEAD
+
+ STRINGLIB_OBJECT *str;
+
+ MarkupIterator it_markup;
+} formatteriterobject;
+
+static void
+formatteriter_dealloc(formatteriterobject *it)
+{
+ Py_XDECREF(it->str);
+ PyObject_FREE(it);
+}
+
+/* returns a tuple:
+ (literal, field_name, format_spec, conversion)
+
+ literal is any literal text to output. might be zero length
+ field_name is the string before the ':'. might be None
+ format_spec is the string after the ':'. mibht be None
+ conversion is either None, or the string after the '!'
+*/
+static PyObject *
+formatteriter_next(formatteriterobject *it)
+{
+ SubString literal;
+ SubString field_name;
+ SubString format_spec;
+ STRINGLIB_CHAR conversion;
+ int format_spec_needs_expanding;
+ int field_present;
+ int result = MarkupIterator_next(&it->it_markup, &literal, &field_present,
+ &field_name, &format_spec, &conversion,
+ &format_spec_needs_expanding);
+
+ /* all of the SubString objects point into it->str, so no
+ memory management needs to be done on them */
+ assert(0 <= result && result <= 2);
+ if (result == 0 || result == 1)
+ /* if 0, error has already been set, if 1, iterator is empty */
+ return NULL;
+ else {
+ PyObject *literal_str = NULL;
+ PyObject *field_name_str = NULL;
+ PyObject *format_spec_str = NULL;
+ PyObject *conversion_str = NULL;
+ PyObject *tuple = NULL;
+
+ literal_str = SubString_new_object(&literal);
+ if (literal_str == NULL)
+ goto done;
+
+ field_name_str = SubString_new_object(&field_name);
+ if (field_name_str == NULL)
+ goto done;
+
+ /* if field_name is non-zero length, return a string for
+ format_spec (even if zero length), else return None */
+ format_spec_str = (field_present ?
+ SubString_new_object_or_empty :
+ SubString_new_object)(&format_spec);
+ if (format_spec_str == NULL)
+ goto done;
+
+ /* if the conversion is not specified, return a None,
+ otherwise create a one length string with the conversion
+ character */
+ if (conversion == '\0') {
+ conversion_str = Py_None;
+ Py_INCREF(conversion_str);
+ }
+ else
+ conversion_str = STRINGLIB_NEW(&conversion, 1);
+ if (conversion_str == NULL)
+ goto done;
+
+ tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str,
+ conversion_str);
+ done:
+ Py_XDECREF(literal_str);
+ Py_XDECREF(field_name_str);
+ Py_XDECREF(format_spec_str);
+ Py_XDECREF(conversion_str);
+ return tuple;
+ }
+}
+
+static PyMethodDef formatteriter_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject PyFormatterIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "formatteriterator", /* tp_name */
+ sizeof(formatteriterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)formatteriter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)formatteriter_next, /* tp_iternext */
+ formatteriter_methods, /* tp_methods */
+ 0,
+};
+
+/* unicode_formatter_parser is used to implement
+ string.Formatter.vformat. it parses a string and returns tuples
+ describing the parsed elements. It's a wrapper around
+ stringlib/string_format.h's MarkupIterator */
+static PyObject *
+formatter_parser(STRINGLIB_OBJECT *self)
+{
+ formatteriterobject *it;
+
+ it = PyObject_New(formatteriterobject, &PyFormatterIter_Type);
+ if (it == NULL)
+ return NULL;
+
+ /* take ownership, give the object to the iterator */
+ Py_INCREF(self);
+ it->str = self;
+
+ /* initialize the contained MarkupIterator */
+ MarkupIterator_init(&it->it_markup,
+ STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+
+ return (PyObject *)it;
+}
+
+
+/************************************************************************/
+/*********** fieldnameiterator ******************************************/
+/************************************************************************/
+
+
+/* This is used to implement string.Formatter.vparse(). It parses the
+ field name into attribute and item values. It's a Python-callable
+ wrapper around FieldNameIterator */
+
+typedef struct {
+ PyObject_HEAD
+
+ STRINGLIB_OBJECT *str;
+
+ FieldNameIterator it_field;
+} fieldnameiterobject;
+
+static void
+fieldnameiter_dealloc(fieldnameiterobject *it)
+{
+ Py_XDECREF(it->str);
+ PyObject_FREE(it);
+}
+
+/* returns a tuple:
+ (is_attr, value)
+ is_attr is true if we used attribute syntax (e.g., '.foo')
+ false if we used index syntax (e.g., '[foo]')
+ value is an integer or string
+*/
+static PyObject *
+fieldnameiter_next(fieldnameiterobject *it)
+{
+ int result;
+ int is_attr;
+ Py_ssize_t idx;
+ SubString name;
+
+ result = FieldNameIterator_next(&it->it_field, &is_attr,
+ &idx, &name);
+ if (result == 0 || result == 1)
+ /* if 0, error has already been set, if 1, iterator is empty */
+ return NULL;
+ else {
+ PyObject* result = NULL;
+ PyObject* is_attr_obj = NULL;
+ PyObject* obj = NULL;
+
+ is_attr_obj = PyBool_FromLong(is_attr);
+ if (is_attr_obj == NULL)
+ goto done;
+
+ /* either an integer or a string */
+ if (idx != -1)
+ obj = PyLong_FromSsize_t(idx);
+ else
+ obj = SubString_new_object(&name);
+ if (obj == NULL)
+ goto done;
+
+ /* return a tuple of values */
+ result = PyTuple_Pack(2, is_attr_obj, obj);
+
+ done:
+ Py_XDECREF(is_attr_obj);
+ Py_XDECREF(obj);
+ return result;
+ }
+}
+
+static PyMethodDef fieldnameiter_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+static PyTypeObject PyFieldNameIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "fieldnameiterator", /* tp_name */
+ sizeof(fieldnameiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)fieldnameiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)fieldnameiter_next, /* tp_iternext */
+ fieldnameiter_methods, /* tp_methods */
+ 0};
+
+/* unicode_formatter_field_name_split is used to implement
+ string.Formatter.vformat. it takes an PEP 3101 "field name", and
+ returns a tuple of (first, rest): "first", the part before the
+ first '.' or '['; and "rest", an iterator for the rest of the field
+ name. it's a wrapper around stringlib/string_format.h's
+ field_name_split. The iterator it returns is a
+ FieldNameIterator */
+static PyObject *
+formatter_field_name_split(STRINGLIB_OBJECT *self)
+{
+ SubString first;
+ Py_ssize_t first_idx;
+ fieldnameiterobject *it;
+
+ PyObject *first_obj = NULL;
+ PyObject *result = NULL;
+
+ it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type);
+ if (it == NULL)
+ return NULL;
+
+ /* take ownership, give the object to the iterator. this is
+ just to keep the field_name alive */
+ Py_INCREF(self);
+ it->str = self;
+
+ /* Pass in auto_number = NULL. We'll return an empty string for
+ first_obj in that case. */
+ if (!field_name_split(STRINGLIB_STR(self),
+ STRINGLIB_LEN(self),
+ &first, &first_idx, &it->it_field, NULL))
+ goto done;
+
+ /* first becomes an integer, if possible; else a string */
+ if (first_idx != -1)
+ first_obj = PyLong_FromSsize_t(first_idx);
+ else
+ /* convert "first" into a string object */
+ first_obj = SubString_new_object(&first);
+ if (first_obj == NULL)
+ goto done;
+
+ /* return a tuple of values */
+ result = PyTuple_Pack(2, first_obj, it);
+
+done:
+ Py_XDECREF(it);
+ Py_XDECREF(first_obj);
+ return result;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/stringdefs.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/stringdefs.h
new file mode 100644
index 0000000000..a301d4e9ce
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/stringdefs.h
@@ -0,0 +1,33 @@
+#ifndef STRINGLIB_STRINGDEFS_H
+#define STRINGLIB_STRINGDEFS_H
+
+/* this is sort of a hack. there's at least one place (formatting
+ floats) where some stringlib code takes a different path if it's
+ compiled as unicode. */
+#define STRINGLIB_IS_UNICODE 0
+
+#define STRINGLIB_OBJECT PyStringObject
+#define STRINGLIB_CHAR char
+#define STRINGLIB_TYPE_NAME "string"
+#define STRINGLIB_PARSE_CODE "S"
+#define STRINGLIB_EMPTY nullstring
+#define STRINGLIB_ISSPACE Py_ISSPACE
+#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
+#define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9'))
+#define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1)
+#define STRINGLIB_TOUPPER Py_TOUPPER
+#define STRINGLIB_TOLOWER Py_TOLOWER
+#define STRINGLIB_FILL memset
+#define STRINGLIB_STR PyString_AS_STRING
+#define STRINGLIB_LEN PyString_GET_SIZE
+#define STRINGLIB_NEW PyString_FromStringAndSize
+#define STRINGLIB_RESIZE _PyString_Resize
+#define STRINGLIB_CHECK PyString_Check
+#define STRINGLIB_CHECK_EXACT PyString_CheckExact
+#define STRINGLIB_TOSTR PyObject_Str
+#define STRINGLIB_GROUPING _PyString_InsertThousandsGrouping
+#define STRINGLIB_GROUPING_LOCALE _PyString_InsertThousandsGroupingLocale
+
+#define STRINGLIB_WANT_CONTAINS_OBJ 1
+
+#endif /* !STRINGLIB_STRINGDEFS_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/transmogrify.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/transmogrify.h
new file mode 100644
index 0000000000..9f61025440
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/transmogrify.h
@@ -0,0 +1,264 @@
+/* NOTE: this API is -ONLY- for use with single byte character strings. */
+/* Do not use it with Unicode. */
+
+/* the more complicated methods. parts of these should be pulled out into the
+ shared code in bytes_methods.c to cut down on duplicate code bloat. */
+
+PyDoc_STRVAR(expandtabs__doc__,
+"B.expandtabs([tabsize]) -> copy of B\n\
+\n\
+Return a copy of B where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+stringlib_expandtabs(PyObject *self, PyObject *args)
+{
+ const char *e, *p;
+ char *q;
+ Py_ssize_t i, j;
+ PyObject *u;
+ int tabsize = 8;
+
+ if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+ return NULL;
+
+ /* First pass: determine size of output string */
+ i = j = 0;
+ e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
+ for (p = STRINGLIB_STR(self); p < e; p++) {
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ Py_ssize_t incr = tabsize - (j % tabsize);
+ if (j > PY_SSIZE_T_MAX - incr)
+ goto overflow;
+ j += incr;
+ }
+ }
+ else {
+ if (j > PY_SSIZE_T_MAX - 1)
+ goto overflow;
+ j++;
+ if (*p == '\n' || *p == '\r') {
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow;
+ i += j;
+ j = 0;
+ }
+ }
+ }
+
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow;
+
+ /* Second pass: create output string and fill it */
+ u = STRINGLIB_NEW(NULL, i + j);
+ if (!u)
+ return NULL;
+
+ j = 0;
+ q = STRINGLIB_STR(u);
+
+ for (p = STRINGLIB_STR(self); p < e; p++) {
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ i = tabsize - (j % tabsize);
+ j += i;
+ while (i--)
+ *q++ = ' ';
+ }
+ }
+ else {
+ j++;
+ *q++ = *p;
+ if (*p == '\n' || *p == '\r')
+ j = 0;
+ }
+ }
+
+ return u;
+ overflow:
+ PyErr_SetString(PyExc_OverflowError, "result too long");
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
+{
+ PyObject *u;
+
+ if (left < 0)
+ left = 0;
+ if (right < 0)
+ right = 0;
+
+ if (left == 0 && right == 0 && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+ /* We're defined as returning a copy; If the object is mutable
+ * that means we must make an identical copy. */
+ return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+ Py_INCREF(self);
+ return (PyObject *)self;
+#endif /* STRINGLIB_MUTABLE */
+ }
+
+ u = STRINGLIB_NEW(NULL,
+ left + STRINGLIB_LEN(self) + right);
+ if (u) {
+ if (left)
+ memset(STRINGLIB_STR(u), fill, left);
+ Py_MEMCPY(STRINGLIB_STR(u) + left,
+ STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
+ if (right)
+ memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self),
+ fill, right);
+ }
+
+ return u;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"B.ljust(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B left justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+stringlib_ljust(PyObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+ return NULL;
+
+ if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+ /* We're defined as returning a copy; If the object is mutable
+ * that means we must make an identical copy. */
+ return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+ Py_INCREF(self);
+ return (PyObject*) self;
+#endif
+ }
+
+ return pad(self, 0, width - STRINGLIB_LEN(self), fillchar);
+}
+
+
+PyDoc_STRVAR(rjust__doc__,
+"B.rjust(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B right justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+stringlib_rjust(PyObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+ return NULL;
+
+ if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+ /* We're defined as returning a copy; If the object is mutable
+ * that means we must make an identical copy. */
+ return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+ Py_INCREF(self);
+ return (PyObject*) self;
+#endif
+ }
+
+ return pad(self, width - STRINGLIB_LEN(self), 0, fillchar);
+}
+
+
+PyDoc_STRVAR(center__doc__,
+"B.center(width[, fillchar]) -> copy of B\n"
+"\n"
+"Return B centered in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+stringlib_center(PyObject *self, PyObject *args)
+{
+ Py_ssize_t marg, left;
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
+ return NULL;
+
+ if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+ /* We're defined as returning a copy; If the object is mutable
+ * that means we must make an identical copy. */
+ return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+ Py_INCREF(self);
+ return (PyObject*) self;
+#endif
+ }
+
+ marg = width - STRINGLIB_LEN(self);
+ left = marg / 2 + (marg & width & 1);
+
+ return pad(self, left, marg - left, fillchar);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"B.zfill(width) -> copy of B\n"
+"\n"
+"Pad a numeric string B with zeros on the left, to fill a field\n"
+"of the specified width. B is never truncated.");
+
+static PyObject *
+stringlib_zfill(PyObject *self, PyObject *args)
+{
+ Py_ssize_t fill;
+ PyObject *s;
+ char *p;
+ Py_ssize_t width;
+
+ if (!PyArg_ParseTuple(args, "n:zfill", &width))
+ return NULL;
+
+ if (STRINGLIB_LEN(self) >= width) {
+ if (STRINGLIB_CHECK_EXACT(self)) {
+#if STRINGLIB_MUTABLE
+ /* We're defined as returning a copy; If the object is mutable
+ * that means we must make an identical copy. */
+ return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
+#else
+ Py_INCREF(self);
+ return (PyObject*) self;
+#endif
+ }
+ else
+ return STRINGLIB_NEW(
+ STRINGLIB_STR(self),
+ STRINGLIB_LEN(self)
+ );
+ }
+
+ fill = width - STRINGLIB_LEN(self);
+
+ s = pad(self, fill, 0, '0');
+
+ if (s == NULL)
+ return NULL;
+
+ p = STRINGLIB_STR(s);
+ if (p[fill] == '+' || p[fill] == '-') {
+ /* move sign to beginning of string */
+ p[0] = p[fill];
+ p[fill] = '0';
+ }
+
+ return (PyObject*) s;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/unicodedefs.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/unicodedefs.h
new file mode 100644
index 0000000000..ecb442584f
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringlib/unicodedefs.h
@@ -0,0 +1,37 @@
+#ifndef STRINGLIB_UNICODEDEFS_H
+#define STRINGLIB_UNICODEDEFS_H
+
+/* this is sort of a hack. there's at least one place (formatting
+ floats) where some stringlib code takes a different path if it's
+ compiled as unicode. */
+#define STRINGLIB_IS_UNICODE 1
+
+#define STRINGLIB_OBJECT PyUnicodeObject
+#define STRINGLIB_CHAR Py_UNICODE
+#define STRINGLIB_TYPE_NAME "unicode"
+#define STRINGLIB_PARSE_CODE "U"
+#define STRINGLIB_EMPTY unicode_empty
+#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE
+#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK
+#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL
+#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL
+#define STRINGLIB_TOUPPER Py_UNICODE_TOUPPER
+#define STRINGLIB_TOLOWER Py_UNICODE_TOLOWER
+#define STRINGLIB_FILL Py_UNICODE_FILL
+#define STRINGLIB_STR PyUnicode_AS_UNICODE
+#define STRINGLIB_LEN PyUnicode_GET_SIZE
+#define STRINGLIB_NEW PyUnicode_FromUnicode
+#define STRINGLIB_RESIZE PyUnicode_Resize
+#define STRINGLIB_CHECK PyUnicode_Check
+#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact
+#define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping
+
+#if PY_VERSION_HEX < 0x03000000
+#define STRINGLIB_TOSTR PyObject_Unicode
+#else
+#define STRINGLIB_TOSTR PyObject_Str
+#endif
+
+#define STRINGLIB_WANT_CONTAINS_OBJ 1
+
+#endif /* !STRINGLIB_UNICODEDEFS_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/stringobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringobject.c
new file mode 100644
index 0000000000..92e893964e
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/stringobject.c
@@ -0,0 +1,4847 @@
+/* String (str/bytes) object implementation */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include <ctype.h>
+#include <stddef.h>
+
+#ifdef COUNT_ALLOCS
+Py_ssize_t null_strings, one_strings;
+#endif
+
+static PyStringObject *characters[UCHAR_MAX + 1];
+static PyStringObject *nullstring;
+
+/* This dictionary holds all interned strings. Note that references to
+ strings in this dictionary are *not* counted in the string's ob_refcnt.
+ When the interned string reaches a refcnt of 0 the string deallocation
+ function will delete the reference from this dictionary.
+
+ Another way to look at this is that to say that the actual reference
+ count of a string is: s->ob_refcnt + (s->ob_sstate?2:0)
+*/
+static PyObject *interned;
+
+/* PyStringObject_SIZE gives the basic size of a string; any memory allocation
+ for a string of length n should request PyStringObject_SIZE + n bytes.
+
+ Using PyStringObject_SIZE instead of sizeof(PyStringObject) saves
+ 3 bytes per string allocation on a typical system.
+*/
+#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1)
+
+/*
+ For PyString_FromString(), the parameter `str' points to a null-terminated
+ string containing exactly `size' bytes.
+
+ For PyString_FromStringAndSize(), the parameter the parameter `str' is
+ either NULL or else points to a string containing at least `size' bytes.
+ For PyString_FromStringAndSize(), the string in the `str' parameter does
+ not have to be null-terminated. (Therefore it is safe to construct a
+ substring by calling `PyString_FromStringAndSize(origstring, substrlen)'.)
+ If `str' is NULL then PyString_FromStringAndSize() will allocate `size+1'
+ bytes (setting the last byte to the null terminating character) and you can
+ fill in the data yourself. If `str' is non-NULL then the resulting
+ PyString object must be treated as immutable and you must not fill in nor
+ alter the data yourself, since the strings may be shared.
+
+ The PyObject member `op->ob_size', which denotes the number of "extra
+ items" in a variable-size object, will contain the number of bytes
+ allocated for string data, not counting the null terminating character.
+ It is therefore equal to the `size' parameter (for
+ PyString_FromStringAndSize()) or the length of the string in the `str'
+ parameter (for PyString_FromString()).
+*/
+PyObject *
+PyString_FromStringAndSize(const char *str, Py_ssize_t size)
+{
+ register PyStringObject *op;
+ if (size < 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "Negative size passed to PyString_FromStringAndSize");
+ return NULL;
+ }
+ if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+ null_strings++;
+#endif
+ Py_INCREF(op);
+ return (PyObject *)op;
+ }
+ if (size == 1 && str != NULL &&
+ (op = characters[*str & UCHAR_MAX]) != NULL)
+ {
+#ifdef COUNT_ALLOCS
+ one_strings++;
+#endif
+ Py_INCREF(op);
+ return (PyObject *)op;
+ }
+
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+ PyErr_SetString(PyExc_OverflowError, "string is too large");
+ return NULL;
+ }
+
+ /* Inline PyObject_NewVar */
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+ if (op == NULL)
+ return PyErr_NoMemory();
+ PyObject_INIT_VAR(op, &PyString_Type, size);
+ op->ob_shash = -1;
+ op->ob_sstate = SSTATE_NOT_INTERNED;
+ if (str != NULL)
+ Py_MEMCPY(op->ob_sval, str, size);
+ op->ob_sval[size] = '\0';
+ /* share short strings */
+ if (size == 0) {
+ PyObject *t = (PyObject *)op;
+ PyString_InternInPlace(&t);
+ op = (PyStringObject *)t;
+ nullstring = op;
+ Py_INCREF(op);
+ } else if (size == 1 && str != NULL) {
+ PyObject *t = (PyObject *)op;
+ PyString_InternInPlace(&t);
+ op = (PyStringObject *)t;
+ characters[*str & UCHAR_MAX] = op;
+ Py_INCREF(op);
+ }
+ return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromString(const char *str)
+{
+ register size_t size;
+ register PyStringObject *op;
+
+ assert(str != NULL);
+ size = strlen(str);
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string is too long for a Python string");
+ return NULL;
+ }
+ if (size == 0 && (op = nullstring) != NULL) {
+#ifdef COUNT_ALLOCS
+ null_strings++;
+#endif
+ Py_INCREF(op);
+ return (PyObject *)op;
+ }
+ if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
+#ifdef COUNT_ALLOCS
+ one_strings++;
+#endif
+ Py_INCREF(op);
+ return (PyObject *)op;
+ }
+
+ /* Inline PyObject_NewVar */
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+ if (op == NULL)
+ return PyErr_NoMemory();
+ PyObject_INIT_VAR(op, &PyString_Type, size);
+ op->ob_shash = -1;
+ op->ob_sstate = SSTATE_NOT_INTERNED;
+ Py_MEMCPY(op->ob_sval, str, size+1);
+ /* share short strings */
+ if (size == 0) {
+ PyObject *t = (PyObject *)op;
+ PyString_InternInPlace(&t);
+ op = (PyStringObject *)t;
+ nullstring = op;
+ Py_INCREF(op);
+ } else if (size == 1) {
+ PyObject *t = (PyObject *)op;
+ PyString_InternInPlace(&t);
+ op = (PyStringObject *)t;
+ characters[*str & UCHAR_MAX] = op;
+ Py_INCREF(op);
+ }
+ return (PyObject *) op;
+}
+
+PyObject *
+PyString_FromFormatV(const char *format, va_list vargs)
+{
+ va_list count;
+ Py_ssize_t n = 0;
+ const char* f;
+ char *s;
+ PyObject* string;
+
+#ifdef VA_LIST_IS_ARRAY
+ Py_MEMCPY(count, vargs, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(count, vargs);
+#else
+ count = vargs;
+#endif
+#endif
+ /* step 1: figure out how large a buffer we need */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+#ifdef HAVE_LONG_LONG
+ int longlongflag = 0;
+#endif
+ const char* p = f;
+ while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ ;
+
+ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+ * they don't affect the amount of space we reserve.
+ */
+ if (*f == 'l') {
+ if (f[1] == 'd' || f[1] == 'u') {
+ ++f;
+ }
+#ifdef HAVE_LONG_LONG
+ else if (f[1] == 'l' &&
+ (f[2] == 'd' || f[2] == 'u')) {
+ longlongflag = 1;
+ f += 2;
+ }
+#endif
+ }
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ ++f;
+ }
+
+ switch (*f) {
+ case 'c':
+ (void)va_arg(count, int);
+ /* fall through... */
+ case '%':
+ n++;
+ break;
+ case 'd': case 'u': case 'i': case 'x':
+ (void) va_arg(count, int);
+#ifdef HAVE_LONG_LONG
+ /* Need at most
+ ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+ plus 1 for the sign. 53/22 is an upper
+ bound for log10(256). */
+ if (longlongflag)
+ n += 2 + (SIZEOF_LONG_LONG*53-1) / 22;
+ else
+#endif
+ /* 20 bytes is enough to hold a 64-bit
+ integer. Decimal takes the most
+ space. This isn't enough for
+ octal. */
+ n += 20;
+
+ break;
+ case 's':
+ s = va_arg(count, char*);
+ n += strlen(s);
+ break;
+ case 'p':
+ (void) va_arg(count, int);
+ /* maximum 64-bit pointer representation:
+ * 0xffffffffffffffff
+ * so 19 characters is enough.
+ * XXX I count 18 -- what's the extra for?
+ */
+ n += 19;
+ break;
+ default:
+ /* if we stumble upon an unknown
+ formatting code, copy the rest of
+ the format string to the output
+ string. (we cannot just skip the
+ code, since there's no way to know
+ what's in the argument list) */
+ n += strlen(p);
+ goto expand;
+ }
+ } else
+ n++;
+ }
+ expand:
+ /* step 2: fill the buffer */
+ /* Since we've analyzed how much space we need for the worst case,
+ use sprintf directly instead of the slower PyOS_snprintf. */
+ string = PyString_FromStringAndSize(NULL, n);
+ if (!string)
+ return NULL;
+
+ s = PyString_AsString(string);
+
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ Py_ssize_t i;
+ int longflag = 0;
+#ifdef HAVE_LONG_LONG
+ int longlongflag = 0;
+#endif
+ int size_tflag = 0;
+ /* parse the width.precision part (we're only
+ interested in the precision value, if any) */
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ if (*f == '.') {
+ f++;
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ }
+ while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ f++;
+ /* Handle %ld, %lu, %lld and %llu. */
+ if (*f == 'l') {
+ if (f[1] == 'd' || f[1] == 'u') {
+ longflag = 1;
+ ++f;
+ }
+#ifdef HAVE_LONG_LONG
+ else if (f[1] == 'l' &&
+ (f[2] == 'd' || f[2] == 'u')) {
+ longlongflag = 1;
+ f += 2;
+ }
+#endif
+ }
+ /* handle the size_t flag. */
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ size_tflag = 1;
+ ++f;
+ }
+
+ switch (*f) {
+ case 'c':
+ *s++ = va_arg(vargs, int);
+ break;
+ case 'd':
+ if (longflag)
+ sprintf(s, "%ld", va_arg(vargs, long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "d",
+ va_arg(vargs, PY_LONG_LONG));
+#endif
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "d",
+ va_arg(vargs, Py_ssize_t));
+ else
+ sprintf(s, "%d", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'u':
+ if (longflag)
+ sprintf(s, "%lu",
+ va_arg(vargs, unsigned long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "u",
+ va_arg(vargs, PY_LONG_LONG));
+#endif
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "u",
+ va_arg(vargs, size_t));
+ else
+ sprintf(s, "%u",
+ va_arg(vargs, unsigned int));
+ s += strlen(s);
+ break;
+ case 'i':
+ sprintf(s, "%i", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'x':
+ sprintf(s, "%x", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 's':
+ p = va_arg(vargs, char*);
+ i = strlen(p);
+ if (n > 0 && i > n)
+ i = n;
+ Py_MEMCPY(s, p, i);
+ s += i;
+ break;
+ case 'p':
+ sprintf(s, "%p", va_arg(vargs, void*));
+ /* %p is ill-defined: ensure leading 0x. */
+ if (s[1] == 'X')
+ s[1] = 'x';
+ else if (s[1] != 'x') {
+ memmove(s+2, s, strlen(s)+1);
+ s[0] = '0';
+ s[1] = 'x';
+ }
+ s += strlen(s);
+ break;
+ case '%':
+ *s++ = '%';
+ break;
+ default:
+ strcpy(s, p);
+ s += strlen(s);
+ goto end;
+ }
+ } else
+ *s++ = *f;
+ }
+
+ end:
+ if (_PyString_Resize(&string, s - PyString_AS_STRING(string)))
+ return NULL;
+ return string;
+}
+
+PyObject *
+PyString_FromFormat(const char *format, ...)
+{
+ PyObject* ret;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ ret = PyString_FromFormatV(format, vargs);
+ va_end(vargs);
+ return ret;
+}
+
+
+PyObject *PyString_Decode(const char *s,
+ Py_ssize_t size,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v, *str;
+
+ str = PyString_FromStringAndSize(s, size);
+ if (str == NULL)
+ return NULL;
+ v = PyString_AsDecodedString(str, encoding, errors);
+ Py_DECREF(str);
+ return v;
+}
+
+PyObject *PyString_AsDecodedObject(PyObject *str,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ if (!PyString_Check(str)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+
+ if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+ encoding = PyUnicode_GetDefaultEncoding();
+#else
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ goto onError;
+#endif
+ }
+
+ /* Decode via the codec registry */
+ v = PyCodec_Decode(str, encoding, errors);
+ if (v == NULL)
+ goto onError;
+
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyString_AsDecodedString(PyObject *str,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ v = PyString_AsDecodedObject(str, encoding, errors);
+ if (v == NULL)
+ goto onError;
+
+#ifdef Py_USING_UNICODE
+ /* Convert Unicode to a string using the default encoding */
+ if (PyUnicode_Check(v)) {
+ PyObject *temp = v;
+ v = PyUnicode_AsEncodedString(v, NULL, NULL);
+ Py_DECREF(temp);
+ if (v == NULL)
+ goto onError;
+ }
+#endif
+ if (!PyString_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "decoder did not return a string object (type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ goto onError;
+ }
+
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyString_Encode(const char *s,
+ Py_ssize_t size,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v, *str;
+
+ str = PyString_FromStringAndSize(s, size);
+ if (str == NULL)
+ return NULL;
+ v = PyString_AsEncodedString(str, encoding, errors);
+ Py_DECREF(str);
+ return v;
+}
+
+PyObject *PyString_AsEncodedObject(PyObject *str,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ if (!PyString_Check(str)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+
+ if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
+ encoding = PyUnicode_GetDefaultEncoding();
+#else
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ goto onError;
+#endif
+ }
+
+ /* Encode via the codec registry */
+ v = PyCodec_Encode(str, encoding, errors);
+ if (v == NULL)
+ goto onError;
+
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyString_AsEncodedString(PyObject *str,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ v = PyString_AsEncodedObject(str, encoding, errors);
+ if (v == NULL)
+ goto onError;
+
+#ifdef Py_USING_UNICODE
+ /* Convert Unicode to a string using the default encoding */
+ if (PyUnicode_Check(v)) {
+ PyObject *temp = v;
+ v = PyUnicode_AsEncodedString(v, NULL, NULL);
+ Py_DECREF(temp);
+ if (v == NULL)
+ goto onError;
+ }
+#endif
+ if (!PyString_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a string object (type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ goto onError;
+ }
+
+ return v;
+
+ onError:
+ return NULL;
+}
+
+static void
+string_dealloc(PyObject *op)
+{
+ switch (PyString_CHECK_INTERNED(op)) {
+ case SSTATE_NOT_INTERNED:
+ break;
+
+ case SSTATE_INTERNED_MORTAL:
+ /* revive dead object temporarily for DelItem */
+ Py_REFCNT(op) = 3;
+ if (PyDict_DelItem(interned, op) != 0)
+ Py_FatalError(
+ "deletion of interned string failed");
+ break;
+
+ case SSTATE_INTERNED_IMMORTAL:
+ Py_FatalError("Immortal interned string died.");
+
+ default:
+ Py_FatalError("Inconsistent interned string state.");
+ }
+ Py_TYPE(op)->tp_free(op);
+}
+
+/* Unescape a backslash-escaped string. If unicode is non-zero,
+ the string is a u-literal. If recode_encoding is non-zero,
+ the string is UTF-8 encoded and should be re-encoded in the
+ specified encoding. */
+
+PyObject *PyString_DecodeEscape(const char *s,
+ Py_ssize_t len,
+ const char *errors,
+ Py_ssize_t unicode,
+ const char *recode_encoding)
+{
+ int c;
+ char *p, *buf;
+ const char *end;
+ PyObject *v;
+ Py_ssize_t newlen = recode_encoding ? 4*len:len;
+ v = PyString_FromStringAndSize((char *)NULL, newlen);
+ if (v == NULL)
+ return NULL;
+ p = buf = PyString_AsString(v);
+ end = s + len;
+ while (s < end) {
+ if (*s != '\\') {
+ non_esc:
+#ifdef Py_USING_UNICODE
+ if (recode_encoding && (*s & 0x80)) {
+ PyObject *u, *w;
+ char *r;
+ const char* t;
+ Py_ssize_t rn;
+ t = s;
+ /* Decode non-ASCII bytes as UTF-8. */
+ while (t < end && (*t & 0x80)) t++;
+ u = PyUnicode_DecodeUTF8(s, t - s, errors);
+ if(!u) goto failed;
+
+ /* Recode them in target encoding. */
+ w = PyUnicode_AsEncodedString(
+ u, recode_encoding, errors);
+ Py_DECREF(u);
+ if (!w) goto failed;
+
+ /* Append bytes to output buffer. */
+ assert(PyString_Check(w));
+ r = PyString_AS_STRING(w);
+ rn = PyString_GET_SIZE(w);
+ Py_MEMCPY(p, r, rn);
+ p += rn;
+ Py_DECREF(w);
+ s = t;
+ } else {
+ *p++ = *s++;
+ }
+#else
+ *p++ = *s++;
+#endif
+ continue;
+ }
+ s++;
+ if (s==end) {
+ PyErr_SetString(PyExc_ValueError,
+ "Trailing \\ in string");
+ goto failed;
+ }
+ switch (*s++) {
+ /* XXX This assumes ASCII! */
+ case '\n': break;
+ case '\\': *p++ = '\\'; break;
+ case '\'': *p++ = '\''; break;
+ case '\"': *p++ = '\"'; break;
+ case 'b': *p++ = '\b'; break;
+ case 'f': *p++ = '\014'; break; /* FF */
+ case 't': *p++ = '\t'; break;
+ case 'n': *p++ = '\n'; break;
+ case 'r': *p++ = '\r'; break;
+ case 'v': *p++ = '\013'; break; /* VT */
+ case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c = s[-1] - '0';
+ if (s < end && '0' <= *s && *s <= '7') {
+ c = (c<<3) + *s++ - '0';
+ if (s < end && '0' <= *s && *s <= '7')
+ c = (c<<3) + *s++ - '0';
+ }
+ *p++ = c;
+ break;
+ case 'x':
+ if (s+1 < end &&
+ isxdigit(Py_CHARMASK(s[0])) &&
+ isxdigit(Py_CHARMASK(s[1])))
+ {
+ unsigned int x = 0;
+ c = Py_CHARMASK(*s);
+ s++;
+ if (isdigit(c))
+ x = c - '0';
+ else if (islower(c))
+ x = 10 + c - 'a';
+ else
+ x = 10 + c - 'A';
+ x = x << 4;
+ c = Py_CHARMASK(*s);
+ s++;
+ if (isdigit(c))
+ x += c - '0';
+ else if (islower(c))
+ x += 10 + c - 'a';
+ else
+ x += 10 + c - 'A';
+ *p++ = x;
+ break;
+ }
+ if (!errors || strcmp(errors, "strict") == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid \\x escape");
+ goto failed;
+ }
+ if (strcmp(errors, "replace") == 0) {
+ *p++ = '?';
+ } else if (strcmp(errors, "ignore") == 0)
+ /* do nothing */;
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "decoding error; "
+ "unknown error handling code: %.400s",
+ errors);
+ goto failed;
+ }
+ /* skip \x */
+ if (s < end && isxdigit(Py_CHARMASK(s[0])))
+ s++; /* and a hexdigit */
+ break;
+#ifndef Py_USING_UNICODE
+ case 'u':
+ case 'U':
+ case 'N':
+ if (unicode) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unicode escapes not legal "
+ "when Unicode disabled");
+ goto failed;
+ }
+#endif
+ default:
+ *p++ = '\\';
+ s--;
+ goto non_esc; /* an arbitrary number of unescaped
+ UTF-8 bytes may follow. */
+ }
+ }
+ if (p-buf < newlen)
+ _PyString_Resize(&v, p - buf); /* v is cleared on error */
+ return v;
+ failed:
+ Py_DECREF(v);
+ return NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* object api */
+
+static Py_ssize_t
+string_getsize(register PyObject *op)
+{
+ char *s;
+ Py_ssize_t len;
+ if (PyString_AsStringAndSize(op, &s, &len))
+ return -1;
+ return len;
+}
+
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
+{
+ char *s;
+ Py_ssize_t len;
+ if (PyString_AsStringAndSize(op, &s, &len))
+ return NULL;
+ return s;
+}
+
+Py_ssize_t
+PyString_Size(register PyObject *op)
+{
+ if (!PyString_Check(op))
+ return string_getsize(op);
+ return Py_SIZE(op);
+}
+
+/*const*/ char *
+PyString_AsString(register PyObject *op)
+{
+ if (!PyString_Check(op))
+ return string_getbuffer(op);
+ return ((PyStringObject *)op) -> ob_sval;
+}
+
+int
+PyString_AsStringAndSize(register PyObject *obj,
+ register char **s,
+ register Py_ssize_t *len)
+{
+ if (s == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ if (!PyString_Check(obj)) {
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(obj)) {
+ obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+ if (obj == NULL)
+ return -1;
+ }
+ else
+#endif
+ {
+ PyErr_Format(PyExc_TypeError,
+ "expected string or Unicode object, "
+ "%.200s found", Py_TYPE(obj)->tp_name);
+ return -1;
+ }
+ }
+
+ *s = PyString_AS_STRING(obj);
+ if (len != NULL)
+ *len = PyString_GET_SIZE(obj);
+ else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "expected string without null bytes");
+ return -1;
+ }
+ return 0;
+}
+
+/* -------------------------------------------------------------------- */
+/* Methods */
+
+#include "stringlib/stringdefs.h"
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+
+#define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
+#include "stringlib/localeutil.h"
+
+
+
+static int
+string_print(PyStringObject *op, FILE *fp, int flags)
+{
+ Py_ssize_t i, str_len;
+ char c;
+ int quote;
+
+ /* XXX Ought to check for interrupts when writing long strings */
+ if (! PyString_CheckExact(op)) {
+ int ret;
+ /* A str subclass may have its own __str__ method. */
+ op = (PyStringObject *) PyObject_Str((PyObject *)op);
+ if (op == NULL)
+ return -1;
+ ret = string_print(op, fp, flags);
+ Py_DECREF(op);
+ return ret;
+ }
+ if (flags & Py_PRINT_RAW) {
+ char *data = op->ob_sval;
+ Py_ssize_t size = Py_SIZE(op);
+ Py_BEGIN_ALLOW_THREADS
+ while (size > INT_MAX) {
+ /* Very long strings cannot be written atomically.
+ * But don't write exactly INT_MAX bytes at a time
+ * to avoid memory aligment issues.
+ */
+ const int chunk_size = INT_MAX & ~0x3FFF;
+ fwrite(data, 1, chunk_size, fp);
+ data += chunk_size;
+ size -= chunk_size;
+ }
+#ifdef __VMS
+ if (size) fwrite(data, (size_t)size, 1, fp);
+#else
+ fwrite(data, 1, (size_t)size, fp);
+#endif
+ Py_END_ALLOW_THREADS
+ return 0;
+ }
+
+ /* figure out which quote to use; single is preferred */
+ quote = '\'';
+ if (memchr(op->ob_sval, '\'', Py_SIZE(op)) &&
+ !memchr(op->ob_sval, '"', Py_SIZE(op)))
+ quote = '"';
+
+ str_len = Py_SIZE(op);
+ Py_BEGIN_ALLOW_THREADS
+ fputc(quote, fp);
+ for (i = 0; i < str_len; i++) {
+ /* Since strings are immutable and the caller should have a
+ reference, accessing the interal buffer should not be an issue
+ with the GIL released. */
+ c = op->ob_sval[i];
+ if (c == quote || c == '\\')
+ fprintf(fp, "\\%c", c);
+ else if (c == '\t')
+ fprintf(fp, "\\t");
+ else if (c == '\n')
+ fprintf(fp, "\\n");
+ else if (c == '\r')
+ fprintf(fp, "\\r");
+ else if (c < ' ' || c >= 0x7f)
+ fprintf(fp, "\\x%02x", c & 0xff);
+ else
+ fputc(c, fp);
+ }
+ fputc(quote, fp);
+ Py_END_ALLOW_THREADS
+ return 0;
+}
+
+PyObject *
+PyString_Repr(PyObject *obj, int smartquotes)
+{
+ register PyStringObject* op = (PyStringObject*) obj;
+ size_t newsize;
+ PyObject *v;
+ if (Py_SIZE(op) > (PY_SSIZE_T_MAX - 2)/4) {
+ PyErr_SetString(PyExc_OverflowError,
+ "string is too large to make repr");
+ return NULL;
+ }
+ newsize = 2 + 4*Py_SIZE(op);
+ v = PyString_FromStringAndSize((char *)NULL, newsize);
+ if (v == NULL) {
+ return NULL;
+ }
+ else {
+ register Py_ssize_t i;
+ register char c;
+ register char *p;
+ int quote;
+
+ /* figure out which quote to use; single is preferred */
+ quote = '\'';
+ if (smartquotes &&
+ memchr(op->ob_sval, '\'', Py_SIZE(op)) &&
+ !memchr(op->ob_sval, '"', Py_SIZE(op)))
+ quote = '"';
+
+ p = PyString_AS_STRING(v);
+ *p++ = quote;
+ for (i = 0; i < Py_SIZE(op); i++) {
+ /* There's at least enough room for a hex escape
+ and a closing quote. */
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+ c = op->ob_sval[i];
+ if (c == quote || c == '\\')
+ *p++ = '\\', *p++ = c;
+ else if (c == '\t')
+ *p++ = '\\', *p++ = 't';
+ else if (c == '\n')
+ *p++ = '\\', *p++ = 'n';
+ else if (c == '\r')
+ *p++ = '\\', *p++ = 'r';
+ else if (c < ' ' || c >= 0x7f) {
+ /* For performance, we don't want to call
+ PyOS_snprintf here (extra layers of
+ function call). */
+ sprintf(p, "\\x%02x", c & 0xff);
+ p += 4;
+ }
+ else
+ *p++ = c;
+ }
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+ *p++ = quote;
+ *p = '\0';
+ if (_PyString_Resize(&v, (p - PyString_AS_STRING(v))))
+ return NULL;
+ return v;
+ }
+}
+
+static PyObject *
+string_repr(PyObject *op)
+{
+ return PyString_Repr(op, 1);
+}
+
+static PyObject *
+string_str(PyObject *s)
+{
+ assert(PyString_Check(s));
+ if (PyString_CheckExact(s)) {
+ Py_INCREF(s);
+ return s;
+ }
+ else {
+ /* Subtype -- return genuine string with the same value. */
+ PyStringObject *t = (PyStringObject *) s;
+ return PyString_FromStringAndSize(t->ob_sval, Py_SIZE(t));
+ }
+}
+
+static Py_ssize_t
+string_length(PyStringObject *a)
+{
+ return Py_SIZE(a);
+}
+
+static PyObject *
+string_concat(register PyStringObject *a, register PyObject *bb)
+{
+ register Py_ssize_t size;
+ register PyStringObject *op;
+ if (!PyString_Check(bb)) {
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(bb))
+ return PyUnicode_Concat((PyObject *)a, bb);
+#endif
+ if (PyByteArray_Check(bb))
+ return PyByteArray_Concat((PyObject *)a, bb);
+ PyErr_Format(PyExc_TypeError,
+ "cannot concatenate 'str' and '%.200s' objects",
+ Py_TYPE(bb)->tp_name);
+ return NULL;
+ }
+#define b ((PyStringObject *)bb)
+ /* Optimize cases with empty left or right operand */
+ if ((Py_SIZE(a) == 0 || Py_SIZE(b) == 0) &&
+ PyString_CheckExact(a) && PyString_CheckExact(b)) {
+ if (Py_SIZE(a) == 0) {
+ Py_INCREF(bb);
+ return bb;
+ }
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ size = Py_SIZE(a) + Py_SIZE(b);
+ /* Check that string sizes are not negative, to prevent an
+ overflow in cases where we are passed incorrectly-created
+ strings with negative lengths (due to a bug in other code).
+ */
+ if (Py_SIZE(a) < 0 || Py_SIZE(b) < 0 ||
+ Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "strings are too large to concat");
+ return NULL;
+ }
+
+ /* Inline PyObject_NewVar */
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
+ PyErr_SetString(PyExc_OverflowError,
+ "strings are too large to concat");
+ return NULL;
+ }
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
+ if (op == NULL)
+ return PyErr_NoMemory();
+ PyObject_INIT_VAR(op, &PyString_Type, size);
+ op->ob_shash = -1;
+ op->ob_sstate = SSTATE_NOT_INTERNED;
+ Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
+ Py_MEMCPY(op->ob_sval + Py_SIZE(a), b->ob_sval, Py_SIZE(b));
+ op->ob_sval[size] = '\0';
+ return (PyObject *) op;
+#undef b
+}
+
+static PyObject *
+string_repeat(register PyStringObject *a, register Py_ssize_t n)
+{
+ register Py_ssize_t i;
+ register Py_ssize_t j;
+ register Py_ssize_t size;
+ register PyStringObject *op;
+ size_t nbytes;
+ if (n < 0)
+ n = 0;
+ /* watch out for overflows: the size can overflow int,
+ * and the # of bytes needed can overflow size_t
+ */
+ size = Py_SIZE(a) * n;
+ if (n && size / n != Py_SIZE(a)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ if (size == Py_SIZE(a) && PyString_CheckExact(a)) {
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ nbytes = (size_t)size;
+ if (nbytes + PyStringObject_SIZE <= nbytes) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes);
+ if (op == NULL)
+ return PyErr_NoMemory();
+ PyObject_INIT_VAR(op, &PyString_Type, size);
+ op->ob_shash = -1;
+ op->ob_sstate = SSTATE_NOT_INTERNED;
+ op->ob_sval[size] = '\0';
+ if (Py_SIZE(a) == 1 && n > 0) {
+ memset(op->ob_sval, a->ob_sval[0] , n);
+ return (PyObject *) op;
+ }
+ i = 0;
+ if (i < size) {
+ Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
+ i = Py_SIZE(a);
+ }
+ while (i < size) {
+ j = (i <= size-i) ? i : size-i;
+ Py_MEMCPY(op->ob_sval+i, op->ob_sval, j);
+ i += j;
+ }
+ return (PyObject *) op;
+}
+
+/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
+
+static PyObject *
+string_slice(register PyStringObject *a, register Py_ssize_t i,
+ register Py_ssize_t j)
+ /* j -- may be negative! */
+{
+ if (i < 0)
+ i = 0;
+ if (j < 0)
+ j = 0; /* Avoid signed/unsigned bug in next line */
+ if (j > Py_SIZE(a))
+ j = Py_SIZE(a);
+ if (i == 0 && j == Py_SIZE(a) && PyString_CheckExact(a)) {
+ /* It's the same as a */
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ if (j < i)
+ j = i;
+ return PyString_FromStringAndSize(a->ob_sval + i, j-i);
+}
+
+static int
+string_contains(PyObject *str_obj, PyObject *sub_obj)
+{
+ if (!PyString_CheckExact(sub_obj)) {
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(sub_obj))
+ return PyUnicode_Contains(str_obj, sub_obj);
+#endif
+ if (!PyString_Check(sub_obj)) {
+ PyErr_Format(PyExc_TypeError,
+ "'in <string>' requires string as left operand, "
+ "not %.200s", Py_TYPE(sub_obj)->tp_name);
+ return -1;
+ }
+ }
+
+ return stringlib_contains_obj(str_obj, sub_obj);
+}
+
+static PyObject *
+string_item(PyStringObject *a, register Py_ssize_t i)
+{
+ char pchar;
+ PyObject *v;
+ if (i < 0 || i >= Py_SIZE(a)) {
+ PyErr_SetString(PyExc_IndexError, "string index out of range");
+ return NULL;
+ }
+ pchar = a->ob_sval[i];
+ v = (PyObject *)characters[pchar & UCHAR_MAX];
+ if (v == NULL)
+ v = PyString_FromStringAndSize(&pchar, 1);
+ else {
+#ifdef COUNT_ALLOCS
+ one_strings++;
+#endif
+ Py_INCREF(v);
+ }
+ return v;
+}
+
+static PyObject*
+string_richcompare(PyStringObject *a, PyStringObject *b, int op)
+{
+ int c;
+ Py_ssize_t len_a, len_b;
+ Py_ssize_t min_len;
+ PyObject *result;
+
+ /* Make sure both arguments are strings. */
+ if (!(PyString_Check(a) && PyString_Check(b))) {
+ result = Py_NotImplemented;
+ goto out;
+ }
+ if (a == b) {
+ switch (op) {
+ case Py_EQ:case Py_LE:case Py_GE:
+ result = Py_True;
+ goto out;
+ case Py_NE:case Py_LT:case Py_GT:
+ result = Py_False;
+ goto out;
+ }
+ }
+ if (op == Py_EQ) {
+ /* Supporting Py_NE here as well does not save
+ much time, since Py_NE is rarely used. */
+ if (Py_SIZE(a) == Py_SIZE(b)
+ && (a->ob_sval[0] == b->ob_sval[0]
+ && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) {
+ result = Py_True;
+ } else {
+ result = Py_False;
+ }
+ goto out;
+ }
+ len_a = Py_SIZE(a); len_b = Py_SIZE(b);
+ min_len = (len_a < len_b) ? len_a : len_b;
+ if (min_len > 0) {
+ c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
+ if (c==0)
+ c = memcmp(a->ob_sval, b->ob_sval, min_len);
+ } else
+ c = 0;
+ if (c == 0)
+ c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+ switch (op) {
+ case Py_LT: c = c < 0; break;
+ case Py_LE: c = c <= 0; break;
+ case Py_EQ: assert(0); break; /* unreachable */
+ case Py_NE: c = c != 0; break;
+ case Py_GT: c = c > 0; break;
+ case Py_GE: c = c >= 0; break;
+ default:
+ result = Py_NotImplemented;
+ goto out;
+ }
+ result = c ? Py_True : Py_False;
+ out:
+ Py_INCREF(result);
+ return result;
+}
+
+int
+_PyString_Eq(PyObject *o1, PyObject *o2)
+{
+ PyStringObject *a = (PyStringObject*) o1;
+ PyStringObject *b = (PyStringObject*) o2;
+ return Py_SIZE(a) == Py_SIZE(b)
+ && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0;
+}
+
+static long
+string_hash(PyStringObject *a)
+{
+ register Py_ssize_t len;
+ register unsigned char *p;
+ register long x;
+
+#ifdef Py_DEBUG
+ assert(_Py_HashSecret_Initialized);
+#endif
+ if (a->ob_shash != -1)
+ return a->ob_shash;
+ len = Py_SIZE(a);
+ /*
+ We make the hash of the empty string be 0, rather than using
+ (prefix ^ suffix), since this slightly obfuscates the hash secret
+ */
+ if (len == 0) {
+ a->ob_shash = 0;
+ return 0;
+ }
+ p = (unsigned char *) a->ob_sval;
+ x = _Py_HashSecret.prefix;
+ x ^= *p << 7;
+ while (--len >= 0)
+ x = (1000003*x) ^ *p++;
+ x ^= Py_SIZE(a);
+ x ^= _Py_HashSecret.suffix;
+ if (x == -1)
+ x = -2;
+ a->ob_shash = x;
+ return x;
+}
+
+static PyObject*
+string_subscript(PyStringObject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyString_GET_SIZE(self);
+ return string_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ char* source_buf;
+ char* result_buf;
+ PyObject* result;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item,
+ PyString_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyString_FromStringAndSize("", 0);
+ }
+ else if (start == 0 && step == 1 &&
+ slicelength == PyString_GET_SIZE(self) &&
+ PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ else if (step == 1) {
+ return PyString_FromStringAndSize(
+ PyString_AS_STRING(self) + start,
+ slicelength);
+ }
+ else {
+ source_buf = PyString_AsString((PyObject*)self);
+ result_buf = (char *)PyMem_Malloc(slicelength);
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+
+ result = PyString_FromStringAndSize(result_buf,
+ slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "string indices must be integers, not %.200s",
+ Py_TYPE(item)->tp_name);
+ return NULL;
+ }
+}
+
+static Py_ssize_t
+string_buffer_getreadbuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent string segment");
+ return -1;
+ }
+ *ptr = (void *)self->ob_sval;
+ return Py_SIZE(self);
+}
+
+static Py_ssize_t
+string_buffer_getwritebuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot use string as modifiable buffer");
+ return -1;
+}
+
+static Py_ssize_t
+string_buffer_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
+{
+ if ( lenp )
+ *lenp = Py_SIZE(self);
+ return 1;
+}
+
+static Py_ssize_t
+string_buffer_getcharbuf(PyStringObject *self, Py_ssize_t index, const char **ptr)
+{
+ if ( index != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent string segment");
+ return -1;
+ }
+ *ptr = self->ob_sval;
+ return Py_SIZE(self);
+}
+
+static int
+string_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags)
+{
+ return PyBuffer_FillInfo(view, (PyObject*)self,
+ (void *)self->ob_sval, Py_SIZE(self),
+ 1, flags);
+}
+
+static PySequenceMethods string_as_sequence = {
+ (lenfunc)string_length, /*sq_length*/
+ (binaryfunc)string_concat, /*sq_concat*/
+ (ssizeargfunc)string_repeat, /*sq_repeat*/
+ (ssizeargfunc)string_item, /*sq_item*/
+ (ssizessizeargfunc)string_slice, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ (objobjproc)string_contains /*sq_contains*/
+};
+
+static PyMappingMethods string_as_mapping = {
+ (lenfunc)string_length,
+ (binaryfunc)string_subscript,
+ 0,
+};
+
+static PyBufferProcs string_as_buffer = {
+ (readbufferproc)string_buffer_getreadbuf,
+ (writebufferproc)string_buffer_getwritebuf,
+ (segcountproc)string_buffer_getsegcount,
+ (charbufferproc)string_buffer_getcharbuf,
+ (getbufferproc)string_buffer_getbuffer,
+ 0, /* XXX */
+};
+
+
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+PyDoc_STRVAR(split__doc__,
+"S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string. If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator and empty strings are removed\n\
+from the result.");
+
+static PyObject *
+string_split(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t len = PyString_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyString_AS_STRING(self), *sub;
+ PyObject *subobj = Py_None;
+
+ if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
+ return NULL;
+ if (maxsplit < 0)
+ maxsplit = PY_SSIZE_T_MAX;
+ if (subobj == Py_None)
+ return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
+ if (PyString_Check(subobj)) {
+ sub = PyString_AS_STRING(subobj);
+ n = PyString_GET_SIZE(subobj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(subobj))
+ return PyUnicode_Split((PyObject *)self, subobj, maxsplit);
+#endif
+ else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+ return NULL;
+
+ return stringlib_split((PyObject*) self, s, len, sub, n, maxsplit);
+}
+
+PyDoc_STRVAR(partition__doc__,
+"S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, and return the part before it,\n\
+the separator itself, and the part after it. If the separator is not\n\
+found, return S and two empty strings.");
+
+static PyObject *
+string_partition(PyStringObject *self, PyObject *sep_obj)
+{
+ const char *sep;
+ Py_ssize_t sep_len;
+
+ if (PyString_Check(sep_obj)) {
+ sep = PyString_AS_STRING(sep_obj);
+ sep_len = PyString_GET_SIZE(sep_obj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(sep_obj))
+ return PyUnicode_Partition((PyObject *) self, sep_obj);
+#endif
+ else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+ return NULL;
+
+ return stringlib_partition(
+ (PyObject*) self,
+ PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ sep_obj, sep, sep_len
+ );
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+"S.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, starting at the end of S, and return\n\
+the part before it, the separator itself, and the part after it. If the\n\
+separator is not found, return two empty strings and S.");
+
+static PyObject *
+string_rpartition(PyStringObject *self, PyObject *sep_obj)
+{
+ const char *sep;
+ Py_ssize_t sep_len;
+
+ if (PyString_Check(sep_obj)) {
+ sep = PyString_AS_STRING(sep_obj);
+ sep_len = PyString_GET_SIZE(sep_obj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(sep_obj))
+ return PyUnicode_RPartition((PyObject *) self, sep_obj);
+#endif
+ else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+ return NULL;
+
+ return stringlib_rpartition(
+ (PyObject*) self,
+ PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ sep_obj, sep, sep_len
+ );
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+"S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in the string S, using sep as the\n\
+delimiter string, starting at the end of the string and working\n\
+to the front. If maxsplit is given, at most maxsplit splits are\n\
+done. If sep is not specified or is None, any whitespace string\n\
+is a separator.");
+
+static PyObject *
+string_rsplit(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t len = PyString_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyString_AS_STRING(self), *sub;
+ PyObject *subobj = Py_None;
+
+ if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
+ return NULL;
+ if (maxsplit < 0)
+ maxsplit = PY_SSIZE_T_MAX;
+ if (subobj == Py_None)
+ return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
+ if (PyString_Check(subobj)) {
+ sub = PyString_AS_STRING(subobj);
+ n = PyString_GET_SIZE(subobj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(subobj))
+ return PyUnicode_RSplit((PyObject *)self, subobj, maxsplit);
+#endif
+ else if (PyObject_AsCharBuffer(subobj, &sub, &n))
+ return NULL;
+
+ return stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit);
+}
+
+
+PyDoc_STRVAR(join__doc__,
+"S.join(iterable) -> string\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+iterable. The separator between elements is S.");
+
+static PyObject *
+string_join(PyStringObject *self, PyObject *orig)
+{
+ char *sep = PyString_AS_STRING(self);
+ const Py_ssize_t seplen = PyString_GET_SIZE(self);
+ PyObject *res = NULL;
+ char *p;
+ Py_ssize_t seqlen = 0;
+ size_t sz = 0;
+ Py_ssize_t i;
+ PyObject *seq, *item;
+
+ seq = PySequence_Fast(orig, "can only join an iterable");
+ if (seq == NULL) {
+ return NULL;
+ }
+
+ seqlen = PySequence_Size(seq);
+ if (seqlen == 0) {
+ Py_DECREF(seq);
+ return PyString_FromString("");
+ }
+ if (seqlen == 1) {
+ item = PySequence_Fast_GET_ITEM(seq, 0);
+ if (PyString_CheckExact(item) || PyUnicode_CheckExact(item)) {
+ Py_INCREF(item);
+ Py_DECREF(seq);
+ return item;
+ }
+ }
+
+ /* There are at least two things to join, or else we have a subclass
+ * of the builtin types in the sequence.
+ * Do a pre-pass to figure out the total amount of space we'll
+ * need (sz), see whether any argument is absurd, and defer to
+ * the Unicode join if appropriate.
+ */
+ for (i = 0; i < seqlen; i++) {
+ const size_t old_sz = sz;
+ item = PySequence_Fast_GET_ITEM(seq, i);
+ if (!PyString_Check(item)){
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(item)) {
+ /* Defer to Unicode join.
+ * CAUTION: There's no gurantee that the
+ * original sequence can be iterated over
+ * again, so we must pass seq here.
+ */
+ PyObject *result;
+ result = PyUnicode_Join((PyObject *)self, seq);
+ Py_DECREF(seq);
+ return result;
+ }
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "sequence item %zd: expected string,"
+ " %.80s found",
+ i, Py_TYPE(item)->tp_name);
+ Py_DECREF(seq);
+ return NULL;
+ }
+ sz += PyString_GET_SIZE(item);
+ if (i != 0)
+ sz += seplen;
+ if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "join() result is too long for a Python string");
+ Py_DECREF(seq);
+ return NULL;
+ }
+ }
+
+ /* Allocate result space. */
+ res = PyString_FromStringAndSize((char*)NULL, sz);
+ if (res == NULL) {
+ Py_DECREF(seq);
+ return NULL;
+ }
+
+ /* Catenate everything. */
+ p = PyString_AS_STRING(res);
+ for (i = 0; i < seqlen; ++i) {
+ size_t n;
+ item = PySequence_Fast_GET_ITEM(seq, i);
+ n = PyString_GET_SIZE(item);
+ Py_MEMCPY(p, PyString_AS_STRING(item), n);
+ p += n;
+ if (i < seqlen - 1) {
+ Py_MEMCPY(p, sep, seplen);
+ p += seplen;
+ }
+ }
+
+ Py_DECREF(seq);
+ return res;
+}
+
+PyObject *
+_PyString_Join(PyObject *sep, PyObject *x)
+{
+ assert(sep != NULL && PyString_Check(sep));
+ assert(x != NULL);
+ return string_join((PyStringObject *)sep, x);
+}
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
+
+Py_LOCAL_INLINE(Py_ssize_t)
+string_find_internal(PyStringObject *self, PyObject *args, int dir)
+{
+ PyObject *subobj;
+ const char *sub;
+ Py_ssize_t sub_len;
+ Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
+
+ if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+ args, &subobj, &start, &end))
+ return -2;
+
+ if (PyString_Check(subobj)) {
+ sub = PyString_AS_STRING(subobj);
+ sub_len = PyString_GET_SIZE(subobj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(subobj))
+ return PyUnicode_Find(
+ (PyObject *)self, subobj, start, end, dir);
+#endif
+ else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
+ /* XXX - the "expected a character buffer object" is pretty
+ confusing for a non-expert. remap to something else ? */
+ return -2;
+
+ if (dir > 0)
+ return stringlib_find_slice(
+ PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ sub, sub_len, start, end);
+ else
+ return stringlib_rfind_slice(
+ PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ sub, sub_len, start, end);
+}
+
+
+PyDoc_STRVAR(find__doc__,
+"S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_find(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t result = string_find_internal(self, args, +1);
+ if (result == -2)
+ return NULL;
+ return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(index__doc__,
+"S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_index(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t result = string_find_internal(self, args, +1);
+ if (result == -2)
+ return NULL;
+ if (result == -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "substring not found");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rfind__doc__,
+"S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+string_rfind(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t result = string_find_internal(self, args, -1);
+ if (result == -2)
+ return NULL;
+ return PyInt_FromSsize_t(result);
+}
+
+
+PyDoc_STRVAR(rindex__doc__,
+"S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+string_rindex(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t result = string_find_internal(self, args, -1);
+ if (result == -2)
+ return NULL;
+ if (result == -1) {
+ PyErr_SetString(PyExc_ValueError,
+ "substring not found");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(result);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
+{
+ char *s = PyString_AS_STRING(self);
+ Py_ssize_t len = PyString_GET_SIZE(self);
+ char *sep = PyString_AS_STRING(sepobj);
+ Py_ssize_t seplen = PyString_GET_SIZE(sepobj);
+ Py_ssize_t i, j;
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
+ i++;
+ }
+ }
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
+ j++;
+ }
+
+ if (i == 0 && j == len && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+ else
+ return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_strip(PyStringObject *self, int striptype)
+{
+ char *s = PyString_AS_STRING(self);
+ Py_ssize_t len = PyString_GET_SIZE(self), i, j;
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && isspace(Py_CHARMASK(s[i]))) {
+ i++;
+ }
+ }
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && isspace(Py_CHARMASK(s[j])));
+ j++;
+ }
+
+ if (i == 0 && j == len && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+ else
+ return PyString_FromStringAndSize(s+i, j-i);
+}
+
+
+Py_LOCAL_INLINE(PyObject *)
+do_argstrip(PyStringObject *self, int striptype, PyObject *args)
+{
+ PyObject *sep = NULL;
+
+ if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+ return NULL;
+
+ if (sep != NULL && sep != Py_None) {
+ if (PyString_Check(sep))
+ return do_xstrip(self, striptype, sep);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(sep)) {
+ PyObject *uniself = PyUnicode_FromObject((PyObject *)self);
+ PyObject *res;
+ if (uniself==NULL)
+ return NULL;
+ res = _PyUnicode_XStrip((PyUnicodeObject *)uniself,
+ striptype, sep);
+ Py_DECREF(uniself);
+ return res;
+ }
+#endif
+ PyErr_Format(PyExc_TypeError,
+#ifdef Py_USING_UNICODE
+ "%s arg must be None, str or unicode",
+#else
+ "%s arg must be None or str",
+#endif
+ STRIPNAME(striptype));
+ return NULL;
+ }
+
+ return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+"S.strip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_strip(PyStringObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, BOTHSTRIP); /* Common case */
+ else
+ return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+"S.lstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_lstrip(PyStringObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, LEFTSTRIP); /* Common case */
+ else
+ return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+"S.rstrip([chars]) -> string or unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is unicode, S will be converted to unicode before stripping");
+
+static PyObject *
+string_rstrip(PyStringObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, RIGHTSTRIP); /* Common case */
+ else
+ return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lower__doc__,
+"S.lower() -> string\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+/* _tolower and _toupper are defined by SUSv2, but they're not ISO C */
+#ifndef _tolower
+#define _tolower tolower
+#endif
+
+static PyObject *
+string_lower(PyStringObject *self)
+{
+ char *s;
+ Py_ssize_t i, n = PyString_GET_SIZE(self);
+ PyObject *newobj;
+
+ newobj = PyString_FromStringAndSize(NULL, n);
+ if (!newobj)
+ return NULL;
+
+ s = PyString_AS_STRING(newobj);
+
+ Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(s[i]);
+ if (isupper(c))
+ s[i] = _tolower(c);
+ }
+
+ return newobj;
+}
+
+PyDoc_STRVAR(upper__doc__,
+"S.upper() -> string\n\
+\n\
+Return a copy of the string S converted to uppercase.");
+
+#ifndef _toupper
+#define _toupper toupper
+#endif
+
+static PyObject *
+string_upper(PyStringObject *self)
+{
+ char *s;
+ Py_ssize_t i, n = PyString_GET_SIZE(self);
+ PyObject *newobj;
+
+ newobj = PyString_FromStringAndSize(NULL, n);
+ if (!newobj)
+ return NULL;
+
+ s = PyString_AS_STRING(newobj);
+
+ Py_MEMCPY(s, PyString_AS_STRING(self), n);
+
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(s[i]);
+ if (islower(c))
+ s[i] = _toupper(c);
+ }
+
+ return newobj;
+}
+
+PyDoc_STRVAR(title__doc__,
+"S.title() -> string\n\
+\n\
+Return a titlecased version of S, i.e. words start with uppercase\n\
+characters, all remaining cased characters have lowercase.");
+
+static PyObject*
+string_title(PyStringObject *self)
+{
+ char *s = PyString_AS_STRING(self), *s_new;
+ Py_ssize_t i, n = PyString_GET_SIZE(self);
+ int previous_is_cased = 0;
+ PyObject *newobj;
+
+ newobj = PyString_FromStringAndSize(NULL, n);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c)) {
+ if (!previous_is_cased)
+ c = toupper(c);
+ previous_is_cased = 1;
+ } else if (isupper(c)) {
+ if (previous_is_cased)
+ c = tolower(c);
+ previous_is_cased = 1;
+ } else
+ previous_is_cased = 0;
+ *s_new++ = c;
+ }
+ return newobj;
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+"S.capitalize() -> string\n\
+\n\
+Return a copy of the string S with only its first character\n\
+capitalized.");
+
+static PyObject *
+string_capitalize(PyStringObject *self)
+{
+ char *s = PyString_AS_STRING(self), *s_new;
+ Py_ssize_t i, n = PyString_GET_SIZE(self);
+ PyObject *newobj;
+
+ newobj = PyString_FromStringAndSize(NULL, n);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ if (0 < n) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c))
+ *s_new = toupper(c);
+ else
+ *s_new = c;
+ s_new++;
+ }
+ for (i = 1; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (isupper(c))
+ *s_new = tolower(c);
+ else
+ *s_new = c;
+ s_new++;
+ }
+ return newobj;
+}
+
+
+PyDoc_STRVAR(count__doc__,
+"S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+string S[start:end]. Optional arguments start and end are interpreted\n\
+as in slice notation.");
+
+static PyObject *
+string_count(PyStringObject *self, PyObject *args)
+{
+ PyObject *sub_obj;
+ const char *str = PyString_AS_STRING(self), *sub;
+ Py_ssize_t sub_len;
+ Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
+
+ if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
+ return NULL;
+
+ if (PyString_Check(sub_obj)) {
+ sub = PyString_AS_STRING(sub_obj);
+ sub_len = PyString_GET_SIZE(sub_obj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(sub_obj)) {
+ Py_ssize_t count;
+ count = PyUnicode_Count((PyObject *)self, sub_obj, start, end);
+ if (count == -1)
+ return NULL;
+ else
+ return PyInt_FromSsize_t(count);
+ }
+#endif
+ else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
+ return NULL;
+
+ ADJUST_INDICES(start, end, PyString_GET_SIZE(self));
+
+ return PyInt_FromSsize_t(
+ stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
+ );
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+"S.swapcase() -> string\n\
+\n\
+Return a copy of the string S with uppercase characters\n\
+converted to lowercase and vice versa.");
+
+static PyObject *
+string_swapcase(PyStringObject *self)
+{
+ char *s = PyString_AS_STRING(self), *s_new;
+ Py_ssize_t i, n = PyString_GET_SIZE(self);
+ PyObject *newobj;
+
+ newobj = PyString_FromStringAndSize(NULL, n);
+ if (newobj == NULL)
+ return NULL;
+ s_new = PyString_AsString(newobj);
+ for (i = 0; i < n; i++) {
+ int c = Py_CHARMASK(*s++);
+ if (islower(c)) {
+ *s_new = toupper(c);
+ }
+ else if (isupper(c)) {
+ *s_new = tolower(c);
+ }
+ else
+ *s_new = c;
+ s_new++;
+ }
+ return newobj;
+}
+
+
+PyDoc_STRVAR(translate__doc__,
+"S.translate(table [,deletechars]) -> string\n\
+\n\
+Return a copy of the string S, where all characters occurring\n\
+in the optional argument deletechars are removed, and the\n\
+remaining characters have been mapped through the given\n\
+translation table, which must be a string of length 256 or None.\n\
+If the table argument is None, no translation is applied and\n\
+the operation simply removes the characters in deletechars.");
+
+static PyObject *
+string_translate(PyStringObject *self, PyObject *args)
+{
+ register char *input, *output;
+ const char *table;
+ register Py_ssize_t i, c, changed = 0;
+ PyObject *input_obj = (PyObject*)self;
+ const char *output_start, *del_table=NULL;
+ Py_ssize_t inlen, tablen, dellen = 0;
+ PyObject *result;
+ int trans_table[256];
+ PyObject *tableobj, *delobj = NULL;
+
+ if (!PyArg_UnpackTuple(args, "translate", 1, 2,
+ &tableobj, &delobj))
+ return NULL;
+
+ if (PyString_Check(tableobj)) {
+ table = PyString_AS_STRING(tableobj);
+ tablen = PyString_GET_SIZE(tableobj);
+ }
+ else if (tableobj == Py_None) {
+ table = NULL;
+ tablen = 256;
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(tableobj)) {
+ /* Unicode .translate() does not support the deletechars
+ parameter; instead a mapping to None will cause characters
+ to be deleted. */
+ if (delobj != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "deletions are implemented differently for unicode");
+ return NULL;
+ }
+ return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
+ }
+#endif
+ else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
+ return NULL;
+
+ if (tablen != 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "translation table must be 256 characters long");
+ return NULL;
+ }
+
+ if (delobj != NULL) {
+ if (PyString_Check(delobj)) {
+ del_table = PyString_AS_STRING(delobj);
+ dellen = PyString_GET_SIZE(delobj);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(delobj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "deletions are implemented differently for unicode");
+ return NULL;
+ }
+#endif
+ else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
+ return NULL;
+ }
+ else {
+ del_table = NULL;
+ dellen = 0;
+ }
+
+ inlen = PyString_GET_SIZE(input_obj);
+ result = PyString_FromStringAndSize((char *)NULL, inlen);
+ if (result == NULL)
+ return NULL;
+ output_start = output = PyString_AsString(result);
+ input = PyString_AS_STRING(input_obj);
+
+ if (dellen == 0 && table != NULL) {
+ /* If no deletions are required, use faster code */
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (Py_CHARMASK((*output++ = table[c])) != c)
+ changed = 1;
+ }
+ if (changed || !PyString_CheckExact(input_obj))
+ return result;
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
+ }
+
+ if (table == NULL) {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(i);
+ } else {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(table[i]);
+ }
+
+ for (i = 0; i < dellen; i++)
+ trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (trans_table[c] != -1)
+ if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+ continue;
+ changed = 1;
+ }
+ if (!changed && PyString_CheckExact(input_obj)) {
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
+ }
+ /* Fix the size of the resulting string */
+ if (inlen > 0 && _PyString_Resize(&result, output - output_start))
+ return NULL;
+ return result;
+}
+
+
+/* find and count characters and substrings */
+
+#define findchar(target, target_len, c) \
+ ((char *)memchr((const void *)(target), c, target_len))
+
+/* String ops must return a string. */
+/* If the object is subclass of string, create a copy */
+Py_LOCAL(PyStringObject *)
+return_self(PyStringObject *self)
+{
+ if (PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return self;
+ }
+ return (PyStringObject *)PyString_FromStringAndSize(
+ PyString_AS_STRING(self),
+ PyString_GET_SIZE(self));
+}
+
+Py_LOCAL_INLINE(Py_ssize_t)
+countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
+{
+ Py_ssize_t count=0;
+ const char *start=target;
+ const char *end=target+target_len;
+
+ while ( (start=findchar(start, end-start, c)) != NULL ) {
+ count++;
+ if (count >= maxcount)
+ break;
+ start += 1;
+ }
+ return count;
+}
+
+
+/* Algorithms for different cases of string replacement */
+
+/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_interleave(PyStringObject *self,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, i, product;
+ PyStringObject *result;
+
+ self_len = PyString_GET_SIZE(self);
+
+ /* 1 at the end plus 1 after every character */
+ count = self_len+1;
+ if (maxcount < count)
+ count = maxcount;
+
+ /* Check for overflow */
+ /* result_len = count * to_len + self_len; */
+ product = count * to_len;
+ if (product / to_len != count) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+ result_len = product + self_len;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+
+ if (! (result = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, result_len)) )
+ return NULL;
+
+ self_s = PyString_AS_STRING(self);
+ result_s = PyString_AS_STRING(result);
+
+ /* TODO: special case single character, which doesn't need memcpy */
+
+ /* Lay the first one down (guaranteed this will occur) */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ count -= 1;
+
+ for (i=0; i<count; i++) {
+ *result_s++ = *self_s++;
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ }
+
+ /* Copy the rest of the original string */
+ Py_MEMCPY(result_s, self_s, self_len-i);
+
+ return result;
+}
+
+/* Special case for deleting a single character */
+/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_delete_single_character(PyStringObject *self,
+ char from_c, Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count;
+ PyStringObject *result;
+
+ self_len = PyString_GET_SIZE(self);
+ self_s = PyString_AS_STRING(self);
+
+ count = countchar(self_s, self_len, from_c, maxcount);
+ if (count == 0) {
+ return return_self(self);
+ }
+
+ result_len = self_len - count; /* from_len == 1 */
+ assert(result_len>=0);
+
+ if ( (result = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyString_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ start = next+1;
+ }
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
+
+Py_LOCAL(PyStringObject *)
+replace_delete_substring(PyStringObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ Py_ssize_t maxcount) {
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, offset;
+ PyStringObject *result;
+
+ self_len = PyString_GET_SIZE(self);
+ self_s = PyString_AS_STRING(self);
+
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
+
+ if (count == 0) {
+ /* no matches */
+ return return_self(self);
+ }
+
+ result_len = self_len - (count * from_len);
+ assert (result_len>=0);
+
+ if ( (result = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, result_len)) == NULL )
+ return NULL;
+
+ result_s = PyString_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset == -1)
+ break;
+ next = start + offset;
+
+ Py_MEMCPY(result_s, start, next-start);
+
+ result_s += (next-start);
+ start = next+from_len;
+ }
+ Py_MEMCPY(result_s, start, end-start);
+ return result;
+}
+
+/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character_in_place(PyStringObject *self,
+ char from_c, char to_c,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s, *start, *end, *next;
+ Py_ssize_t self_len;
+ PyStringObject *result;
+
+ /* The result string will be the same size */
+ self_s = PyString_AS_STRING(self);
+ self_len = PyString_GET_SIZE(self);
+
+ next = findchar(self_s, self_len, from_c);
+
+ if (next == NULL) {
+ /* No matches; return the original string */
+ return return_self(self);
+ }
+
+ /* Need to make a new string */
+ result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+ if (result == NULL)
+ return NULL;
+ result_s = PyString_AS_STRING(result);
+ Py_MEMCPY(result_s, self_s, self_len);
+
+ /* change everything in-place, starting with this one */
+ start = result_s + (next-self_s);
+ *start = to_c;
+ start++;
+ end = result_s + self_len;
+
+ while (--maxcount > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+ *next = to_c;
+ start = next+1;
+ }
+
+ return result;
+}
+
+/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring_in_place(PyStringObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *result_s, *start, *end;
+ char *self_s;
+ Py_ssize_t self_len, offset;
+ PyStringObject *result;
+
+ /* The result string will be the same size */
+
+ self_s = PyString_AS_STRING(self);
+ self_len = PyString_GET_SIZE(self);
+
+ offset = stringlib_find(self_s, self_len,
+ from_s, from_len,
+ 0);
+ if (offset == -1) {
+ /* No matches; return the original string */
+ return return_self(self);
+ }
+
+ /* Need to make a new string */
+ result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
+ if (result == NULL)
+ return NULL;
+ result_s = PyString_AS_STRING(result);
+ Py_MEMCPY(result_s, self_s, self_len);
+
+ /* change everything in-place, starting with this one */
+ start = result_s + offset;
+ Py_MEMCPY(start, to_s, from_len);
+ start += from_len;
+ end = result_s + self_len;
+
+ while ( --maxcount > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset==-1)
+ break;
+ Py_MEMCPY(start+offset, to_s, from_len);
+ start += offset+from_len;
+ }
+
+ return result;
+}
+
+/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_single_character(PyStringObject *self,
+ char from_c,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, product;
+ PyStringObject *result;
+
+ self_s = PyString_AS_STRING(self);
+ self_len = PyString_GET_SIZE(self);
+
+ count = countchar(self_s, self_len, from_c, maxcount);
+ if (count == 0) {
+ /* no matches, return unchanged */
+ return return_self(self);
+ }
+
+ /* use the difference between current and new, hence the "-1" */
+ /* result_len = self_len + count * (to_len-1) */
+ product = count * (to_len-1);
+ if (product / (to_len-1) != count) {
+ PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+ return NULL;
+ }
+ result_len = self_len + product;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+ return NULL;
+ }
+
+ if ( (result = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyString_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ next = findchar(start, end-start, from_c);
+ if (next == NULL)
+ break;
+
+ if (next == start) {
+ /* replace with the 'to' */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start += 1;
+ } else {
+ /* copy the unchanged old then the 'to' */
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start = next+1;
+ }
+ }
+ /* Copy the remainder of the remaining string */
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
+Py_LOCAL(PyStringObject *)
+replace_substring(PyStringObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount) {
+ char *self_s, *result_s;
+ char *start, *next, *end;
+ Py_ssize_t self_len, result_len;
+ Py_ssize_t count, offset, product;
+ PyStringObject *result;
+
+ self_s = PyString_AS_STRING(self);
+ self_len = PyString_GET_SIZE(self);
+
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
+
+ if (count == 0) {
+ /* no matches, return unchanged */
+ return return_self(self);
+ }
+
+ /* Check for overflow */
+ /* result_len = self_len + count * (to_len-from_len) */
+ product = count * (to_len-from_len);
+ if (product / (to_len-from_len) != count) {
+ PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+ return NULL;
+ }
+ result_len = self_len + product;
+ if (result_len < 0) {
+ PyErr_SetString(PyExc_OverflowError, "replace string is too long");
+ return NULL;
+ }
+
+ if ( (result = (PyStringObject *)
+ PyString_FromStringAndSize(NULL, result_len)) == NULL)
+ return NULL;
+ result_s = PyString_AS_STRING(result);
+
+ start = self_s;
+ end = self_s + self_len;
+ while (count-- > 0) {
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
+ if (offset == -1)
+ break;
+ next = start+offset;
+ if (next == start) {
+ /* replace with the 'to' */
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start += from_len;
+ } else {
+ /* copy the unchanged old then the 'to' */
+ Py_MEMCPY(result_s, start, next-start);
+ result_s += (next-start);
+ Py_MEMCPY(result_s, to_s, to_len);
+ result_s += to_len;
+ start = next+from_len;
+ }
+ }
+ /* Copy the remainder of the remaining string */
+ Py_MEMCPY(result_s, start, end-start);
+
+ return result;
+}
+
+
+Py_LOCAL(PyStringObject *)
+replace(PyStringObject *self,
+ const char *from_s, Py_ssize_t from_len,
+ const char *to_s, Py_ssize_t to_len,
+ Py_ssize_t maxcount)
+{
+ if (maxcount < 0) {
+ maxcount = PY_SSIZE_T_MAX;
+ } else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) {
+ /* nothing to do; return the original string */
+ return return_self(self);
+ }
+
+ if (maxcount == 0 ||
+ (from_len == 0 && to_len == 0)) {
+ /* nothing to do; return the original string */
+ return return_self(self);
+ }
+
+ /* Handle zero-length special cases */
+
+ if (from_len == 0) {
+ /* insert the 'to' string everywhere. */
+ /* >>> "Python".replace("", ".") */
+ /* '.P.y.t.h.o.n.' */
+ return replace_interleave(self, to_s, to_len, maxcount);
+ }
+
+ /* Except for "".replace("", "A") == "A" there is no way beyond this */
+ /* point for an empty self string to generate a non-empty string */
+ /* Special case so the remaining code always gets a non-empty string */
+ if (PyString_GET_SIZE(self) == 0) {
+ return return_self(self);
+ }
+
+ if (to_len == 0) {
+ /* delete all occurances of 'from' string */
+ if (from_len == 1) {
+ return replace_delete_single_character(
+ self, from_s[0], maxcount);
+ } else {
+ return replace_delete_substring(self, from_s, from_len, maxcount);
+ }
+ }
+
+ /* Handle special case where both strings have the same length */
+
+ if (from_len == to_len) {
+ if (from_len == 1) {
+ return replace_single_character_in_place(
+ self,
+ from_s[0],
+ to_s[0],
+ maxcount);
+ } else {
+ return replace_substring_in_place(
+ self, from_s, from_len, to_s, to_len, maxcount);
+ }
+ }
+
+ /* Otherwise use the more generic algorithms */
+ if (from_len == 1) {
+ return replace_single_character(self, from_s[0],
+ to_s, to_len, maxcount);
+ } else {
+ /* len('from')>=2, len('to')>=1 */
+ return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
+ }
+}
+
+PyDoc_STRVAR(replace__doc__,
+"S.replace(old, new[, count]) -> string\n\
+\n\
+Return a copy of string S with all occurrences of substring\n\
+old replaced by new. If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject *
+string_replace(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t count = -1;
+ PyObject *from, *to;
+ const char *from_s, *to_s;
+ Py_ssize_t from_len, to_len;
+
+ if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+ return NULL;
+
+ if (PyString_Check(from)) {
+ from_s = PyString_AS_STRING(from);
+ from_len = PyString_GET_SIZE(from);
+ }
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(from))
+ return PyUnicode_Replace((PyObject *)self,
+ from, to, count);
+#endif
+ else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
+ return NULL;
+
+ if (PyString_Check(to)) {
+ to_s = PyString_AS_STRING(to);
+ to_len = PyString_GET_SIZE(to);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(to))
+ return PyUnicode_Replace((PyObject *)self,
+ from, to, count);
+#endif
+ else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
+ return NULL;
+
+ return (PyObject *)replace((PyStringObject *) self,
+ from_s, from_len,
+ to_s, to_len, count);
+}
+
+/** End DALKE **/
+
+/* Matches the end (direction >= 0) or start (direction < 0) of self
+ * against substr, using the start and end arguments. Returns
+ * -1 on error, 0 if not found and 1 if found.
+ */
+Py_LOCAL(int)
+_string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start,
+ Py_ssize_t end, int direction)
+{
+ Py_ssize_t len = PyString_GET_SIZE(self);
+ Py_ssize_t slen;
+ const char* sub;
+ const char* str;
+
+ if (PyString_Check(substr)) {
+ sub = PyString_AS_STRING(substr);
+ slen = PyString_GET_SIZE(substr);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(substr))
+ return PyUnicode_Tailmatch((PyObject *)self,
+ substr, start, end, direction);
+#endif
+ else if (PyObject_AsCharBuffer(substr, &sub, &slen))
+ return -1;
+ str = PyString_AS_STRING(self);
+
+ ADJUST_INDICES(start, end, len);
+
+ if (direction < 0) {
+ /* startswith */
+ if (start+slen > len)
+ return 0;
+ } else {
+ /* endswith */
+ if (end-start < slen || start > len)
+ return 0;
+
+ if (end-slen > start)
+ start = end - slen;
+ }
+ if (end-start >= slen)
+ return ! memcmp(str+start, sub, slen);
+ return 0;
+}
+
+
+PyDoc_STRVAR(startswith__doc__,
+"S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+string_startswith(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ PyObject *subobj;
+ int result;
+
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ result = _string_tailmatch(self,
+ PyTuple_GET_ITEM(subobj, i),
+ start, end, -1);
+ if (result == -1)
+ return NULL;
+ else if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ result = _string_tailmatch(self, subobj, start, end, -1);
+ if (result == -1) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+ return NULL;
+ }
+ else
+ return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+"S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+string_endswith(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ PyObject *subobj;
+ int result;
+
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ result = _string_tailmatch(self,
+ PyTuple_GET_ITEM(subobj, i),
+ start, end, +1);
+ if (result == -1)
+ return NULL;
+ else if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ result = _string_tailmatch(self, subobj, start, end, +1);
+ if (result == -1) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+ return NULL;
+ }
+ else
+ return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(encode__doc__,
+"S.encode([encoding[,errors]]) -> object\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that is able to handle UnicodeEncodeErrors.");
+
+static PyObject *
+string_encode(PyStringObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"encoding", "errors", 0};
+ char *encoding = NULL;
+ char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode",
+ kwlist, &encoding, &errors))
+ return NULL;
+ v = PyString_AsEncodedObject((PyObject *)self, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a string/unicode object "
+ "(type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ return NULL;
+ }
+ return v;
+
+ onError:
+ return NULL;
+}
+
+
+PyDoc_STRVAR(decode__doc__,
+"S.decode([encoding[,errors]]) -> object\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+string_decode(PyStringObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"encoding", "errors", 0};
+ char *encoding = NULL;
+ char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+ kwlist, &encoding, &errors))
+ return NULL;
+ v = PyString_AsDecodedObject((PyObject *)self, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "decoder did not return a string/unicode object "
+ "(type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ return NULL;
+ }
+ return v;
+
+ onError:
+ return NULL;
+}
+
+
+PyDoc_STRVAR(expandtabs__doc__,
+"S.expandtabs([tabsize]) -> string\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+string_expandtabs(PyStringObject *self, PyObject *args)
+{
+ const char *e, *p, *qe;
+ char *q;
+ Py_ssize_t i, j, incr;
+ PyObject *u;
+ int tabsize = 8;
+
+ if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+ return NULL;
+
+ /* First pass: determine size of output string */
+ i = 0; /* chars up to and including most recent \n or \r */
+ j = 0; /* chars since most recent \n or \r (use in tab calculations) */
+ e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); /* end of input */
+ for (p = PyString_AS_STRING(self); p < e; p++) {
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ incr = tabsize - (j % tabsize);
+ if (j > PY_SSIZE_T_MAX - incr)
+ goto overflow1;
+ j += incr;
+ }
+ }
+ else {
+ if (j > PY_SSIZE_T_MAX - 1)
+ goto overflow1;
+ j++;
+ if (*p == '\n' || *p == '\r') {
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow1;
+ i += j;
+ j = 0;
+ }
+ }
+ }
+
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow1;
+
+ /* Second pass: create output string and fill it */
+ u = PyString_FromStringAndSize(NULL, i + j);
+ if (!u)
+ return NULL;
+
+ j = 0; /* same as in first pass */
+ q = PyString_AS_STRING(u); /* next output char */
+ qe = PyString_AS_STRING(u) + PyString_GET_SIZE(u); /* end of output */
+
+ for (p = PyString_AS_STRING(self); p < e; p++) {
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ i = tabsize - (j % tabsize);
+ j += i;
+ while (i--) {
+ if (q >= qe)
+ goto overflow2;
+ *q++ = ' ';
+ }
+ }
+ }
+ else {
+ if (q >= qe)
+ goto overflow2;
+ *q++ = *p;
+ j++;
+ if (*p == '\n' || *p == '\r')
+ j = 0;
+ }
+ }
+
+ return u;
+
+ overflow2:
+ Py_DECREF(u);
+ overflow1:
+ PyErr_SetString(PyExc_OverflowError, "new string is too long");
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+pad(PyStringObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
+{
+ PyObject *u;
+
+ if (left < 0)
+ left = 0;
+ if (right < 0)
+ right = 0;
+
+ if (left == 0 && right == 0 && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+
+ u = PyString_FromStringAndSize(NULL,
+ left + PyString_GET_SIZE(self) + right);
+ if (u) {
+ if (left)
+ memset(PyString_AS_STRING(u), fill, left);
+ Py_MEMCPY(PyString_AS_STRING(u) + left,
+ PyString_AS_STRING(self),
+ PyString_GET_SIZE(self));
+ if (right)
+ memset(PyString_AS_STRING(u) + left + PyString_GET_SIZE(self),
+ fill, right);
+ }
+
+ return u;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+"S.ljust(width[, fillchar]) -> string\n"
+"\n"
+"Return S left-justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space).");
+
+static PyObject *
+string_ljust(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
+ return NULL;
+
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ return pad(self, 0, width - PyString_GET_SIZE(self), fillchar);
+}
+
+
+PyDoc_STRVAR(rjust__doc__,
+"S.rjust(width[, fillchar]) -> string\n"
+"\n"
+"Return S right-justified in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_rjust(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
+ return NULL;
+
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ return pad(self, width - PyString_GET_SIZE(self), 0, fillchar);
+}
+
+
+PyDoc_STRVAR(center__doc__,
+"S.center(width[, fillchar]) -> string\n"
+"\n"
+"Return S centered in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
+
+static PyObject *
+string_center(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t marg, left;
+ Py_ssize_t width;
+ char fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
+ return NULL;
+
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ marg = width - PyString_GET_SIZE(self);
+ left = marg / 2 + (marg & width & 1);
+
+ return pad(self, left, marg - left, fillchar);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+"S.zfill(width) -> string\n"
+"\n"
+"Pad a numeric string S with zeros on the left, to fill a field\n"
+"of the specified width. The string S is never truncated.");
+
+static PyObject *
+string_zfill(PyStringObject *self, PyObject *args)
+{
+ Py_ssize_t fill;
+ PyObject *s;
+ char *p;
+ Py_ssize_t width;
+
+ if (!PyArg_ParseTuple(args, "n:zfill", &width))
+ return NULL;
+
+ if (PyString_GET_SIZE(self) >= width) {
+ if (PyString_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+ else
+ return PyString_FromStringAndSize(
+ PyString_AS_STRING(self),
+ PyString_GET_SIZE(self)
+ );
+ }
+
+ fill = width - PyString_GET_SIZE(self);
+
+ s = pad(self, fill, 0, '0');
+
+ if (s == NULL)
+ return NULL;
+
+ p = PyString_AS_STRING(s);
+ if (p[fill] == '+' || p[fill] == '-') {
+ /* move sign to beginning of string */
+ p[0] = p[fill];
+ p[fill] = '0';
+ }
+
+ return (PyObject*) s;
+}
+
+PyDoc_STRVAR(isspace__doc__,
+"S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isspace(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1 &&
+ isspace(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!isspace(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalpha__doc__,
+"S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalpha(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1 &&
+ isalpha(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!isalpha(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isalnum__doc__,
+"S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isalnum(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1 &&
+ isalnum(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!isalnum(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(isdigit__doc__,
+"S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+string_isdigit(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1 &&
+ isdigit(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!isdigit(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+
+PyDoc_STRVAR(islower__doc__,
+"S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_islower(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1)
+ return PyBool_FromLong(islower(*p) != 0);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ cased = 0;
+ for (; p < e; p++) {
+ if (isupper(*p))
+ return PyBool_FromLong(0);
+ else if (!cased && islower(*p))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(isupper__doc__,
+"S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+string_isupper(PyStringObject *self)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1)
+ return PyBool_FromLong(isupper(*p) != 0);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ cased = 0;
+ for (; p < e; p++) {
+ if (islower(*p))
+ return PyBool_FromLong(0);
+ else if (!cased && isupper(*p))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(istitle__doc__,
+"S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. uppercase characters may only follow uncased\n\
+characters and lowercase characters only cased ones. Return False\n\
+otherwise.");
+
+static PyObject*
+string_istitle(PyStringObject *self, PyObject *uncased)
+{
+ register const unsigned char *p
+ = (unsigned char *) PyString_AS_STRING(self);
+ register const unsigned char *e;
+ int cased, previous_is_cased;
+
+ /* Shortcut for single character strings */
+ if (PyString_GET_SIZE(self) == 1)
+ return PyBool_FromLong(isupper(*p) != 0);
+
+ /* Special case for empty strings */
+ if (PyString_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyString_GET_SIZE(self);
+ cased = 0;
+ previous_is_cased = 0;
+ for (; p < e; p++) {
+ register const unsigned char ch = *p;
+
+ if (isupper(ch)) {
+ if (previous_is_cased)
+ return PyBool_FromLong(0);
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else if (islower(ch)) {
+ if (!previous_is_cased)
+ return PyBool_FromLong(0);
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else
+ previous_is_cased = 0;
+ }
+ return PyBool_FromLong(cased);
+}
+
+
+PyDoc_STRVAR(splitlines__doc__,
+"S.splitlines(keepends=False) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+string_splitlines(PyStringObject *self, PyObject *args)
+{
+ int keepends = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+ return NULL;
+
+ return stringlib_splitlines(
+ (PyObject*) self, PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ keepends
+ );
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+"S.__sizeof__() -> size of S in memory, in bytes");
+
+static PyObject *
+string_sizeof(PyStringObject *v)
+{
+ Py_ssize_t res;
+ res = PyStringObject_SIZE + PyString_GET_SIZE(v) * Py_TYPE(v)->tp_itemsize;
+ return PyInt_FromSsize_t(res);
+}
+
+static PyObject *
+string_getnewargs(PyStringObject *v)
+{
+ return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v));
+}
+
+
+#include "stringlib/string_format.h"
+
+PyDoc_STRVAR(format__doc__,
+"S.format(*args, **kwargs) -> string\n\
+\n\
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
+
+static PyObject *
+string__format__(PyObject* self, PyObject* args)
+{
+ PyObject *format_spec;
+ PyObject *result = NULL;
+ PyObject *tmp = NULL;
+
+ /* If 2.x, convert format_spec to the same type as value */
+ /* This is to allow things like u''.format('') */
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ goto done;
+ if (!(PyString_Check(format_spec) || PyUnicode_Check(format_spec))) {
+ PyErr_Format(PyExc_TypeError, "__format__ arg must be str "
+ "or unicode, not %s", Py_TYPE(format_spec)->tp_name);
+ goto done;
+ }
+ tmp = PyObject_Str(format_spec);
+ if (tmp == NULL)
+ goto done;
+ format_spec = tmp;
+
+ result = _PyBytes_FormatAdvanced(self,
+ PyString_AS_STRING(format_spec),
+ PyString_GET_SIZE(format_spec));
+done:
+ Py_XDECREF(tmp);
+ return result;
+}
+
+PyDoc_STRVAR(p_format__doc__,
+"S.__format__(format_spec) -> string\n\
+\n\
+Return a formatted version of S as described by format_spec.");
+
+
+static PyMethodDef
+string_methods[] = {
+ /* Counterparts of the obsolete stropmodule functions; except
+ string.maketrans(). */
+ {"join", (PyCFunction)string_join, METH_O, join__doc__},
+ {"split", (PyCFunction)string_split, METH_VARARGS, split__doc__},
+ {"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__},
+ {"lower", (PyCFunction)string_lower, METH_NOARGS, lower__doc__},
+ {"upper", (PyCFunction)string_upper, METH_NOARGS, upper__doc__},
+ {"islower", (PyCFunction)string_islower, METH_NOARGS, islower__doc__},
+ {"isupper", (PyCFunction)string_isupper, METH_NOARGS, isupper__doc__},
+ {"isspace", (PyCFunction)string_isspace, METH_NOARGS, isspace__doc__},
+ {"isdigit", (PyCFunction)string_isdigit, METH_NOARGS, isdigit__doc__},
+ {"istitle", (PyCFunction)string_istitle, METH_NOARGS, istitle__doc__},
+ {"isalpha", (PyCFunction)string_isalpha, METH_NOARGS, isalpha__doc__},
+ {"isalnum", (PyCFunction)string_isalnum, METH_NOARGS, isalnum__doc__},
+ {"capitalize", (PyCFunction)string_capitalize, METH_NOARGS,
+ capitalize__doc__},
+ {"count", (PyCFunction)string_count, METH_VARARGS, count__doc__},
+ {"endswith", (PyCFunction)string_endswith, METH_VARARGS,
+ endswith__doc__},
+ {"partition", (PyCFunction)string_partition, METH_O, partition__doc__},
+ {"find", (PyCFunction)string_find, METH_VARARGS, find__doc__},
+ {"index", (PyCFunction)string_index, METH_VARARGS, index__doc__},
+ {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
+ {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
+ {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},
+ {"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__},
+ {"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__},
+ {"rpartition", (PyCFunction)string_rpartition, METH_O,
+ rpartition__doc__},
+ {"startswith", (PyCFunction)string_startswith, METH_VARARGS,
+ startswith__doc__},
+ {"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__},
+ {"swapcase", (PyCFunction)string_swapcase, METH_NOARGS,
+ swapcase__doc__},
+ {"translate", (PyCFunction)string_translate, METH_VARARGS,
+ translate__doc__},
+ {"title", (PyCFunction)string_title, METH_NOARGS, title__doc__},
+ {"ljust", (PyCFunction)string_ljust, METH_VARARGS, ljust__doc__},
+ {"rjust", (PyCFunction)string_rjust, METH_VARARGS, rjust__doc__},
+ {"center", (PyCFunction)string_center, METH_VARARGS, center__doc__},
+ {"zfill", (PyCFunction)string_zfill, METH_VARARGS, zfill__doc__},
+ {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+ {"__format__", (PyCFunction) string__format__, METH_VARARGS, p_format__doc__},
+ {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
+ {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
+ {"encode", (PyCFunction)string_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
+ {"decode", (PyCFunction)string_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
+ {"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS,
+ expandtabs__doc__},
+ {"splitlines", (PyCFunction)string_splitlines, METH_VARARGS,
+ splitlines__doc__},
+ {"__sizeof__", (PyCFunction)string_sizeof, METH_NOARGS,
+ sizeof__doc__},
+ {"__getnewargs__", (PyCFunction)string_getnewargs, METH_NOARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *x = NULL;
+ static char *kwlist[] = {"object", 0};
+
+ if (type != &PyString_Type)
+ return str_subtype_new(type, args, kwds);
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:str", kwlist, &x))
+ return NULL;
+ if (x == NULL)
+ return PyString_FromString("");
+ return PyObject_Str(x);
+}
+
+static PyObject *
+str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *tmp, *pnew;
+ Py_ssize_t n;
+
+ assert(PyType_IsSubtype(type, &PyString_Type));
+ tmp = string_new(&PyString_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyString_CheckExact(tmp));
+ n = PyString_GET_SIZE(tmp);
+ pnew = type->tp_alloc(type, n);
+ if (pnew != NULL) {
+ Py_MEMCPY(PyString_AS_STRING(pnew), PyString_AS_STRING(tmp), n+1);
+ ((PyStringObject *)pnew)->ob_shash =
+ ((PyStringObject *)tmp)->ob_shash;
+ ((PyStringObject *)pnew)->ob_sstate = SSTATE_NOT_INTERNED;
+ }
+ Py_DECREF(tmp);
+ return pnew;
+}
+
+static PyObject *
+basestring_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "The basestring type cannot be instantiated");
+ return NULL;
+}
+
+static PyObject *
+string_mod(PyObject *v, PyObject *w)
+{
+ if (!PyString_Check(v)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyString_Format(v, w);
+}
+
+PyDoc_STRVAR(basestring_doc,
+"Type basestring cannot be instantiated; it is the base for str and unicode.");
+
+static PyNumberMethods string_as_number = {
+ 0, /*nb_add*/
+ 0, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ string_mod, /*nb_remainder*/
+};
+
+
+PyTypeObject PyBaseString_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "basestring",
+ 0,
+ 0,
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ basestring_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &PyBaseObject_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ basestring_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+PyDoc_STRVAR(string_doc,
+"str(object='') -> string\n\
+\n\
+Return a nice string representation of the object.\n\
+If the argument is a string, the return value is the same object.");
+
+PyTypeObject PyString_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "str",
+ PyStringObject_SIZE,
+ sizeof(char),
+ string_dealloc, /* tp_dealloc */
+ (printfunc)string_print, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ string_repr, /* tp_repr */
+ &string_as_number, /* tp_as_number */
+ &string_as_sequence, /* tp_as_sequence */
+ &string_as_mapping, /* tp_as_mapping */
+ (hashfunc)string_hash, /* tp_hash */
+ 0, /* tp_call */
+ string_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &string_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_STRING_SUBCLASS |
+ Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+ string_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)string_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ string_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &PyBaseString_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ string_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+void
+PyString_Concat(register PyObject **pv, register PyObject *w)
+{
+ register PyObject *v;
+ if (*pv == NULL)
+ return;
+ if (w == NULL || !PyString_Check(*pv)) {
+ Py_CLEAR(*pv);
+ return;
+ }
+ v = string_concat((PyStringObject *) *pv, w);
+ Py_DECREF(*pv);
+ *pv = v;
+}
+
+void
+PyString_ConcatAndDel(register PyObject **pv, register PyObject *w)
+{
+ PyString_Concat(pv, w);
+ Py_XDECREF(w);
+}
+
+
+/* The following function breaks the notion that strings are immutable:
+ it changes the size of a string. We get away with this only if there
+ is only one module referencing the object. You can also think of it
+ as creating a new string object and destroying the old one, only
+ more efficiently. In any case, don't use this if the string may
+ already be known to some other part of the code...
+ Note that if there's not enough memory to resize the string, the original
+ string object at *pv is deallocated, *pv is set to NULL, an "out of
+ memory" exception is set, and -1 is returned. Else (on success) 0 is
+ returned, and the value in *pv may or may not be the same as on input.
+ As always, an extra byte is allocated for a trailing \0 byte (newsize
+ does *not* include that), and a trailing \0 byte is stored.
+*/
+
+int
+_PyString_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+ register PyObject *v;
+ register PyStringObject *sv;
+ v = *pv;
+ if (!PyString_Check(v) || Py_REFCNT(v) != 1 || newsize < 0 ||
+ PyString_CHECK_INTERNED(v)) {
+ *pv = 0;
+ Py_DECREF(v);
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ /* XXX UNREF/NEWREF interface should be more symmetrical */
+ _Py_DEC_REFTOTAL;
+ _Py_ForgetReference(v);
+ *pv = (PyObject *)
+ PyObject_REALLOC((char *)v, PyStringObject_SIZE + newsize);
+ if (*pv == NULL) {
+ PyObject_Del(v);
+ PyErr_NoMemory();
+ return -1;
+ }
+ _Py_NewReference(*pv);
+ sv = (PyStringObject *) *pv;
+ Py_SIZE(sv) = newsize;
+ sv->ob_sval[newsize] = '\0';
+ sv->ob_shash = -1; /* invalidate cached hash value */
+ return 0;
+}
+
+/* Helpers for formatstring */
+
+Py_LOCAL_INLINE(PyObject *)
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+ Py_ssize_t argidx = *p_argidx;
+ if (argidx < arglen) {
+ (*p_argidx)++;
+ if (arglen < 0)
+ return args;
+ else
+ return PyTuple_GetItem(args, argidx);
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "not enough arguments for format string");
+ return NULL;
+}
+
+/* Format codes
+ * F_LJUST '-'
+ * F_SIGN '+'
+ * F_BLANK ' '
+ * F_ALT '#'
+ * F_ZERO '0'
+ */
+#define F_LJUST (1<<0)
+#define F_SIGN (1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT (1<<3)
+#define F_ZERO (1<<4)
+
+/* Returns a new reference to a PyString object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
+{
+ char *p;
+ PyObject *result;
+ double x;
+
+ x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError, "float argument required, "
+ "not %.200s", Py_TYPE(v)->tp_name);
+ return NULL;
+ }
+
+ if (prec < 0)
+ prec = 6;
+
+ p = PyOS_double_to_string(x, type, prec,
+ (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
+
+ if (p == NULL)
+ return NULL;
+ result = PyString_FromStringAndSize(p, strlen(p));
+ PyMem_Free(p);
+ return result;
+}
+
+/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
+ * the F_ALT flag, for Python's long (unbounded) ints. It's not used for
+ * Python's regular ints.
+ * Return value: a new PyString*, or NULL if error.
+ * . *pbuf is set to point into it,
+ * *plen set to the # of chars following that.
+ * Caller must decref it when done using pbuf.
+ * The string starting at *pbuf is of the form
+ * "-"? ("0x" | "0X")? digit+
+ * "0x"/"0X" are present only for x and X conversions, with F_ALT
+ * set in flags. The case of hex digits will be correct,
+ * There will be at least prec digits, zero-filled on the left if
+ * necessary to get that many.
+ * val object to be converted
+ * flags bitmask of format flags; only F_ALT is looked at
+ * prec minimum number of digits; 0-fill on left if needed
+ * type a character in [duoxX]; u acts the same as d
+ *
+ * CAUTION: o, x and X conversions on regular ints can never
+ * produce a '-' sign, but can for Python's unbounded ints.
+ */
+PyObject*
+_PyString_FormatLong(PyObject *val, int flags, int prec, int type,
+ char **pbuf, int *plen)
+{
+ PyObject *result = NULL;
+ char *buf;
+ Py_ssize_t i;
+ int sign; /* 1 if '-', else 0 */
+ int len; /* number of characters */
+ Py_ssize_t llen;
+ int numdigits; /* len == numnondigits + numdigits */
+ int numnondigits = 0;
+
+ switch (type) {
+ case 'd':
+ case 'u':
+ result = Py_TYPE(val)->tp_str(val);
+ break;
+ case 'o':
+ result = Py_TYPE(val)->tp_as_number->nb_oct(val);
+ break;
+ case 'x':
+ case 'X':
+ numnondigits = 2;
+ result = Py_TYPE(val)->tp_as_number->nb_hex(val);
+ break;
+ default:
+ assert(!"'type' not in [duoxX]");
+ }
+ if (!result)
+ return NULL;
+
+ buf = PyString_AsString(result);
+ if (!buf) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ /* To modify the string in-place, there can only be one reference. */
+ if (Py_REFCNT(result) != 1) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ llen = PyString_Size(result);
+ if (llen > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong");
+ return NULL;
+ }
+ len = (int)llen;
+ if (buf[len-1] == 'L') {
+ --len;
+ buf[len] = '\0';
+ }
+ sign = buf[0] == '-';
+ numnondigits += sign;
+ numdigits = len - numnondigits;
+ assert(numdigits > 0);
+
+ /* Get rid of base marker unless F_ALT */
+ if ((flags & F_ALT) == 0) {
+ /* Need to skip 0x, 0X or 0. */
+ int skipped = 0;
+ switch (type) {
+ case 'o':
+ assert(buf[sign] == '0');
+ /* If 0 is only digit, leave it alone. */
+ if (numdigits > 1) {
+ skipped = 1;
+ --numdigits;
+ }
+ break;
+ case 'x':
+ case 'X':
+ assert(buf[sign] == '0');
+ assert(buf[sign + 1] == 'x');
+ skipped = 2;
+ numnondigits -= 2;
+ break;
+ }
+ if (skipped) {
+ buf += skipped;
+ len -= skipped;
+ if (sign)
+ buf[0] = '-';
+ }
+ assert(len == numnondigits + numdigits);
+ assert(numdigits > 0);
+ }
+
+ /* Fill with leading zeroes to meet minimum width. */
+ if (prec > numdigits) {
+ PyObject *r1 = PyString_FromStringAndSize(NULL,
+ numnondigits + prec);
+ char *b1;
+ if (!r1) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ b1 = PyString_AS_STRING(r1);
+ for (i = 0; i < numnondigits; ++i)
+ *b1++ = *buf++;
+ for (i = 0; i < prec - numdigits; i++)
+ *b1++ = '0';
+ for (i = 0; i < numdigits; i++)
+ *b1++ = *buf++;
+ *b1 = '\0';
+ Py_DECREF(result);
+ result = r1;
+ buf = PyString_AS_STRING(result);
+ len = numnondigits + prec;
+ }
+
+ /* Fix up case for hex conversions. */
+ if (type == 'X') {
+ /* Need to convert all lower case letters to upper case.
+ and need to convert 0x to 0X (and -0x to -0X). */
+ for (i = 0; i < len; i++)
+ if (buf[i] >= 'a' && buf[i] <= 'x')
+ buf[i] -= 'a'-'A';
+ }
+ *pbuf = buf;
+ *plen = len;
+ return result;
+}
+
+Py_LOCAL_INLINE(int)
+formatint(char *buf, size_t buflen, int flags,
+ int prec, int type, PyObject *v)
+{
+ /* fmt = '%#.' + `prec` + 'l' + `type`
+ worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+ + 1 + 1 = 24 */
+ char fmt[64]; /* plenty big enough! */
+ char *sign;
+ long x;
+
+ x = PyInt_AsLong(v);
+ if (x == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError, "int argument required, not %.200s",
+ Py_TYPE(v)->tp_name);
+ return -1;
+ }
+ if (x < 0 && type == 'u') {
+ type = 'd';
+ }
+ if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+ sign = "-";
+ else
+ sign = "";
+ if (prec < 0)
+ prec = 1;
+
+ if ((flags & F_ALT) &&
+ (type == 'x' || type == 'X')) {
+ /* When converting under %#x or %#X, there are a number
+ * of issues that cause pain:
+ * - when 0 is being converted, the C standard leaves off
+ * the '0x' or '0X', which is inconsistent with other
+ * %#x/%#X conversions and inconsistent with Python's
+ * hex() function
+ * - there are platforms that violate the standard and
+ * convert 0 with the '0x' or '0X'
+ * (Metrowerks, Compaq Tru64)
+ * - there are platforms that give '0x' when converting
+ * under %#X, but convert 0 in accordance with the
+ * standard (OS/2 EMX)
+ *
+ * We can achieve the desired consistency by inserting our
+ * own '0x' or '0X' prefix, and substituting %x/%X in place
+ * of %#x/%#X.
+ *
+ * Note that this is the same approach as used in
+ * formatint() in unicodeobject.c
+ */
+ PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+ sign, type, prec, type);
+ }
+ else {
+ PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+ sign, (flags&F_ALT) ? "#" : "",
+ prec, type);
+ }
+
+ /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+ * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+ */
+ if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+ PyErr_SetString(PyExc_OverflowError,
+ "formatted integer is too long (precision too large?)");
+ return -1;
+ }
+ if (sign[0])
+ PyOS_snprintf(buf, buflen, fmt, -x);
+ else
+ PyOS_snprintf(buf, buflen, fmt, x);
+ return (int)strlen(buf);
+}
+
+Py_LOCAL_INLINE(int)
+formatchar(char *buf, size_t buflen, PyObject *v)
+{
+ /* presume that the buffer is at least 2 characters long */
+ if (PyString_Check(v)) {
+ if (!PyArg_Parse(v, "c;%c requires int or char", &buf[0]))
+ return -1;
+ }
+ else {
+ if (!PyArg_Parse(v, "b;%c requires int or char", &buf[0]))
+ return -1;
+ }
+ buf[1] = '\0';
+ return 1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+ FORMATBUFLEN is the length of the buffer in which the ints &
+ chars are formatted. XXX This is a magic number. Each formatting
+ routine does bounds checking to ensure no overflow, but a better
+ solution may be to malloc a buffer of appropriate size for each
+ format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *
+PyString_Format(PyObject *format, PyObject *args)
+{
+ char *fmt, *res;
+ Py_ssize_t arglen, argidx;
+ Py_ssize_t reslen, rescnt, fmtcnt;
+ int args_owned = 0;
+ PyObject *result, *orig_args;
+#ifdef Py_USING_UNICODE
+ PyObject *v, *w;
+#endif
+ PyObject *dict = NULL;
+ if (format == NULL || !PyString_Check(format) || args == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ orig_args = args;
+ fmt = PyString_AS_STRING(format);
+ fmtcnt = PyString_GET_SIZE(format);
+ reslen = rescnt = fmtcnt + 100;
+ result = PyString_FromStringAndSize((char *)NULL, reslen);
+ if (result == NULL)
+ return NULL;
+ res = PyString_AsString(result);
+ if (PyTuple_Check(args)) {
+ arglen = PyTuple_GET_SIZE(args);
+ argidx = 0;
+ }
+ else {
+ arglen = -1;
+ argidx = -2;
+ }
+ if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript &&
+ !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type))
+ dict = args;
+ while (--fmtcnt >= 0) {
+ if (*fmt != '%') {
+ if (--rescnt < 0) {
+ rescnt = fmtcnt + 100;
+ reslen += rescnt;
+ if (_PyString_Resize(&result, reslen))
+ return NULL;
+ res = PyString_AS_STRING(result)
+ + reslen - rescnt;
+ --rescnt;
+ }
+ *res++ = *fmt++;
+ }
+ else {
+ /* Got a format specifier */
+ int flags = 0;
+ Py_ssize_t width = -1;
+ int prec = -1;
+ int c = '\0';
+ int fill;
+ int isnumok;
+ PyObject *v = NULL;
+ PyObject *temp = NULL;
+ char *pbuf;
+ int sign;
+ Py_ssize_t len;
+ char formatbuf[FORMATBUFLEN];
+ /* For format{int,char}() */
+#ifdef Py_USING_UNICODE
+ char *fmt_start = fmt;
+ Py_ssize_t argidx_start = argidx;
+#endif
+
+ fmt++;
+ if (*fmt == '(') {
+ char *keystart;
+ Py_ssize_t keylen;
+ PyObject *key;
+ int pcount = 1;
+
+ if (dict == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "format requires a mapping");
+ goto error;
+ }
+ ++fmt;
+ --fmtcnt;
+ keystart = fmt;
+ /* Skip over balanced parentheses */
+ while (pcount > 0 && --fmtcnt >= 0) {
+ if (*fmt == ')')
+ --pcount;
+ else if (*fmt == '(')
+ ++pcount;
+ fmt++;
+ }
+ keylen = fmt - keystart - 1;
+ if (fmtcnt < 0 || pcount > 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "incomplete format key");
+ goto error;
+ }
+ key = PyString_FromStringAndSize(keystart,
+ keylen);
+ if (key == NULL)
+ goto error;
+ if (args_owned) {
+ Py_DECREF(args);
+ args_owned = 0;
+ }
+ args = PyObject_GetItem(dict, key);
+ Py_DECREF(key);
+ if (args == NULL) {
+ goto error;
+ }
+ args_owned = 1;
+ arglen = -1;
+ argidx = -2;
+ }
+ while (--fmtcnt >= 0) {
+ switch (c = *fmt++) {
+ case '-': flags |= F_LJUST; continue;
+ case '+': flags |= F_SIGN; continue;
+ case ' ': flags |= F_BLANK; continue;
+ case '#': flags |= F_ALT; continue;
+ case '0': flags |= F_ZERO; continue;
+ }
+ break;
+ }
+ if (c == '*') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto error;
+ if (!PyInt_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "* wants int");
+ goto error;
+ }
+ width = PyInt_AsSsize_t(v);
+ if (width == -1 && PyErr_Occurred())
+ goto error;
+ if (width < 0) {
+ flags |= F_LJUST;
+ width = -width;
+ }
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ else if (c >= 0 && isdigit(c)) {
+ width = c - '0';
+ while (--fmtcnt >= 0) {
+ c = Py_CHARMASK(*fmt++);
+ if (!isdigit(c))
+ break;
+ if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "width too big");
+ goto error;
+ }
+ width = width*10 + (c - '0');
+ }
+ }
+ if (c == '.') {
+ prec = 0;
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ if (c == '*') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto error;
+ if (!PyInt_Check(v)) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "* wants int");
+ goto error;
+ }
+ prec = _PyInt_AsInt(v);
+ if (prec == -1 && PyErr_Occurred())
+ goto error;
+ if (prec < 0)
+ prec = 0;
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ else if (c >= 0 && isdigit(c)) {
+ prec = c - '0';
+ while (--fmtcnt >= 0) {
+ c = Py_CHARMASK(*fmt++);
+ if (!isdigit(c))
+ break;
+ if (prec > (INT_MAX - ((int)c - '0')) / 10) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "prec too big");
+ goto error;
+ }
+ prec = prec*10 + (c - '0');
+ }
+ }
+ } /* prec */
+ if (fmtcnt >= 0) {
+ if (c == 'h' || c == 'l' || c == 'L') {
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ }
+ if (fmtcnt < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "incomplete format");
+ goto error;
+ }
+ if (c != '%') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto error;
+ }
+ sign = 0;
+ fill = ' ';
+ switch (c) {
+ case '%':
+ pbuf = "%";
+ len = 1;
+ break;
+ case 's':
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(v)) {
+ fmt = fmt_start;
+ argidx = argidx_start;
+ goto unicode;
+ }
+#endif
+ temp = _PyObject_Str(v);
+#ifdef Py_USING_UNICODE
+ if (temp != NULL && PyUnicode_Check(temp)) {
+ Py_DECREF(temp);
+ fmt = fmt_start;
+ argidx = argidx_start;
+ goto unicode;
+ }
+#endif
+ /* Fall through */
+ case 'r':
+ if (c == 'r')
+ temp = PyObject_Repr(v);
+ if (temp == NULL)
+ goto error;
+ if (!PyString_Check(temp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "%s argument has non-string str()");
+ Py_DECREF(temp);
+ goto error;
+ }
+ pbuf = PyString_AS_STRING(temp);
+ len = PyString_GET_SIZE(temp);
+ if (prec >= 0 && len > prec)
+ len = prec;
+ break;
+ case 'i':
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ if (c == 'i')
+ c = 'd';
+ isnumok = 0;
+ if (PyNumber_Check(v)) {
+ PyObject *iobj=NULL;
+
+ if (PyInt_Check(v) || (PyLong_Check(v))) {
+ iobj = v;
+ Py_INCREF(iobj);
+ }
+ else {
+ iobj = PyNumber_Int(v);
+ if (iobj==NULL) {
+ PyErr_Clear();
+ iobj = PyNumber_Long(v);
+ }
+ }
+ if (iobj!=NULL) {
+ if (PyInt_Check(iobj)) {
+ isnumok = 1;
+ pbuf = formatbuf;
+ len = formatint(pbuf,
+ sizeof(formatbuf),
+ flags, prec, c, iobj);
+ Py_DECREF(iobj);
+ if (len < 0)
+ goto error;
+ sign = 1;
+ }
+ else if (PyLong_Check(iobj)) {
+ int ilen;
+
+ isnumok = 1;
+ temp = _PyString_FormatLong(iobj, flags,
+ prec, c, &pbuf, &ilen);
+ Py_DECREF(iobj);
+ len = ilen;
+ if (!temp)
+ goto error;
+ sign = 1;
+ }
+ else {
+ Py_DECREF(iobj);
+ }
+ }
+ }
+ if (!isnumok) {
+ PyErr_Format(PyExc_TypeError,
+ "%%%c format: a number is required, "
+ "not %.200s", c, Py_TYPE(v)->tp_name);
+ goto error;
+ }
+ if (flags & F_ZERO)
+ fill = '0';
+ break;
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ temp = formatfloat(v, flags, prec, c);
+ if (temp == NULL)
+ goto error;
+ pbuf = PyString_AS_STRING(temp);
+ len = PyString_GET_SIZE(temp);
+ sign = 1;
+ if (flags & F_ZERO)
+ fill = '0';
+ break;
+ case 'c':
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(v)) {
+ fmt = fmt_start;
+ argidx = argidx_start;
+ goto unicode;
+ }
+#endif
+ pbuf = formatbuf;
+ len = formatchar(pbuf, sizeof(formatbuf), v);
+ if (len < 0)
+ goto error;
+ break;
+ default:
+ PyErr_Format(PyExc_ValueError,
+ "unsupported format character '%c' (0x%x) "
+ "at index %zd",
+ c, c,
+ (Py_ssize_t)(fmt - 1 -
+ PyString_AsString(format)));
+ goto error;
+ }
+ if (sign) {
+ if (*pbuf == '-' || *pbuf == '+') {
+ sign = *pbuf++;
+ len--;
+ }
+ else if (flags & F_SIGN)
+ sign = '+';
+ else if (flags & F_BLANK)
+ sign = ' ';
+ else
+ sign = 0;
+ }
+ if (width < len)
+ width = len;
+ if (rescnt - (sign != 0) < width) {
+ reslen -= rescnt;
+ rescnt = width + fmtcnt + 100;
+ reslen += rescnt;
+ if (reslen < 0) {
+ Py_DECREF(result);
+ Py_XDECREF(temp);
+ return PyErr_NoMemory();
+ }
+ if (_PyString_Resize(&result, reslen)) {
+ Py_XDECREF(temp);
+ return NULL;
+ }
+ res = PyString_AS_STRING(result)
+ + reslen - rescnt;
+ }
+ if (sign) {
+ if (fill != ' ')
+ *res++ = sign;
+ rescnt--;
+ if (width > len)
+ width--;
+ }
+ if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+ assert(pbuf[0] == '0');
+ assert(pbuf[1] == c);
+ if (fill != ' ') {
+ *res++ = *pbuf++;
+ *res++ = *pbuf++;
+ }
+ rescnt -= 2;
+ width -= 2;
+ if (width < 0)
+ width = 0;
+ len -= 2;
+ }
+ if (width > len && !(flags & F_LJUST)) {
+ do {
+ --rescnt;
+ *res++ = fill;
+ } while (--width > len);
+ }
+ if (fill == ' ') {
+ if (sign)
+ *res++ = sign;
+ if ((flags & F_ALT) &&
+ (c == 'x' || c == 'X')) {
+ assert(pbuf[0] == '0');
+ assert(pbuf[1] == c);
+ *res++ = *pbuf++;
+ *res++ = *pbuf++;
+ }
+ }
+ Py_MEMCPY(res, pbuf, len);
+ res += len;
+ rescnt -= len;
+ while (--width >= len) {
+ --rescnt;
+ *res++ = ' ';
+ }
+ if (dict && (argidx < arglen) && c != '%') {
+ PyErr_SetString(PyExc_TypeError,
+ "not all arguments converted during string formatting");
+ Py_XDECREF(temp);
+ goto error;
+ }
+ Py_XDECREF(temp);
+ } /* '%' */
+ } /* until end */
+ if (argidx < arglen && !dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "not all arguments converted during string formatting");
+ goto error;
+ }
+ if (args_owned) {
+ Py_DECREF(args);
+ }
+ if (_PyString_Resize(&result, reslen - rescnt))
+ return NULL;
+ return result;
+
+#ifdef Py_USING_UNICODE
+ unicode:
+ if (args_owned) {
+ Py_DECREF(args);
+ args_owned = 0;
+ }
+ /* Fiddle args right (remove the first argidx arguments) */
+ if (PyTuple_Check(orig_args) && argidx > 0) {
+ PyObject *v;
+ Py_ssize_t n = PyTuple_GET_SIZE(orig_args) - argidx;
+ v = PyTuple_New(n);
+ if (v == NULL)
+ goto error;
+ while (--n >= 0) {
+ PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx);
+ Py_INCREF(w);
+ PyTuple_SET_ITEM(v, n, w);
+ }
+ args = v;
+ } else {
+ Py_INCREF(orig_args);
+ args = orig_args;
+ }
+ args_owned = 1;
+ /* Take what we have of the result and let the Unicode formatting
+ function format the rest of the input. */
+ rescnt = res - PyString_AS_STRING(result);
+ if (_PyString_Resize(&result, rescnt))
+ goto error;
+ fmtcnt = PyString_GET_SIZE(format) - \
+ (fmt - PyString_AS_STRING(format));
+ format = PyUnicode_Decode(fmt, fmtcnt, NULL, NULL);
+ if (format == NULL)
+ goto error;
+ v = PyUnicode_Format(format, args);
+ Py_DECREF(format);
+ if (v == NULL)
+ goto error;
+ /* Paste what we have (result) to what the Unicode formatting
+ function returned (v) and return the result (or error) */
+ w = PyUnicode_Concat(result, v);
+ Py_DECREF(result);
+ Py_DECREF(v);
+ Py_DECREF(args);
+ return w;
+#endif /* Py_USING_UNICODE */
+
+ error:
+ Py_DECREF(result);
+ if (args_owned) {
+ Py_DECREF(args);
+ }
+ return NULL;
+}
+
+void
+PyString_InternInPlace(PyObject **p)
+{
+ register PyStringObject *s = (PyStringObject *)(*p);
+ PyObject *t;
+ if (s == NULL || !PyString_Check(s))
+ Py_FatalError("PyString_InternInPlace: strings only please!");
+ /* If it's a string subclass, we don't really know what putting
+ it in the interned dict might do. */
+ if (!PyString_CheckExact(s))
+ return;
+ if (PyString_CHECK_INTERNED(s))
+ return;
+ if (interned == NULL) {
+ interned = PyDict_New();
+ if (interned == NULL) {
+ PyErr_Clear(); /* Don't leave an exception */
+ return;
+ }
+ }
+ t = PyDict_GetItem(interned, (PyObject *)s);
+ if (t) {
+ Py_INCREF(t);
+ Py_DECREF(*p);
+ *p = t;
+ return;
+ }
+
+ if (PyDict_SetItem(interned, (PyObject *)s, (PyObject *)s) < 0) {
+ PyErr_Clear();
+ return;
+ }
+ /* The two references in interned are not counted by refcnt.
+ The string deallocator will take care of this */
+ Py_REFCNT(s) -= 2;
+ PyString_CHECK_INTERNED(s) = SSTATE_INTERNED_MORTAL;
+}
+
+void
+PyString_InternImmortal(PyObject **p)
+{
+ PyString_InternInPlace(p);
+ if (PyString_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) {
+ PyString_CHECK_INTERNED(*p) = SSTATE_INTERNED_IMMORTAL;
+ Py_INCREF(*p);
+ }
+}
+
+
+PyObject *
+PyString_InternFromString(const char *cp)
+{
+ PyObject *s = PyString_FromString(cp);
+ if (s == NULL)
+ return NULL;
+ PyString_InternInPlace(&s);
+ return s;
+}
+
+void
+PyString_Fini(void)
+{
+ int i;
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ Py_CLEAR(characters[i]);
+ Py_CLEAR(nullstring);
+}
+
+void _Py_ReleaseInternedStrings(void)
+{
+ PyObject *keys;
+ PyStringObject *s;
+ Py_ssize_t i, n;
+ Py_ssize_t immortal_size = 0, mortal_size = 0;
+
+ if (interned == NULL || !PyDict_Check(interned))
+ return;
+ keys = PyDict_Keys(interned);
+ if (keys == NULL || !PyList_Check(keys)) {
+ PyErr_Clear();
+ return;
+ }
+
+ /* Since _Py_ReleaseInternedStrings() is intended to help a leak
+ detector, interned strings are not forcibly deallocated; rather, we
+ give them their stolen references back, and then clear and DECREF
+ the interned dict. */
+
+ n = PyList_GET_SIZE(keys);
+ fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n",
+ n);
+ for (i = 0; i < n; i++) {
+ s = (PyStringObject *) PyList_GET_ITEM(keys, i);
+ switch (s->ob_sstate) {
+ case SSTATE_NOT_INTERNED:
+ /* XXX Shouldn't happen */
+ break;
+ case SSTATE_INTERNED_IMMORTAL:
+ Py_REFCNT(s) += 1;
+ immortal_size += Py_SIZE(s);
+ break;
+ case SSTATE_INTERNED_MORTAL:
+ Py_REFCNT(s) += 2;
+ mortal_size += Py_SIZE(s);
+ break;
+ default:
+ Py_FatalError("Inconsistent interned string state.");
+ }
+ s->ob_sstate = SSTATE_NOT_INTERNED;
+ }
+ fprintf(stderr, "total size of all interned strings: "
+ "%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d "
+ "mortal/immortal\n", mortal_size, immortal_size);
+ Py_DECREF(keys);
+ PyDict_Clear(interned);
+ Py_CLEAR(interned);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/structseq.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/structseq.c
new file mode 100644
index 0000000000..6dc4312918
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/structseq.c
@@ -0,0 +1,540 @@
+/* Implementation helper: a struct that looks like a tuple. See timemodule
+ and posixmodule for example uses. */
+
+#include "Python.h"
+#include "structmember.h"
+#include "structseq.h"
+
+static char visible_length_key[] = "n_sequence_fields";
+static char real_length_key[] = "n_fields";
+static char unnamed_fields_key[] = "n_unnamed_fields";
+
+/* Fields with this name have only a field index, not a field name.
+ They are only allowed for indices < n_visible_fields. */
+char *PyStructSequence_UnnamedField = "unnamed field";
+
+#define VISIBLE_SIZE(op) Py_SIZE(op)
+#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
+ PyDict_GetItemString((tp)->tp_dict, visible_length_key))
+
+#define REAL_SIZE_TP(tp) PyInt_AsLong( \
+ PyDict_GetItemString((tp)->tp_dict, real_length_key))
+#define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
+
+#define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
+ PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
+#define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
+
+
+PyObject *
+PyStructSequence_New(PyTypeObject *type)
+{
+ PyStructSequence *obj;
+
+ obj = PyObject_New(PyStructSequence, type);
+ if (obj == NULL)
+ return NULL;
+ Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
+
+ return (PyObject*) obj;
+}
+
+static void
+structseq_dealloc(PyStructSequence *obj)
+{
+ Py_ssize_t i, size;
+
+ size = REAL_SIZE(obj);
+ for (i = 0; i < size; ++i) {
+ Py_XDECREF(obj->ob_item[i]);
+ }
+ PyObject_Del(obj);
+}
+
+static Py_ssize_t
+structseq_length(PyStructSequence *obj)
+{
+ return VISIBLE_SIZE(obj);
+}
+
+static PyObject*
+structseq_item(PyStructSequence *obj, Py_ssize_t i)
+{
+ if (i < 0 || i >= VISIBLE_SIZE(obj)) {
+ PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+ return NULL;
+ }
+ Py_INCREF(obj->ob_item[i]);
+ return obj->ob_item[i];
+}
+
+static PyObject*
+structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
+{
+ PyTupleObject *np;
+ Py_ssize_t i;
+
+ if (low < 0)
+ low = 0;
+ if (high > VISIBLE_SIZE(obj))
+ high = VISIBLE_SIZE(obj);
+ if (high < low)
+ high = low;
+ np = (PyTupleObject *)PyTuple_New(high-low);
+ if (np == NULL)
+ return NULL;
+ for(i = low; i < high; ++i) {
+ PyObject *v = obj->ob_item[i];
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(np, i-low, v);
+ }
+ return (PyObject *) np;
+}
+
+static PyObject *
+structseq_subscript(PyStructSequence *self, PyObject *item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+
+ if (i < 0)
+ i += VISIBLE_SIZE(self);
+
+ if (i < 0 || i >= VISIBLE_SIZE(self)) {
+ PyErr_SetString(PyExc_IndexError,
+ "tuple index out of range");
+ return NULL;
+ }
+ Py_INCREF(self->ob_item[i]);
+ return self->ob_item[i];
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelen, cur, i;
+ PyObject *result;
+
+ if (PySlice_GetIndicesEx((PySliceObject *)item,
+ VISIBLE_SIZE(self), &start, &stop,
+ &step, &slicelen) < 0) {
+ return NULL;
+ }
+ if (slicelen <= 0)
+ return PyTuple_New(0);
+ result = PyTuple_New(slicelen);
+ if (result == NULL)
+ return NULL;
+ for (cur = start, i = 0; i < slicelen;
+ cur += step, i++) {
+ PyObject *v = self->ob_item[cur];
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(result, i, v);
+ }
+ return result;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "structseq index must be integer");
+ return NULL;
+ }
+}
+
+static PyObject *
+structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *arg = NULL;
+ PyObject *dict = NULL;
+ PyObject *ob;
+ PyStructSequence *res = NULL;
+ Py_ssize_t len, min_len, max_len, i, n_unnamed_fields;
+ static char *kwlist[] = {"sequence", "dict", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:structseq",
+ kwlist, &arg, &dict))
+ return NULL;
+
+ arg = PySequence_Fast(arg, "constructor requires a sequence");
+
+ if (!arg) {
+ return NULL;
+ }
+
+ if (dict && !PyDict_Check(dict)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.500s() takes a dict as second arg, if any",
+ type->tp_name);
+ Py_DECREF(arg);
+ return NULL;
+ }
+
+ len = PySequence_Fast_GET_SIZE(arg);
+ min_len = VISIBLE_SIZE_TP(type);
+ max_len = REAL_SIZE_TP(type);
+ n_unnamed_fields = UNNAMED_FIELDS_TP(type);
+
+ if (min_len != max_len) {
+ if (len < min_len) {
+ PyErr_Format(PyExc_TypeError,
+ "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
+ }
+
+ if (len > max_len) {
+ PyErr_Format(PyExc_TypeError,
+ "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+ type->tp_name, max_len, len);
+ Py_DECREF(arg);
+ return NULL;
+ }
+ }
+ else {
+ if (len != min_len) {
+ PyErr_Format(PyExc_TypeError,
+ "%.500s() takes a %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
+ }
+ }
+
+ res = (PyStructSequence*) PyStructSequence_New(type);
+ if (res == NULL) {
+ Py_DECREF(arg);
+ return NULL;
+ }
+ for (i = 0; i < len; ++i) {
+ PyObject *v = PySequence_Fast_GET_ITEM(arg, i);
+ Py_INCREF(v);
+ res->ob_item[i] = v;
+ }
+ for (; i < max_len; ++i) {
+ if (dict && (ob = PyDict_GetItemString(
+ dict, type->tp_members[i-n_unnamed_fields].name))) {
+ }
+ else {
+ ob = Py_None;
+ }
+ Py_INCREF(ob);
+ res->ob_item[i] = ob;
+ }
+
+ Py_DECREF(arg);
+ return (PyObject*) res;
+}
+
+static PyObject *
+make_tuple(PyStructSequence *obj)
+{
+ return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
+}
+
+static PyObject *
+structseq_repr(PyStructSequence *obj)
+{
+ /* buffer and type size were chosen well considered. */
+#define REPR_BUFFER_SIZE 512
+#define TYPE_MAXSIZE 100
+
+ PyObject *tup;
+ PyTypeObject *typ = Py_TYPE(obj);
+ int i, removelast = 0;
+ Py_ssize_t len;
+ char buf[REPR_BUFFER_SIZE];
+ char *endofbuf, *pbuf = buf;
+
+ /* pointer to end of writeable buffer; safes space for "...)\0" */
+ endofbuf= &buf[REPR_BUFFER_SIZE-5];
+
+ if ((tup = make_tuple(obj)) == NULL) {
+ return NULL;
+ }
+
+ /* "typename(", limited to TYPE_MAXSIZE */
+ len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
+ strlen(typ->tp_name);
+ strncpy(pbuf, typ->tp_name, len);
+ pbuf += len;
+ *pbuf++ = '(';
+
+ for (i=0; i < VISIBLE_SIZE(obj); i++) {
+ PyObject *val, *repr;
+ char *cname, *crepr;
+
+ cname = typ->tp_members[i].name;
+
+ val = PyTuple_GetItem(tup, i);
+ if (cname == NULL || val == NULL) {
+ return NULL;
+ }
+ repr = PyObject_Repr(val);
+ if (repr == NULL) {
+ Py_DECREF(tup);
+ return NULL;
+ }
+ crepr = PyString_AsString(repr);
+ if (crepr == NULL) {
+ Py_DECREF(tup);
+ Py_DECREF(repr);
+ return NULL;
+ }
+
+ /* + 3: keep space for "=" and ", " */
+ len = strlen(cname) + strlen(crepr) + 3;
+ if ((pbuf+len) <= endofbuf) {
+ strcpy(pbuf, cname);
+ pbuf += strlen(cname);
+ *pbuf++ = '=';
+ strcpy(pbuf, crepr);
+ pbuf += strlen(crepr);
+ *pbuf++ = ',';
+ *pbuf++ = ' ';
+ removelast = 1;
+ Py_DECREF(repr);
+ }
+ else {
+ strcpy(pbuf, "...");
+ pbuf += 3;
+ removelast = 0;
+ Py_DECREF(repr);
+ break;
+ }
+ }
+ Py_DECREF(tup);
+ if (removelast) {
+ /* overwrite last ", " */
+ pbuf-=2;
+ }
+ *pbuf++ = ')';
+ *pbuf = '\0';
+
+ return PyString_FromString(buf);
+}
+
+static PyObject *
+structseq_concat(PyStructSequence *obj, PyObject *b)
+{
+ PyObject *tup, *result;
+ tup = make_tuple(obj);
+ result = PySequence_Concat(tup, b);
+ Py_DECREF(tup);
+ return result;
+}
+
+static PyObject *
+structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
+{
+ PyObject *tup, *result;
+ tup = make_tuple(obj);
+ result = PySequence_Repeat(tup, n);
+ Py_DECREF(tup);
+ return result;
+}
+
+static int
+structseq_contains(PyStructSequence *obj, PyObject *o)
+{
+ PyObject *tup;
+ int result;
+ tup = make_tuple(obj);
+ if (!tup)
+ return -1;
+ result = PySequence_Contains(tup, o);
+ Py_DECREF(tup);
+ return result;
+}
+
+static long
+structseq_hash(PyObject *obj)
+{
+ PyObject *tup;
+ long result;
+ tup = make_tuple((PyStructSequence*) obj);
+ if (!tup)
+ return -1;
+ result = PyObject_Hash(tup);
+ Py_DECREF(tup);
+ return result;
+}
+
+static PyObject *
+structseq_richcompare(PyObject *obj, PyObject *o2, int op)
+{
+ PyObject *tup, *result;
+ tup = make_tuple((PyStructSequence*) obj);
+ result = PyObject_RichCompare(tup, o2, op);
+ Py_DECREF(tup);
+ return result;
+}
+
+static PyObject *
+structseq_reduce(PyStructSequence* self)
+{
+ PyObject* tup;
+ PyObject* dict;
+ PyObject* result;
+ Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
+ int i;
+
+ n_fields = REAL_SIZE(self);
+ n_visible_fields = VISIBLE_SIZE(self);
+ n_unnamed_fields = UNNAMED_FIELDS(self);
+ tup = PyTuple_New(n_visible_fields);
+ if (!tup) {
+ return NULL;
+ }
+
+ dict = PyDict_New();
+ if (!dict) {
+ Py_DECREF(tup);
+ return NULL;
+ }
+
+ for (i = 0; i < n_visible_fields; i++) {
+ Py_INCREF(self->ob_item[i]);
+ PyTuple_SET_ITEM(tup, i, self->ob_item[i]);
+ }
+
+ for (; i < n_fields; i++) {
+ char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name;
+ PyDict_SetItemString(dict, n,
+ self->ob_item[i]);
+ }
+
+ result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict);
+
+ Py_DECREF(tup);
+ Py_DECREF(dict);
+
+ return result;
+}
+
+static PySequenceMethods structseq_as_sequence = {
+ (lenfunc)structseq_length,
+ (binaryfunc)structseq_concat, /* sq_concat */
+ (ssizeargfunc)structseq_repeat, /* sq_repeat */
+ (ssizeargfunc)structseq_item, /* sq_item */
+ (ssizessizeargfunc)structseq_slice, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)structseq_contains, /* sq_contains */
+};
+
+static PyMappingMethods structseq_as_mapping = {
+ (lenfunc)structseq_length,
+ (binaryfunc)structseq_subscript,
+};
+
+static PyMethodDef structseq_methods[] = {
+ {"__reduce__", (PyCFunction)structseq_reduce,
+ METH_NOARGS, NULL},
+ {NULL, NULL}
+};
+
+static PyTypeObject _struct_sequence_template = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ NULL, /* tp_name */
+ 0, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)structseq_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)structseq_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &structseq_as_sequence, /* tp_as_sequence */
+ &structseq_as_mapping, /* tp_as_mapping */
+ structseq_hash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ NULL, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ structseq_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ structseq_methods, /* tp_methods */
+ NULL, /* 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 */
+ structseq_new, /* tp_new */
+};
+
+void
+PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
+{
+ PyObject *dict;
+ PyMemberDef* members;
+ int n_members, n_unnamed_members, i, k;
+
+#ifdef Py_TRACE_REFS
+ /* if the type object was chained, unchain it first
+ before overwriting its storage */
+ if (type->_ob_next) {
+ _Py_ForgetReference((PyObject*)type);
+ }
+#endif
+
+ n_unnamed_members = 0;
+ for (i = 0; desc->fields[i].name != NULL; ++i)
+ if (desc->fields[i].name == PyStructSequence_UnnamedField)
+ n_unnamed_members++;
+ n_members = i;
+
+ memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
+ type->tp_name = desc->name;
+ type->tp_doc = desc->doc;
+ type->tp_basicsize = sizeof(PyStructSequence)+
+ sizeof(PyObject*)*(n_members-1);
+ type->tp_itemsize = 0;
+
+ members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
+ if (members == NULL)
+ return;
+
+ for (i = k = 0; i < n_members; ++i) {
+ if (desc->fields[i].name == PyStructSequence_UnnamedField)
+ continue;
+ members[k].name = desc->fields[i].name;
+ members[k].type = T_OBJECT;
+ members[k].offset = offsetof(PyStructSequence, ob_item)
+ + i * sizeof(PyObject*);
+ members[k].flags = READONLY;
+ members[k].doc = desc->fields[i].doc;
+ k++;
+ }
+ members[k].name = NULL;
+
+ type->tp_members = members;
+
+ if (PyType_Ready(type) < 0)
+ return;
+ Py_INCREF(type);
+
+ dict = type->tp_dict;
+#define SET_DICT_FROM_INT(key, value) \
+ do { \
+ PyObject *v = PyInt_FromLong((long) value); \
+ if (v != NULL) { \
+ PyDict_SetItemString(dict, key, v); \
+ Py_DECREF(v); \
+ } \
+ } while (0)
+
+ SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
+ SET_DICT_FROM_INT(real_length_key, n_members);
+ SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/tupleobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/tupleobject.c
new file mode 100644
index 0000000000..8193e441cb
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/tupleobject.c
@@ -0,0 +1,1040 @@
+
+/* Tuple object implementation */
+
+#include "Python.h"
+
+/* Speed optimization to avoid frequent malloc/free of small tuples */
+#ifndef PyTuple_MAXSAVESIZE
+#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
+#endif
+#ifndef PyTuple_MAXFREELIST
+#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */
+#endif
+
+#if PyTuple_MAXSAVESIZE > 0
+/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
+ tuple () of which at most one instance will be allocated.
+*/
+static PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
+static int numfree[PyTuple_MAXSAVESIZE];
+#endif
+#ifdef COUNT_ALLOCS
+Py_ssize_t fast_tuple_allocs;
+Py_ssize_t tuple_zero_allocs;
+#endif
+
+/* Debug statistic to count GC tracking of tuples.
+ Please note that tuples are only untracked when considered by the GC, and
+ many of them will be dead before. Therefore, a tracking rate close to 100%
+ does not necessarily prove that the heuristic is inefficient.
+*/
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+ fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n",
+ count_tracked + count_untracked);
+ fprintf(stderr, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T
+ "d\n", count_tracked);
+ fprintf(stderr, "%.2f%% tuple tracking rate\n\n",
+ (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
+PyObject *
+PyTuple_New(register Py_ssize_t size)
+{
+ register PyTupleObject *op;
+ Py_ssize_t i;
+ if (size < 0) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+#if PyTuple_MAXSAVESIZE > 0
+ if (size == 0 && free_list[0]) {
+ op = free_list[0];
+ Py_INCREF(op);
+#ifdef COUNT_ALLOCS
+ tuple_zero_allocs++;
+#endif
+ return (PyObject *) op;
+ }
+ if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) {
+ free_list[size] = (PyTupleObject *) op->ob_item[0];
+ numfree[size]--;
+#ifdef COUNT_ALLOCS
+ fast_tuple_allocs++;
+#endif
+ /* Inline PyObject_InitVar */
+#ifdef Py_TRACE_REFS
+ Py_SIZE(op) = size;
+ Py_TYPE(op) = &PyTuple_Type;
+#endif
+ _Py_NewReference((PyObject *)op);
+ }
+ else
+#endif
+ {
+ Py_ssize_t nbytes = size * sizeof(PyObject *);
+ /* Check for overflow */
+ if (nbytes / sizeof(PyObject *) != (size_t)size ||
+ (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)))
+ {
+ return PyErr_NoMemory();
+ }
+
+ op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
+ if (op == NULL)
+ return NULL;
+ }
+ for (i=0; i < size; i++)
+ op->ob_item[i] = NULL;
+#if PyTuple_MAXSAVESIZE > 0
+ if (size == 0) {
+ free_list[0] = op;
+ ++numfree[0];
+ Py_INCREF(op); /* extra INCREF so that this is never freed */
+ }
+#endif
+#ifdef SHOW_TRACK_COUNT
+ count_tracked++;
+#endif
+ _PyObject_GC_TRACK(op);
+ return (PyObject *) op;
+}
+
+Py_ssize_t
+PyTuple_Size(register PyObject *op)
+{
+ if (!PyTuple_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ else
+ return Py_SIZE(op);
+}
+
+PyObject *
+PyTuple_GetItem(register PyObject *op, register Py_ssize_t i)
+{
+ if (!PyTuple_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (i < 0 || i >= Py_SIZE(op)) {
+ PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+ return NULL;
+ }
+ return ((PyTupleObject *)op) -> ob_item[i];
+}
+
+int
+PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
+{
+ register PyObject *olditem;
+ register PyObject **p;
+ if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
+ Py_XDECREF(newitem);
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (i < 0 || i >= Py_SIZE(op)) {
+ Py_XDECREF(newitem);
+ PyErr_SetString(PyExc_IndexError,
+ "tuple assignment index out of range");
+ return -1;
+ }
+ p = ((PyTupleObject *)op) -> ob_item + i;
+ olditem = *p;
+ *p = newitem;
+ Py_XDECREF(olditem);
+ return 0;
+}
+
+void
+_PyTuple_MaybeUntrack(PyObject *op)
+{
+ PyTupleObject *t;
+ Py_ssize_t i, n;
+
+ if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+ return;
+ t = (PyTupleObject *) op;
+ n = Py_SIZE(t);
+ for (i = 0; i < n; i++) {
+ PyObject *elt = PyTuple_GET_ITEM(t, i);
+ /* Tuple with NULL elements aren't
+ fully constructed, don't untrack
+ them yet. */
+ if (!elt ||
+ _PyObject_GC_MAY_BE_TRACKED(elt))
+ return;
+ }
+#ifdef SHOW_TRACK_COUNT
+ count_tracked--;
+ count_untracked++;
+#endif
+ _PyObject_GC_UNTRACK(op);
+}
+
+PyObject *
+PyTuple_Pack(Py_ssize_t n, ...)
+{
+ Py_ssize_t i;
+ PyObject *o;
+ PyObject *result;
+ PyObject **items;
+ va_list vargs;
+
+ va_start(vargs, n);
+ result = PyTuple_New(n);
+ if (result == NULL) {
+ va_end(vargs);
+ return NULL;
+ }
+ items = ((PyTupleObject *)result)->ob_item;
+ for (i = 0; i < n; i++) {
+ o = va_arg(vargs, PyObject *);
+ Py_INCREF(o);
+ items[i] = o;
+ }
+ va_end(vargs);
+ return result;
+}
+
+
+/* Methods */
+
+static void
+tupledealloc(register PyTupleObject *op)
+{
+ register Py_ssize_t i;
+ register Py_ssize_t len = Py_SIZE(op);
+ PyObject_GC_UnTrack(op);
+ Py_TRASHCAN_SAFE_BEGIN(op)
+ if (len > 0) {
+ i = len;
+ while (--i >= 0)
+ Py_XDECREF(op->ob_item[i]);
+#if PyTuple_MAXSAVESIZE > 0
+ if (len < PyTuple_MAXSAVESIZE &&
+ numfree[len] < PyTuple_MAXFREELIST &&
+ Py_TYPE(op) == &PyTuple_Type)
+ {
+ op->ob_item[0] = (PyObject *) free_list[len];
+ numfree[len]++;
+ free_list[len] = op;
+ goto done; /* return */
+ }
+#endif
+ }
+ Py_TYPE(op)->tp_free((PyObject *)op);
+done:
+ Py_TRASHCAN_SAFE_END(op)
+}
+
+static int
+tupleprint(PyTupleObject *op, FILE *fp, int flags)
+{
+ Py_ssize_t i;
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, "(");
+ Py_END_ALLOW_THREADS
+ for (i = 0; i < Py_SIZE(op); i++) {
+ if (i > 0) {
+ Py_BEGIN_ALLOW_THREADS
+ fprintf(fp, ", ");
+ Py_END_ALLOW_THREADS
+ }
+ if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
+ return -1;
+ }
+ i = Py_SIZE(op);
+ Py_BEGIN_ALLOW_THREADS
+ if (i == 1)
+ fprintf(fp, ",");
+ fprintf(fp, ")");
+ Py_END_ALLOW_THREADS
+ return 0;
+}
+
+static PyObject *
+tuplerepr(PyTupleObject *v)
+{
+ Py_ssize_t i, n;
+ PyObject *s, *temp;
+ PyObject *pieces, *result = NULL;
+
+ n = Py_SIZE(v);
+ if (n == 0)
+ return PyString_FromString("()");
+
+ /* While not mutable, it is still possible to end up with a cycle in a
+ tuple through an object that stores itself within a tuple (and thus
+ infinitely asks for the repr of itself). This should only be
+ possible within a type. */
+ i = Py_ReprEnter((PyObject *)v);
+ if (i != 0) {
+ return i > 0 ? PyString_FromString("(...)") : NULL;
+ }
+
+ pieces = PyTuple_New(n);
+ if (pieces == NULL)
+ return NULL;
+
+ /* Do repr() on each element. */
+ for (i = 0; i < n; ++i) {
+ if (Py_EnterRecursiveCall(" while getting the repr of a tuple"))
+ goto Done;
+ s = PyObject_Repr(v->ob_item[i]);
+ Py_LeaveRecursiveCall();
+ if (s == NULL)
+ goto Done;
+ PyTuple_SET_ITEM(pieces, i, s);
+ }
+
+ /* Add "()" decorations to the first and last items. */
+ assert(n > 0);
+ s = PyString_FromString("(");
+ if (s == NULL)
+ goto Done;
+ temp = PyTuple_GET_ITEM(pieces, 0);
+ PyString_ConcatAndDel(&s, temp);
+ PyTuple_SET_ITEM(pieces, 0, s);
+ if (s == NULL)
+ goto Done;
+
+ s = PyString_FromString(n == 1 ? ",)" : ")");
+ if (s == NULL)
+ goto Done;
+ temp = PyTuple_GET_ITEM(pieces, n-1);
+ PyString_ConcatAndDel(&temp, s);
+ PyTuple_SET_ITEM(pieces, n-1, temp);
+ if (temp == NULL)
+ goto Done;
+
+ /* Paste them all together with ", " between. */
+ s = PyString_FromString(", ");
+ if (s == NULL)
+ goto Done;
+ result = _PyString_Join(s, pieces);
+ Py_DECREF(s);
+
+Done:
+ Py_DECREF(pieces);
+ Py_ReprLeave((PyObject *)v);
+ return result;
+}
+
+/* The addend 82520, was selected from the range(0, 1000000) for
+ generating the greatest number of prime multipliers for tuples
+ upto length eight:
+
+ 1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533,
+ 1330111, 1412633, 1165069, 1247599, 1495177, 1577699
+*/
+
+static long
+tuplehash(PyTupleObject *v)
+{
+ register long x, y;
+ register Py_ssize_t len = Py_SIZE(v);
+ register PyObject **p;
+ long mult = 1000003L;
+ x = 0x345678L;
+ p = v->ob_item;
+ while (--len >= 0) {
+ y = PyObject_Hash(*p++);
+ if (y == -1)
+ return -1;
+ x = (x ^ y) * mult;
+ /* the cast might truncate len; that doesn't change hash stability */
+ mult += (long)(82520L + len + len);
+ }
+ x += 97531L;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
+static Py_ssize_t
+tuplelength(PyTupleObject *a)
+{
+ return Py_SIZE(a);
+}
+
+static int
+tuplecontains(PyTupleObject *a, PyObject *el)
+{
+ Py_ssize_t i;
+ int cmp;
+
+ for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i)
+ cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
+ Py_EQ);
+ return cmp;
+}
+
+static PyObject *
+tupleitem(register PyTupleObject *a, register Py_ssize_t i)
+{
+ if (i < 0 || i >= Py_SIZE(a)) {
+ PyErr_SetString(PyExc_IndexError, "tuple index out of range");
+ return NULL;
+ }
+ Py_INCREF(a->ob_item[i]);
+ return a->ob_item[i];
+}
+
+static PyObject *
+tupleslice(register PyTupleObject *a, register Py_ssize_t ilow,
+ register Py_ssize_t ihigh)
+{
+ register PyTupleObject *np;
+ PyObject **src, **dest;
+ register Py_ssize_t i;
+ Py_ssize_t len;
+ if (ilow < 0)
+ ilow = 0;
+ if (ihigh > Py_SIZE(a))
+ ihigh = Py_SIZE(a);
+ if (ihigh < ilow)
+ ihigh = ilow;
+ if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) {
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ len = ihigh - ilow;
+ np = (PyTupleObject *)PyTuple_New(len);
+ if (np == NULL)
+ return NULL;
+ src = a->ob_item + ilow;
+ dest = np->ob_item;
+ for (i = 0; i < len; i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ return (PyObject *)np;
+}
+
+PyObject *
+PyTuple_GetSlice(PyObject *op, Py_ssize_t i, Py_ssize_t j)
+{
+ if (op == NULL || !PyTuple_Check(op)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return tupleslice((PyTupleObject *)op, i, j);
+}
+
+static PyObject *
+tupleconcat(register PyTupleObject *a, register PyObject *bb)
+{
+ register Py_ssize_t size;
+ register Py_ssize_t i;
+ PyObject **src, **dest;
+ PyTupleObject *np;
+ if (!PyTuple_Check(bb)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only concatenate tuple (not \"%.200s\") to tuple",
+ Py_TYPE(bb)->tp_name);
+ return NULL;
+ }
+#define b ((PyTupleObject *)bb)
+ size = Py_SIZE(a) + Py_SIZE(b);
+ if (size < 0)
+ return PyErr_NoMemory();
+ np = (PyTupleObject *) PyTuple_New(size);
+ if (np == NULL) {
+ return NULL;
+ }
+ src = a->ob_item;
+ dest = np->ob_item;
+ for (i = 0; i < Py_SIZE(a); i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ src = b->ob_item;
+ dest = np->ob_item + Py_SIZE(a);
+ for (i = 0; i < Py_SIZE(b); i++) {
+ PyObject *v = src[i];
+ Py_INCREF(v);
+ dest[i] = v;
+ }
+ return (PyObject *)np;
+#undef b
+}
+
+static PyObject *
+tuplerepeat(PyTupleObject *a, Py_ssize_t n)
+{
+ Py_ssize_t i, j;
+ Py_ssize_t size;
+ PyTupleObject *np;
+ PyObject **p, **items;
+ if (n < 0)
+ n = 0;
+ if (Py_SIZE(a) == 0 || n == 1) {
+ if (PyTuple_CheckExact(a)) {
+ /* Since tuples are immutable, we can return a shared
+ copy in this case */
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ if (Py_SIZE(a) == 0)
+ return PyTuple_New(0);
+ }
+ size = Py_SIZE(a) * n;
+ if (size/Py_SIZE(a) != n)
+ return PyErr_NoMemory();
+ np = (PyTupleObject *) PyTuple_New(size);
+ if (np == NULL)
+ return NULL;
+ p = np->ob_item;
+ items = a->ob_item;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < Py_SIZE(a); j++) {
+ *p = items[j];
+ Py_INCREF(*p);
+ p++;
+ }
+ }
+ return (PyObject *) np;
+}
+
+static PyObject *
+tupleindex(PyTupleObject *self, PyObject *args)
+{
+ Py_ssize_t i, start=0, stop=Py_SIZE(self);
+ PyObject *v;
+
+ if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
+ _PyEval_SliceIndex, &start,
+ _PyEval_SliceIndex, &stop))
+ return NULL;
+ if (start < 0) {
+ start += Py_SIZE(self);
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0) {
+ stop += Py_SIZE(self);
+ if (stop < 0)
+ stop = 0;
+ }
+ for (i = start; i < stop && i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ return PyInt_FromSsize_t(i);
+ else if (cmp < 0)
+ return NULL;
+ }
+ PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple");
+ return NULL;
+}
+
+static PyObject *
+tuplecount(PyTupleObject *self, PyObject *v)
+{
+ Py_ssize_t count = 0;
+ Py_ssize_t i;
+
+ for (i = 0; i < Py_SIZE(self); i++) {
+ int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
+ if (cmp > 0)
+ count++;
+ else if (cmp < 0)
+ return NULL;
+ }
+ return PyInt_FromSsize_t(count);
+}
+
+static int
+tupletraverse(PyTupleObject *o, visitproc visit, void *arg)
+{
+ Py_ssize_t i;
+
+ for (i = Py_SIZE(o); --i >= 0; )
+ Py_VISIT(o->ob_item[i]);
+ return 0;
+}
+
+static PyObject *
+tuplerichcompare(PyObject *v, PyObject *w, int op)
+{
+ PyTupleObject *vt, *wt;
+ Py_ssize_t i;
+ Py_ssize_t vlen, wlen;
+
+ if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ vt = (PyTupleObject *)v;
+ wt = (PyTupleObject *)w;
+
+ vlen = Py_SIZE(vt);
+ wlen = Py_SIZE(wt);
+
+ /* Note: the corresponding code for lists has an "early out" test
+ * here when op is EQ or NE and the lengths differ. That pays there,
+ * but Tim was unable to find any real code where EQ/NE tuple
+ * compares don't have the same length, so testing for it here would
+ * have cost without benefit.
+ */
+
+ /* Search for the first index where items are different.
+ * Note that because tuples are immutable, it's safe to reuse
+ * vlen and wlen across the comparison calls.
+ */
+ for (i = 0; i < vlen && i < wlen; i++) {
+ int k = PyObject_RichCompareBool(vt->ob_item[i],
+ wt->ob_item[i], Py_EQ);
+ if (k < 0)
+ return NULL;
+ if (!k)
+ break;
+ }
+
+ if (i >= vlen || i >= wlen) {
+ /* No more items to compare -- compare sizes */
+ int cmp;
+ PyObject *res;
+ switch (op) {
+ case Py_LT: cmp = vlen < wlen; break;
+ case Py_LE: cmp = vlen <= wlen; break;
+ case Py_EQ: cmp = vlen == wlen; break;
+ case Py_NE: cmp = vlen != wlen; break;
+ case Py_GT: cmp = vlen > wlen; break;
+ case Py_GE: cmp = vlen >= wlen; break;
+ default: return NULL; /* cannot happen */
+ }
+ if (cmp)
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+ }
+
+ /* We have an item that differs -- shortcuts for EQ/NE */
+ if (op == Py_EQ) {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ if (op == Py_NE) {
+ Py_INCREF(Py_True);
+ return Py_True;
+ }
+
+ /* Compare the final item again using the proper operator */
+ return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *arg = NULL;
+ static char *kwlist[] = {"sequence", 0};
+
+ if (type != &PyTuple_Type)
+ return tuple_subtype_new(type, args, kwds);
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:tuple", kwlist, &arg))
+ return NULL;
+
+ if (arg == NULL)
+ return PyTuple_New(0);
+ else
+ return PySequence_Tuple(arg);
+}
+
+static PyObject *
+tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *tmp, *newobj, *item;
+ Py_ssize_t i, n;
+
+ assert(PyType_IsSubtype(type, &PyTuple_Type));
+ tmp = tuple_new(&PyTuple_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyTuple_Check(tmp));
+ newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp));
+ if (newobj == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ item = PyTuple_GET_ITEM(tmp, i);
+ Py_INCREF(item);
+ PyTuple_SET_ITEM(newobj, i, item);
+ }
+ Py_DECREF(tmp);
+ return newobj;
+}
+
+PyDoc_STRVAR(tuple_doc,
+"tuple() -> empty tuple\n\
+tuple(iterable) -> tuple initialized from iterable's items\n\
+\n\
+If the argument is a tuple, the return value is the same object.");
+
+static PySequenceMethods tuple_as_sequence = {
+ (lenfunc)tuplelength, /* sq_length */
+ (binaryfunc)tupleconcat, /* sq_concat */
+ (ssizeargfunc)tuplerepeat, /* sq_repeat */
+ (ssizeargfunc)tupleitem, /* sq_item */
+ (ssizessizeargfunc)tupleslice, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)tuplecontains, /* sq_contains */
+};
+
+static PyObject*
+tuplesubscript(PyTupleObject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyTuple_GET_SIZE(self);
+ return tupleitem(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ PyObject* result;
+ PyObject* it;
+ PyObject **src, **dest;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item,
+ PyTuple_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (start == 0 && step == 1 &&
+ slicelength == PyTuple_GET_SIZE(self) &&
+ PyTuple_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ else {
+ result = PyTuple_New(slicelength);
+ if (!result) return NULL;
+
+ src = self->ob_item;
+ dest = ((PyTupleObject *)result)->ob_item;
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ it = src[cur];
+ Py_INCREF(it);
+ dest[i] = it;
+ }
+
+ return result;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "tuple indices must be integers, not %.200s",
+ Py_TYPE(item)->tp_name);
+ return NULL;
+ }
+}
+
+static PyObject *
+tuple_getnewargs(PyTupleObject *v)
+{
+ return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
+
+}
+
+PyDoc_STRVAR(index_doc,
+"T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
+"Raises ValueError if the value is not present."
+);
+PyDoc_STRVAR(count_doc,
+"T.count(value) -> integer -- return number of occurrences of value");
+
+static PyMethodDef tuple_methods[] = {
+ {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS},
+ {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc},
+ {"count", (PyCFunction)tuplecount, METH_O, count_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyMappingMethods tuple_as_mapping = {
+ (lenfunc)tuplelength,
+ (binaryfunc)tuplesubscript,
+ 0
+};
+
+static PyObject *tuple_iter(PyObject *seq);
+
+PyTypeObject PyTuple_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "tuple",
+ sizeof(PyTupleObject) - sizeof(PyObject *),
+ sizeof(PyObject *),
+ (destructor)tupledealloc, /* tp_dealloc */
+ (printfunc)tupleprint, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)tuplerepr, /* tp_repr */
+ 0, /* tp_as_number */
+ &tuple_as_sequence, /* tp_as_sequence */
+ &tuple_as_mapping, /* tp_as_mapping */
+ (hashfunc)tuplehash, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
+ tuple_doc, /* tp_doc */
+ (traverseproc)tupletraverse, /* tp_traverse */
+ 0, /* tp_clear */
+ tuplerichcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ tuple_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ tuple_methods, /* tp_methods */
+ 0, /* 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 */
+ tuple_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
+
+/* The following function breaks the notion that tuples are immutable:
+ it changes the size of a tuple. We get away with this only if there
+ is only one module referencing the object. You can also think of it
+ as creating a new tuple object and destroying the old one, only more
+ efficiently. In any case, don't use this if the tuple may already be
+ known to some other part of the code. */
+
+int
+_PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
+{
+ register PyTupleObject *v;
+ register PyTupleObject *sv;
+ Py_ssize_t i;
+ Py_ssize_t oldsize;
+
+ v = (PyTupleObject *) *pv;
+ if (v == NULL || Py_TYPE(v) != &PyTuple_Type ||
+ (Py_SIZE(v) != 0 && Py_REFCNT(v) != 1)) {
+ *pv = 0;
+ Py_XDECREF(v);
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ oldsize = Py_SIZE(v);
+ if (oldsize == newsize)
+ return 0;
+
+ if (oldsize == 0) {
+ /* Empty tuples are often shared, so we should never
+ resize them in-place even if we do own the only
+ (current) reference */
+ Py_DECREF(v);
+ *pv = PyTuple_New(newsize);
+ return *pv == NULL ? -1 : 0;
+ }
+
+ /* XXX UNREF/NEWREF interface should be more symmetrical */
+ _Py_DEC_REFTOTAL;
+ if (_PyObject_GC_IS_TRACKED(v))
+ _PyObject_GC_UNTRACK(v);
+ _Py_ForgetReference((PyObject *) v);
+ /* DECREF items deleted by shrinkage */
+ for (i = newsize; i < oldsize; i++) {
+ Py_CLEAR(v->ob_item[i]);
+ }
+ sv = PyObject_GC_Resize(PyTupleObject, v, newsize);
+ if (sv == NULL) {
+ *pv = NULL;
+ PyObject_GC_Del(v);
+ return -1;
+ }
+ _Py_NewReference((PyObject *) sv);
+ /* Zero out items added by growing */
+ if (newsize > oldsize)
+ memset(&sv->ob_item[oldsize], 0,
+ sizeof(*sv->ob_item) * (newsize - oldsize));
+ *pv = (PyObject *) sv;
+ _PyObject_GC_TRACK(sv);
+ return 0;
+}
+
+int
+PyTuple_ClearFreeList(void)
+{
+ int freelist_size = 0;
+#if PyTuple_MAXSAVESIZE > 0
+ int i;
+ for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
+ PyTupleObject *p, *q;
+ p = free_list[i];
+ freelist_size += numfree[i];
+ free_list[i] = NULL;
+ numfree[i] = 0;
+ while (p) {
+ q = p;
+ p = (PyTupleObject *)(p->ob_item[0]);
+ PyObject_GC_Del(q);
+ }
+ }
+#endif
+ return freelist_size;
+}
+
+void
+PyTuple_Fini(void)
+{
+#if PyTuple_MAXSAVESIZE > 0
+ /* empty tuples are used all over the place and applications may
+ * rely on the fact that an empty tuple is a singleton. */
+ Py_CLEAR(free_list[0]);
+
+ (void)PyTuple_ClearFreeList();
+#endif
+#ifdef SHOW_TRACK_COUNT
+ show_track();
+#endif
+}
+
+/*********************** Tuple Iterator **************************/
+
+typedef struct {
+ PyObject_HEAD
+ long it_index;
+ PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */
+} tupleiterobject;
+
+static void
+tupleiter_dealloc(tupleiterobject *it)
+{
+ _PyObject_GC_UNTRACK(it);
+ Py_XDECREF(it->it_seq);
+ PyObject_GC_Del(it);
+}
+
+static int
+tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg)
+{
+ Py_VISIT(it->it_seq);
+ return 0;
+}
+
+static PyObject *
+tupleiter_next(tupleiterobject *it)
+{
+ PyTupleObject *seq;
+ PyObject *item;
+
+ assert(it != NULL);
+ seq = it->it_seq;
+ if (seq == NULL)
+ return NULL;
+ assert(PyTuple_Check(seq));
+
+ if (it->it_index < PyTuple_GET_SIZE(seq)) {
+ item = PyTuple_GET_ITEM(seq, it->it_index);
+ ++it->it_index;
+ Py_INCREF(item);
+ return item;
+ }
+
+ Py_DECREF(seq);
+ it->it_seq = NULL;
+ return NULL;
+}
+
+static PyObject *
+tupleiter_len(tupleiterobject *it)
+{
+ Py_ssize_t len = 0;
+ if (it->it_seq)
+ len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
+ return PyInt_FromSsize_t(len);
+}
+
+PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef tupleiter_methods[] = {
+ {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyTupleIter_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "tupleiterator", /* tp_name */
+ sizeof(tupleiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)tupleiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* 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 | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)tupleiter_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ PyObject_SelfIter, /* tp_iter */
+ (iternextfunc)tupleiter_next, /* tp_iternext */
+ tupleiter_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+tuple_iter(PyObject *seq)
+{
+ tupleiterobject *it;
+
+ if (!PyTuple_Check(seq)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type);
+ if (it == NULL)
+ return NULL;
+ it->it_index = 0;
+ Py_INCREF(seq);
+ it->it_seq = (PyTupleObject *)seq;
+ _PyObject_GC_TRACK(it);
+ return (PyObject *)it;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/typeobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/typeobject.c
new file mode 100644
index 0000000000..e42a86b9ee
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/typeobject.c
@@ -0,0 +1,6748 @@
+/* Type object implementation */
+
+#include "Python.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+
+/* Support type attribute cache */
+
+/* The cache can keep references to the names alive for longer than
+ they normally would. This is why the maximum size is limited to
+ MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large
+ strings are used as attribute names. */
+#define MCACHE_MAX_ATTR_SIZE 100
+#define MCACHE_SIZE_EXP 10
+#define MCACHE_HASH(version, name_hash) \
+ (((unsigned int)(version) * (unsigned int)(name_hash)) \
+ >> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP))
+#define MCACHE_HASH_METHOD(type, name) \
+ MCACHE_HASH((type)->tp_version_tag, \
+ ((PyStringObject *)(name))->ob_shash)
+#define MCACHE_CACHEABLE_NAME(name) \
+ PyString_CheckExact(name) && \
+ PyString_GET_SIZE(name) <= MCACHE_MAX_ATTR_SIZE
+
+struct method_cache_entry {
+ unsigned int version;
+ PyObject *name; /* reference to exactly a str or None */
+ PyObject *value; /* borrowed */
+};
+
+static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
+static unsigned int next_version_tag = 0;
+
+unsigned int
+PyType_ClearCache(void)
+{
+ Py_ssize_t i;
+ unsigned int cur_version_tag = next_version_tag - 1;
+
+ for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
+ method_cache[i].version = 0;
+ Py_CLEAR(method_cache[i].name);
+ method_cache[i].value = NULL;
+ }
+ next_version_tag = 0;
+ /* mark all version tags as invalid */
+ PyType_Modified(&PyBaseObject_Type);
+ return cur_version_tag;
+}
+
+void
+PyType_Modified(PyTypeObject *type)
+{
+ /* Invalidate any cached data for the specified type and all
+ subclasses. This function is called after the base
+ classes, mro, or attributes of the type are altered.
+
+ Invariants:
+
+ - Py_TPFLAGS_VALID_VERSION_TAG is never set if
+ Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type
+ objects coming from non-recompiled extension modules)
+
+ - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
+ it must first be set on all super types.
+
+ This function clears the Py_TPFLAGS_VALID_VERSION_TAG of a
+ type (so it must first clear it on all subclasses). The
+ tp_version_tag value is meaningless unless this flag is set.
+ We don't assign new version tags eagerly, but only as
+ needed.
+ */
+ PyObject *raw, *ref;
+ Py_ssize_t i, n;
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
+ return;
+
+ raw = type->tp_subclasses;
+ if (raw != NULL) {
+ n = PyList_GET_SIZE(raw);
+ for (i = 0; i < n; i++) {
+ ref = PyList_GET_ITEM(raw, i);
+ ref = PyWeakref_GET_OBJECT(ref);
+ if (ref != Py_None) {
+ PyType_Modified((PyTypeObject *)ref);
+ }
+ }
+ }
+ type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+}
+
+static void
+type_mro_modified(PyTypeObject *type, PyObject *bases) {
+ /*
+ Check that all base classes or elements of the mro of type are
+ able to be cached. This function is called after the base
+ classes or mro of the type are altered.
+
+ Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
+ inherits from an old-style class, either directly or if it
+ appears in the MRO of a new-style class. No support either for
+ custom MROs that include types that are not officially super
+ types.
+
+ Called from mro_internal, which will subsequently be called on
+ each subclass when their mro is recursively updated.
+ */
+ Py_ssize_t i, n;
+ int clear = 0;
+
+ if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
+ return;
+
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 0; i < n; i++) {
+ PyObject *b = PyTuple_GET_ITEM(bases, i);
+ PyTypeObject *cls;
+
+ if (!PyType_Check(b) ) {
+ clear = 1;
+ break;
+ }
+
+ cls = (PyTypeObject *)b;
+
+ if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
+ !PyType_IsSubtype(type, cls)) {
+ clear = 1;
+ break;
+ }
+ }
+
+ if (clear)
+ type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
+ Py_TPFLAGS_VALID_VERSION_TAG);
+}
+
+static int
+assign_version_tag(PyTypeObject *type)
+{
+ /* Ensure that the tp_version_tag is valid and set
+ Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this
+ must first be done on all super classes. Return 0 if this
+ cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG.
+ */
+ Py_ssize_t i, n;
+ PyObject *bases;
+
+ if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
+ return 1;
+ if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
+ return 0;
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ return 0;
+
+ type->tp_version_tag = next_version_tag++;
+ /* for stress-testing: next_version_tag &= 0xFF; */
+
+ if (type->tp_version_tag == 0) {
+ /* wrap-around or just starting Python - clear the whole
+ cache by filling names with references to Py_None.
+ Values are also set to NULL for added protection, as they
+ are borrowed reference */
+ for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
+ method_cache[i].value = NULL;
+ Py_XDECREF(method_cache[i].name);
+ method_cache[i].name = Py_None;
+ Py_INCREF(Py_None);
+ }
+ /* mark all version tags as invalid */
+ PyType_Modified(&PyBaseObject_Type);
+ return 1;
+ }
+ bases = type->tp_bases;
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 0; i < n; i++) {
+ PyObject *b = PyTuple_GET_ITEM(bases, i);
+ assert(PyType_Check(b));
+ if (!assign_version_tag((PyTypeObject *)b))
+ return 0;
+ }
+ type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG;
+ return 1;
+}
+
+
+static PyMemberDef type_members[] = {
+ {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY},
+ {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY},
+ {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY},
+ {"__weakrefoffset__", T_LONG,
+ offsetof(PyTypeObject, tp_weaklistoffset), READONLY},
+ {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY},
+ {"__dictoffset__", T_LONG,
+ offsetof(PyTypeObject, tp_dictoffset), READONLY},
+ {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY},
+ {0}
+};
+
+static PyObject *
+type_name(PyTypeObject *type, void *context)
+{
+ const char *s;
+
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ PyHeapTypeObject* et = (PyHeapTypeObject*)type;
+
+ Py_INCREF(et->ht_name);
+ return et->ht_name;
+ }
+ else {
+ s = strrchr(type->tp_name, '.');
+ if (s == NULL)
+ s = type->tp_name;
+ else
+ s++;
+ return PyString_FromString(s);
+ }
+}
+
+static int
+type_set_name(PyTypeObject *type, PyObject *value, void *context)
+{
+ PyHeapTypeObject* et;
+ PyObject *tmp;
+
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ PyErr_Format(PyExc_TypeError,
+ "can't set %s.__name__", type->tp_name);
+ return -1;
+ }
+ if (!value) {
+ PyErr_Format(PyExc_TypeError,
+ "can't delete %s.__name__", type->tp_name);
+ return -1;
+ }
+ if (!PyString_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only assign string to %s.__name__, not '%s'",
+ type->tp_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ if (strlen(PyString_AS_STRING(value))
+ != (size_t)PyString_GET_SIZE(value)) {
+ PyErr_Format(PyExc_ValueError,
+ "__name__ must not contain null bytes");
+ return -1;
+ }
+
+ et = (PyHeapTypeObject*)type;
+
+ Py_INCREF(value);
+
+ /* Wait until et is a sane state before Py_DECREF'ing the old et->ht_name
+ value. (Bug #16447.) */
+ tmp = et->ht_name;
+ et->ht_name = value;
+
+ type->tp_name = PyString_AS_STRING(value);
+ Py_DECREF(tmp);
+
+ return 0;
+}
+
+static PyObject *
+type_module(PyTypeObject *type, void *context)
+{
+ PyObject *mod;
+ char *s;
+
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ mod = PyDict_GetItemString(type->tp_dict, "__module__");
+ if (!mod) {
+ PyErr_Format(PyExc_AttributeError, "__module__");
+ return 0;
+ }
+ Py_XINCREF(mod);
+ return mod;
+ }
+ else {
+ s = strrchr(type->tp_name, '.');
+ if (s != NULL)
+ return PyString_FromStringAndSize(
+ type->tp_name, (Py_ssize_t)(s - type->tp_name));
+ return PyString_FromString("__builtin__");
+ }
+}
+
+static int
+type_set_module(PyTypeObject *type, PyObject *value, void *context)
+{
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ PyErr_Format(PyExc_TypeError,
+ "can't set %s.__module__", type->tp_name);
+ return -1;
+ }
+ if (!value) {
+ PyErr_Format(PyExc_TypeError,
+ "can't delete %s.__module__", type->tp_name);
+ return -1;
+ }
+
+ PyType_Modified(type);
+
+ return PyDict_SetItemString(type->tp_dict, "__module__", value);
+}
+
+static PyObject *
+type_abstractmethods(PyTypeObject *type, void *context)
+{
+ PyObject *mod = NULL;
+ /* type itself has an __abstractmethods__ descriptor (this). Don't return
+ that. */
+ if (type != &PyType_Type)
+ mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__");
+ if (!mod) {
+ PyErr_SetString(PyExc_AttributeError, "__abstractmethods__");
+ return NULL;
+ }
+ Py_XINCREF(mod);
+ return mod;
+}
+
+static int
+type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
+{
+ /* __abstractmethods__ should only be set once on a type, in
+ abc.ABCMeta.__new__, so this function doesn't do anything
+ special to update subclasses.
+ */
+ int abstract, res;
+ if (value != NULL) {
+ abstract = PyObject_IsTrue(value);
+ if (abstract < 0)
+ return -1;
+ res = PyDict_SetItemString(type->tp_dict, "__abstractmethods__", value);
+ }
+ else {
+ abstract = 0;
+ res = PyDict_DelItemString(type->tp_dict, "__abstractmethods__");
+ if (res && PyErr_ExceptionMatches(PyExc_KeyError)) {
+ PyErr_SetString(PyExc_AttributeError, "__abstractmethods__");
+ return -1;
+ }
+ }
+ if (res == 0) {
+ PyType_Modified(type);
+ if (abstract)
+ type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
+ else
+ type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT;
+ }
+ return res;
+}
+
+static PyObject *
+type_get_bases(PyTypeObject *type, void *context)
+{
+ Py_INCREF(type->tp_bases);
+ return type->tp_bases;
+}
+
+static PyTypeObject *best_base(PyObject *);
+static int mro_internal(PyTypeObject *);
+static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *);
+static int add_subclass(PyTypeObject*, PyTypeObject*);
+static void remove_subclass(PyTypeObject *, PyTypeObject *);
+static void update_all_slots(PyTypeObject *);
+
+typedef int (*update_callback)(PyTypeObject *, void *);
+static int update_subclasses(PyTypeObject *type, PyObject *name,
+ update_callback callback, void *data);
+static int recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+ update_callback callback, void *data);
+
+static int
+mro_subclasses(PyTypeObject *type, PyObject* temp)
+{
+ PyTypeObject *subclass;
+ PyObject *ref, *subclasses, *old_mro;
+ Py_ssize_t i, n;
+
+ subclasses = type->tp_subclasses;
+ if (subclasses == NULL)
+ return 0;
+ assert(PyList_Check(subclasses));
+ n = PyList_GET_SIZE(subclasses);
+ for (i = 0; i < n; i++) {
+ ref = PyList_GET_ITEM(subclasses, i);
+ assert(PyWeakref_CheckRef(ref));
+ subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+ assert(subclass != NULL);
+ if ((PyObject *)subclass == Py_None)
+ continue;
+ assert(PyType_Check(subclass));
+ old_mro = subclass->tp_mro;
+ if (mro_internal(subclass) < 0) {
+ subclass->tp_mro = old_mro;
+ return -1;
+ }
+ else {
+ PyObject* tuple;
+ tuple = PyTuple_Pack(2, subclass, old_mro);
+ Py_DECREF(old_mro);
+ if (!tuple)
+ return -1;
+ if (PyList_Append(temp, tuple) < 0)
+ return -1;
+ Py_DECREF(tuple);
+ }
+ if (mro_subclasses(subclass, temp) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+type_set_bases(PyTypeObject *type, PyObject *value, void *context)
+{
+ Py_ssize_t i;
+ int r = 0;
+ PyObject *ob, *temp;
+ PyTypeObject *new_base, *old_base;
+ PyObject *old_bases, *old_mro;
+
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ PyErr_Format(PyExc_TypeError,
+ "can't set %s.__bases__", type->tp_name);
+ return -1;
+ }
+ if (!value) {
+ PyErr_Format(PyExc_TypeError,
+ "can't delete %s.__bases__", type->tp_name);
+ return -1;
+ }
+ if (!PyTuple_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "can only assign tuple to %s.__bases__, not %s",
+ type->tp_name, Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ if (PyTuple_GET_SIZE(value) == 0) {
+ PyErr_Format(PyExc_TypeError,
+ "can only assign non-empty tuple to %s.__bases__, not ()",
+ type->tp_name);
+ return -1;
+ }
+ for (i = 0; i < PyTuple_GET_SIZE(value); i++) {
+ ob = PyTuple_GET_ITEM(value, i);
+ if (!PyClass_Check(ob) && !PyType_Check(ob)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
+ type->tp_name, Py_TYPE(ob)->tp_name);
+ return -1;
+ }
+ if (PyType_Check(ob)) {
+ if (PyType_IsSubtype((PyTypeObject*)ob, type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "a __bases__ item causes an inheritance cycle");
+ return -1;
+ }
+ }
+ }
+
+ new_base = best_base(value);
+
+ if (!new_base) {
+ return -1;
+ }
+
+ if (!compatible_for_assignment(type->tp_base, new_base, "__bases__"))
+ return -1;
+
+ Py_INCREF(new_base);
+ Py_INCREF(value);
+
+ old_bases = type->tp_bases;
+ old_base = type->tp_base;
+ old_mro = type->tp_mro;
+
+ type->tp_bases = value;
+ type->tp_base = new_base;
+
+ if (mro_internal(type) < 0) {
+ goto bail;
+ }
+
+ temp = PyList_New(0);
+ if (!temp)
+ goto bail;
+
+ r = mro_subclasses(type, temp);
+
+ if (r < 0) {
+ for (i = 0; i < PyList_Size(temp); i++) {
+ PyTypeObject* cls;
+ PyObject* mro;
+ PyArg_UnpackTuple(PyList_GET_ITEM(temp, i),
+ "", 2, 2, &cls, &mro);
+ Py_INCREF(mro);
+ ob = cls->tp_mro;
+ cls->tp_mro = mro;
+ Py_DECREF(ob);
+ }
+ Py_DECREF(temp);
+ goto bail;
+ }
+
+ Py_DECREF(temp);
+
+ /* any base that was in __bases__ but now isn't, we
+ need to remove |type| from its tp_subclasses.
+ conversely, any class now in __bases__ that wasn't
+ needs to have |type| added to its subclasses. */
+
+ /* for now, sod that: just remove from all old_bases,
+ add to all new_bases */
+
+ for (i = PyTuple_GET_SIZE(old_bases) - 1; i >= 0; i--) {
+ ob = PyTuple_GET_ITEM(old_bases, i);
+ if (PyType_Check(ob)) {
+ remove_subclass(
+ (PyTypeObject*)ob, type);
+ }
+ }
+
+ for (i = PyTuple_GET_SIZE(value) - 1; i >= 0; i--) {
+ ob = PyTuple_GET_ITEM(value, i);
+ if (PyType_Check(ob)) {
+ if (add_subclass((PyTypeObject*)ob, type) < 0)
+ r = -1;
+ }
+ }
+
+ update_all_slots(type);
+
+ Py_DECREF(old_bases);
+ Py_DECREF(old_base);
+ Py_DECREF(old_mro);
+
+ return r;
+
+ bail:
+ Py_DECREF(type->tp_bases);
+ Py_DECREF(type->tp_base);
+ if (type->tp_mro != old_mro) {
+ Py_DECREF(type->tp_mro);
+ }
+
+ type->tp_bases = old_bases;
+ type->tp_base = old_base;
+ type->tp_mro = old_mro;
+
+ return -1;
+}
+
+static PyObject *
+type_dict(PyTypeObject *type, void *context)
+{
+ if (type->tp_dict == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return PyDictProxy_New(type->tp_dict);
+}
+
+static PyObject *
+type_get_doc(PyTypeObject *type, void *context)
+{
+ PyObject *result;
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL)
+ return PyString_FromString(type->tp_doc);
+ result = PyDict_GetItemString(type->tp_dict, "__doc__");
+ if (result == NULL) {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else if (Py_TYPE(result)->tp_descr_get) {
+ result = Py_TYPE(result)->tp_descr_get(result, NULL,
+ (PyObject *)type);
+ }
+ else {
+ Py_INCREF(result);
+ }
+ return result;
+}
+
+static PyObject *
+type___instancecheck__(PyObject *type, PyObject *inst)
+{
+ switch (_PyObject_RealIsInstance(inst, type)) {
+ case -1:
+ return NULL;
+ case 0:
+ Py_RETURN_FALSE;
+ default:
+ Py_RETURN_TRUE;
+ }
+}
+
+
+static PyObject *
+type___subclasscheck__(PyObject *type, PyObject *inst)
+{
+ switch (_PyObject_RealIsSubclass(inst, type)) {
+ case -1:
+ return NULL;
+ case 0:
+ Py_RETURN_FALSE;
+ default:
+ Py_RETURN_TRUE;
+ }
+}
+
+
+static PyGetSetDef type_getsets[] = {
+ {"__name__", (getter)type_name, (setter)type_set_name, NULL},
+ {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
+ {"__module__", (getter)type_module, (setter)type_set_module, NULL},
+ {"__abstractmethods__", (getter)type_abstractmethods,
+ (setter)type_set_abstractmethods, NULL},
+ {"__dict__", (getter)type_dict, NULL, NULL},
+ {"__doc__", (getter)type_get_doc, NULL, NULL},
+ {0}
+};
+
+
+static PyObject*
+type_richcompare(PyObject *v, PyObject *w, int op)
+{
+ PyObject *result;
+ Py_uintptr_t vv, ww;
+ int c;
+
+ /* Make sure both arguments are types. */
+ if (!PyType_Check(v) || !PyType_Check(w) ||
+ /* If there is a __cmp__ method defined, let it be called instead
+ of our dumb function designed merely to warn. See bug
+ #7491. */
+ Py_TYPE(v)->tp_compare || Py_TYPE(w)->tp_compare) {
+ result = Py_NotImplemented;
+ goto out;
+ }
+
+ /* Py3K warning if comparison isn't == or != */
+ if (Py_Py3kWarningFlag && op != Py_EQ && op != Py_NE &&
+ PyErr_WarnEx(PyExc_DeprecationWarning,
+ "type inequality comparisons not supported "
+ "in 3.x", 1) < 0) {
+ return NULL;
+ }
+
+ /* Compare addresses */
+ vv = (Py_uintptr_t)v;
+ ww = (Py_uintptr_t)w;
+ switch (op) {
+ case Py_LT: c = vv < ww; break;
+ case Py_LE: c = vv <= ww; break;
+ case Py_EQ: c = vv == ww; break;
+ case Py_NE: c = vv != ww; break;
+ case Py_GT: c = vv > ww; break;
+ case Py_GE: c = vv >= ww; break;
+ default:
+ result = Py_NotImplemented;
+ goto out;
+ }
+ result = c ? Py_True : Py_False;
+
+ /* incref and return */
+ out:
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+type_repr(PyTypeObject *type)
+{
+ PyObject *mod, *name, *rtn;
+ char *kind;
+
+ mod = type_module(type, NULL);
+ if (mod == NULL)
+ PyErr_Clear();
+ else if (!PyString_Check(mod)) {
+ Py_DECREF(mod);
+ mod = NULL;
+ }
+ name = type_name(type, NULL);
+ if (name == NULL) {
+ Py_XDECREF(mod);
+ return NULL;
+ }
+
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ kind = "class";
+ else
+ kind = "type";
+
+ if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) {
+ rtn = PyString_FromFormat("<%s '%s.%s'>",
+ kind,
+ PyString_AS_STRING(mod),
+ PyString_AS_STRING(name));
+ }
+ else
+ rtn = PyString_FromFormat("<%s '%s'>", kind, type->tp_name);
+
+ Py_XDECREF(mod);
+ Py_DECREF(name);
+ return rtn;
+}
+
+static PyObject *
+type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *obj;
+
+ if (type->tp_new == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%.100s' instances",
+ type->tp_name);
+ return NULL;
+ }
+
+ obj = type->tp_new(type, args, kwds);
+ if (obj != NULL) {
+ /* Ugly exception: when the call was type(something),
+ don't call tp_init on the result. */
+ if (type == &PyType_Type &&
+ PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+ (kwds == NULL ||
+ (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+ return obj;
+ /* If the returned object is not an instance of type,
+ it won't be initialized. */
+ if (!PyType_IsSubtype(obj->ob_type, type))
+ return obj;
+ type = obj->ob_type;
+ if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) &&
+ type->tp_init != NULL &&
+ type->tp_init(obj, args, kwds) < 0) {
+ Py_DECREF(obj);
+ obj = NULL;
+ }
+ }
+ return obj;
+}
+
+PyObject *
+PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
+{
+ PyObject *obj;
+ const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
+ /* note that we need to add one, for the sentinel */
+
+ if (PyType_IS_GC(type))
+ obj = _PyObject_GC_Malloc(size);
+ else
+ obj = (PyObject *)PyObject_MALLOC(size);
+
+ if (obj == NULL)
+ return PyErr_NoMemory();
+
+ memset(obj, '\0', size);
+
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ Py_INCREF(type);
+
+ if (type->tp_itemsize == 0)
+ PyObject_INIT(obj, type);
+ else
+ (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
+
+ if (PyType_IS_GC(type))
+ _PyObject_GC_TRACK(obj);
+ return obj;
+}
+
+PyObject *
+PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ return type->tp_alloc(type, 0);
+}
+
+/* Helpers for subtyping */
+
+static int
+traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg)
+{
+ Py_ssize_t i, n;
+ PyMemberDef *mp;
+
+ n = Py_SIZE(type);
+ mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+ for (i = 0; i < n; i++, mp++) {
+ if (mp->type == T_OBJECT_EX) {
+ char *addr = (char *)self + mp->offset;
+ PyObject *obj = *(PyObject **)addr;
+ if (obj != NULL) {
+ int err = visit(obj, arg);
+ if (err)
+ return err;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+subtype_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ PyTypeObject *type, *base;
+ traverseproc basetraverse;
+
+ /* Find the nearest base with a different tp_traverse,
+ and traverse slots while we're at it */
+ type = Py_TYPE(self);
+ base = type;
+ while ((basetraverse = base->tp_traverse) == subtype_traverse) {
+ if (Py_SIZE(base)) {
+ int err = traverse_slots(base, self, visit, arg);
+ if (err)
+ return err;
+ }
+ base = base->tp_base;
+ assert(base);
+ }
+
+ if (type->tp_dictoffset != base->tp_dictoffset) {
+ PyObject **dictptr = _PyObject_GetDictPtr(self);
+ if (dictptr && *dictptr)
+ Py_VISIT(*dictptr);
+ }
+
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ /* For a heaptype, the instances count as references
+ to the type. Traverse the type so the collector
+ can find cycles involving this link. */
+ Py_VISIT(type);
+
+ if (basetraverse)
+ return basetraverse(self, visit, arg);
+ return 0;
+}
+
+static void
+clear_slots(PyTypeObject *type, PyObject *self)
+{
+ Py_ssize_t i, n;
+ PyMemberDef *mp;
+
+ n = Py_SIZE(type);
+ mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type);
+ for (i = 0; i < n; i++, mp++) {
+ if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) {
+ char *addr = (char *)self + mp->offset;
+ PyObject *obj = *(PyObject **)addr;
+ if (obj != NULL) {
+ *(PyObject **)addr = NULL;
+ Py_DECREF(obj);
+ }
+ }
+ }
+}
+
+static int
+subtype_clear(PyObject *self)
+{
+ PyTypeObject *type, *base;
+ inquiry baseclear;
+
+ /* Find the nearest base with a different tp_clear
+ and clear slots while we're at it */
+ type = Py_TYPE(self);
+ base = type;
+ while ((baseclear = base->tp_clear) == subtype_clear) {
+ if (Py_SIZE(base))
+ clear_slots(base, self);
+ base = base->tp_base;
+ assert(base);
+ }
+
+ /* Clear the instance dict (if any), to break cycles involving only
+ __dict__ slots (as in the case 'self.__dict__ is self'). */
+ if (type->tp_dictoffset != base->tp_dictoffset) {
+ PyObject **dictptr = _PyObject_GetDictPtr(self);
+ if (dictptr && *dictptr)
+ Py_CLEAR(*dictptr);
+ }
+
+ if (baseclear)
+ return baseclear(self);
+ return 0;
+}
+
+static void
+subtype_dealloc(PyObject *self)
+{
+ PyTypeObject *type, *base;
+ destructor basedealloc;
+ PyThreadState *tstate = PyThreadState_GET();
+
+ /* Extract the type; we expect it to be a heap type */
+ type = Py_TYPE(self);
+ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+ /* Test whether the type has GC exactly once */
+
+ if (!PyType_IS_GC(type)) {
+ /* It's really rare to find a dynamic type that doesn't have
+ GC; it can only happen when deriving from 'object' and not
+ adding any slots or instance variables. This allows
+ certain simplifications: there's no need to call
+ clear_slots(), or DECREF the dict, or clear weakrefs. */
+
+ /* Maybe call finalizer; exit early if resurrected */
+ if (type->tp_del) {
+ type->tp_del(self);
+ if (self->ob_refcnt > 0)
+ return;
+ }
+
+ /* Find the nearest base with a different tp_dealloc */
+ base = type;
+ while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+ assert(Py_SIZE(base) == 0);
+ base = base->tp_base;
+ assert(base);
+ }
+
+ /* Extract the type again; tp_del may have changed it */
+ type = Py_TYPE(self);
+
+ /* Call the base tp_dealloc() */
+ assert(basedealloc);
+ basedealloc(self);
+
+ /* Can't reference self beyond this point */
+ Py_DECREF(type);
+
+ /* Done */
+ return;
+ }
+
+ /* We get here only if the type has GC */
+
+ /* UnTrack and re-Track around the trashcan macro, alas */
+ /* See explanation at end of function for full disclosure */
+ PyObject_GC_UnTrack(self);
+ ++_PyTrash_delete_nesting;
+ ++ tstate->trash_delete_nesting;
+ Py_TRASHCAN_SAFE_BEGIN(self);
+ --_PyTrash_delete_nesting;
+ -- tstate->trash_delete_nesting;
+ /* DO NOT restore GC tracking at this point. weakref callbacks
+ * (if any, and whether directly here or indirectly in something we
+ * call) may trigger GC, and if self is tracked at that point, it
+ * will look like trash to GC and GC will try to delete self again.
+ */
+
+ /* Find the nearest base with a different tp_dealloc */
+ base = type;
+ while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+ base = base->tp_base;
+ assert(base);
+ }
+
+ /* If we added a weaklist, we clear it. Do this *before* calling
+ the finalizer (__del__), clearing slots, or clearing the instance
+ dict. */
+
+ if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
+ PyObject_ClearWeakRefs(self);
+
+ /* Maybe call finalizer; exit early if resurrected */
+ if (type->tp_del) {
+ _PyObject_GC_TRACK(self);
+ type->tp_del(self);
+ if (self->ob_refcnt > 0)
+ goto endlabel; /* resurrected */
+ else
+ _PyObject_GC_UNTRACK(self);
+ /* New weakrefs could be created during the finalizer call.
+ If this occurs, clear them out without calling their
+ finalizers since they might rely on part of the object
+ being finalized that has already been destroyed. */
+ if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
+ /* Modeled after GET_WEAKREFS_LISTPTR() */
+ PyWeakReference **list = (PyWeakReference **) \
+ PyObject_GET_WEAKREFS_LISTPTR(self);
+ while (*list)
+ _PyWeakref_ClearRef(*list);
+ }
+ }
+
+ /* Clear slots up to the nearest base with a different tp_dealloc */
+ base = type;
+ while (base->tp_dealloc == subtype_dealloc) {
+ if (Py_SIZE(base))
+ clear_slots(base, self);
+ base = base->tp_base;
+ assert(base);
+ }
+
+ /* If we added a dict, DECREF it */
+ if (type->tp_dictoffset && !base->tp_dictoffset) {
+ PyObject **dictptr = _PyObject_GetDictPtr(self);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ if (dict != NULL) {
+ Py_DECREF(dict);
+ *dictptr = NULL;
+ }
+ }
+ }
+
+ /* Extract the type again; tp_del may have changed it */
+ type = Py_TYPE(self);
+
+ /* Call the base tp_dealloc(); first retrack self if
+ * basedealloc knows about gc.
+ */
+ if (PyType_IS_GC(base))
+ _PyObject_GC_TRACK(self);
+ assert(basedealloc);
+ basedealloc(self);
+
+ /* Can't reference self beyond this point */
+ Py_DECREF(type);
+
+ endlabel:
+ ++_PyTrash_delete_nesting;
+ ++ tstate->trash_delete_nesting;
+ Py_TRASHCAN_SAFE_END(self);
+ --_PyTrash_delete_nesting;
+ -- tstate->trash_delete_nesting;
+
+ /* Explanation of the weirdness around the trashcan macros:
+
+ Q. What do the trashcan macros do?
+
+ A. Read the comment titled "Trashcan mechanism" in object.h.
+ For one, this explains why there must be a call to GC-untrack
+ before the trashcan begin macro. Without understanding the
+ trashcan code, the answers to the following questions don't make
+ sense.
+
+ Q. Why do we GC-untrack before the trashcan and then immediately
+ GC-track again afterward?
+
+ A. In the case that the base class is GC-aware, the base class
+ probably GC-untracks the object. If it does that using the
+ UNTRACK macro, this will crash when the object is already
+ untracked. Because we don't know what the base class does, the
+ only safe thing is to make sure the object is tracked when we
+ call the base class dealloc. But... The trashcan begin macro
+ requires that the object is *untracked* before it is called. So
+ the dance becomes:
+
+ GC untrack
+ trashcan begin
+ GC track
+
+ Q. Why did the last question say "immediately GC-track again"?
+ It's nowhere near immediately.
+
+ A. Because the code *used* to re-track immediately. Bad Idea.
+ self has a refcount of 0, and if gc ever gets its hands on it
+ (which can happen if any weakref callback gets invoked), it
+ looks like trash to gc too, and gc also tries to delete self
+ then. But we're already deleting self. Double deallocation is
+ a subtle disaster.
+
+ Q. Why the bizarre (net-zero) manipulation of
+ _PyTrash_delete_nesting around the trashcan macros?
+
+ A. Some base classes (e.g. list) also use the trashcan mechanism.
+ The following scenario used to be possible:
+
+ - suppose the trashcan level is one below the trashcan limit
+
+ - subtype_dealloc() is called
+
+ - the trashcan limit is not yet reached, so the trashcan level
+ is incremented and the code between trashcan begin and end is
+ executed
+
+ - this destroys much of the object's contents, including its
+ slots and __dict__
+
+ - basedealloc() is called; this is really list_dealloc(), or
+ some other type which also uses the trashcan macros
+
+ - the trashcan limit is now reached, so the object is put on the
+ trashcan's to-be-deleted-later list
+
+ - basedealloc() returns
+
+ - subtype_dealloc() decrefs the object's type
+
+ - subtype_dealloc() returns
+
+ - later, the trashcan code starts deleting the objects from its
+ to-be-deleted-later list
+
+ - subtype_dealloc() is called *AGAIN* for the same object
+
+ - at the very least (if the destroyed slots and __dict__ don't
+ cause problems) the object's type gets decref'ed a second
+ time, which is *BAD*!!!
+
+ The remedy is to make sure that if the code between trashcan
+ begin and end in subtype_dealloc() is called, the code between
+ trashcan begin and end in basedealloc() will also be called.
+ This is done by decrementing the level after passing into the
+ trashcan block, and incrementing it just before leaving the
+ block.
+
+ But now it's possible that a chain of objects consisting solely
+ of objects whose deallocator is subtype_dealloc() will defeat
+ the trashcan mechanism completely: the decremented level means
+ that the effective level never reaches the limit. Therefore, we
+ *increment* the level *before* entering the trashcan block, and
+ matchingly decrement it after leaving. This means the trashcan
+ code will trigger a little early, but that's no big deal.
+
+ Q. Are there any live examples of code in need of all this
+ complexity?
+
+ A. Yes. See SF bug 668433 for code that crashed (when Python was
+ compiled in debug mode) before the trashcan level manipulations
+ were added. For more discussion, see SF patches 581742, 575073
+ and bug 574207.
+ */
+}
+
+static PyTypeObject *solid_base(PyTypeObject *type);
+
+/* type test with subclassing support */
+
+int
+PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
+{
+ PyObject *mro;
+
+ if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS))
+ return b == a || b == &PyBaseObject_Type;
+
+ mro = a->tp_mro;
+ if (mro != NULL) {
+ /* Deal with multiple inheritance without recursion
+ by walking the MRO tuple */
+ Py_ssize_t i, n;
+ assert(PyTuple_Check(mro));
+ n = PyTuple_GET_SIZE(mro);
+ for (i = 0; i < n; i++) {
+ if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
+ return 1;
+ }
+ return 0;
+ }
+ else {
+ /* a is not completely initilized yet; follow tp_base */
+ do {
+ if (a == b)
+ return 1;
+ a = a->tp_base;
+ } while (a != NULL);
+ return b == &PyBaseObject_Type;
+ }
+}
+
+/* Internal routines to do a method lookup in the type
+ without looking in the instance dictionary
+ (so we can't use PyObject_GetAttr) but still binding
+ it to the instance. The arguments are the object,
+ the method name as a C string, and the address of a
+ static variable used to cache the interned Python string.
+
+ Two variants:
+
+ - lookup_maybe() returns NULL without raising an exception
+ when the _PyType_Lookup() call fails;
+
+ - lookup_method() always raises an exception upon errors.
+
+ - _PyObject_LookupSpecial() exported for the benefit of other places.
+*/
+
+static PyObject *
+lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+ PyObject *res;
+
+ if (*attrobj == NULL) {
+ *attrobj = PyString_InternFromString(attrstr);
+ if (*attrobj == NULL)
+ return NULL;
+ }
+ res = _PyType_Lookup(Py_TYPE(self), *attrobj);
+ if (res != NULL) {
+ descrgetfunc f;
+ if ((f = Py_TYPE(res)->tp_descr_get) == NULL)
+ Py_INCREF(res);
+ else
+ res = f(res, self, (PyObject *)(Py_TYPE(self)));
+ }
+ return res;
+}
+
+static PyObject *
+lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+ PyObject *res = lookup_maybe(self, attrstr, attrobj);
+ if (res == NULL && !PyErr_Occurred())
+ PyErr_SetObject(PyExc_AttributeError, *attrobj);
+ return res;
+}
+
+PyObject *
+_PyObject_LookupSpecial(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+ assert(!PyInstance_Check(self));
+ return lookup_maybe(self, attrstr, attrobj);
+}
+
+/* A variation of PyObject_CallMethod that uses lookup_method()
+ instead of PyObject_GetAttrString(). This uses the same convention
+ as lookup_method to cache the interned name string object. */
+
+static PyObject *
+call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+ va_list va;
+ PyObject *args, *func = 0, *retval;
+ va_start(va, format);
+
+ func = lookup_maybe(o, name, nameobj);
+ if (func == NULL) {
+ va_end(va);
+ if (!PyErr_Occurred())
+ PyErr_SetObject(PyExc_AttributeError, *nameobj);
+ return NULL;
+ }
+
+ if (format && *format)
+ args = Py_VaBuildValue(format, va);
+ else
+ args = PyTuple_New(0);
+
+ va_end(va);
+
+ if (args == NULL)
+ return NULL;
+
+ assert(PyTuple_Check(args));
+ retval = PyObject_Call(func, args, NULL);
+
+ Py_DECREF(args);
+ Py_DECREF(func);
+
+ return retval;
+}
+
+/* Clone of call_method() that returns NotImplemented when the lookup fails. */
+
+static PyObject *
+call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
+{
+ va_list va;
+ PyObject *args, *func = 0, *retval;
+ va_start(va, format);
+
+ func = lookup_maybe(o, name, nameobj);
+ if (func == NULL) {
+ va_end(va);
+ if (!PyErr_Occurred()) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return NULL;
+ }
+
+ if (format && *format)
+ args = Py_VaBuildValue(format, va);
+ else
+ args = PyTuple_New(0);
+
+ va_end(va);
+
+ if (args == NULL)
+ return NULL;
+
+ assert(PyTuple_Check(args));
+ retval = PyObject_Call(func, args, NULL);
+
+ Py_DECREF(args);
+ Py_DECREF(func);
+
+ return retval;
+}
+
+static int
+fill_classic_mro(PyObject *mro, PyObject *cls)
+{
+ PyObject *bases, *base;
+ Py_ssize_t i, n;
+
+ assert(PyList_Check(mro));
+ assert(PyClass_Check(cls));
+ i = PySequence_Contains(mro, cls);
+ if (i < 0)
+ return -1;
+ if (!i) {
+ if (PyList_Append(mro, cls) < 0)
+ return -1;
+ }
+ bases = ((PyClassObject *)cls)->cl_bases;
+ assert(bases && PyTuple_Check(bases));
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 0; i < n; i++) {
+ base = PyTuple_GET_ITEM(bases, i);
+ if (fill_classic_mro(mro, base) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+classic_mro(PyObject *cls)
+{
+ PyObject *mro;
+
+ assert(PyClass_Check(cls));
+ mro = PyList_New(0);
+ if (mro != NULL) {
+ if (fill_classic_mro(mro, cls) == 0)
+ return mro;
+ Py_DECREF(mro);
+ }
+ return NULL;
+}
+
+/*
+ Method resolution order algorithm C3 described in
+ "A Monotonic Superclass Linearization for Dylan",
+ by Kim Barrett, Bob Cassel, Paul Haahr,
+ David A. Moon, Keith Playford, and P. Tucker Withington.
+ (OOPSLA 1996)
+
+ Some notes about the rules implied by C3:
+
+ No duplicate bases.
+ It isn't legal to repeat a class in a list of base classes.
+
+ The next three properties are the 3 constraints in "C3".
+
+ Local precendece order.
+ If A precedes B in C's MRO, then A will precede B in the MRO of all
+ subclasses of C.
+
+ Monotonicity.
+ The MRO of a class must be an extension without reordering of the
+ MRO of each of its superclasses.
+
+ Extended Precedence Graph (EPG).
+ Linearization is consistent if there is a path in the EPG from
+ each class to all its successors in the linearization. See
+ the paper for definition of EPG.
+ */
+
+static int
+tail_contains(PyObject *list, int whence, PyObject *o) {
+ Py_ssize_t j, size;
+ size = PyList_GET_SIZE(list);
+
+ for (j = whence+1; j < size; j++) {
+ if (PyList_GET_ITEM(list, j) == o)
+ return 1;
+ }
+ return 0;
+}
+
+static PyObject *
+class_name(PyObject *cls)
+{
+ PyObject *name = PyObject_GetAttrString(cls, "__name__");
+ if (name == NULL) {
+ PyErr_Clear();
+ Py_XDECREF(name);
+ name = PyObject_Repr(cls);
+ }
+ if (name == NULL)
+ return NULL;
+ if (!PyString_Check(name)) {
+ Py_DECREF(name);
+ return NULL;
+ }
+ return name;
+}
+
+static int
+check_duplicates(PyObject *list)
+{
+ Py_ssize_t i, j, n;
+ /* Let's use a quadratic time algorithm,
+ assuming that the bases lists is short.
+ */
+ n = PyList_GET_SIZE(list);
+ for (i = 0; i < n; i++) {
+ PyObject *o = PyList_GET_ITEM(list, i);
+ for (j = i + 1; j < n; j++) {
+ if (PyList_GET_ITEM(list, j) == o) {
+ o = class_name(o);
+ PyErr_Format(PyExc_TypeError,
+ "duplicate base class %s",
+ o ? PyString_AS_STRING(o) : "?");
+ Py_XDECREF(o);
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Raise a TypeError for an MRO order disagreement.
+
+ It's hard to produce a good error message. In the absence of better
+ insight into error reporting, report the classes that were candidates
+ to be put next into the MRO. There is some conflict between the
+ order in which they should be put in the MRO, but it's hard to
+ diagnose what constraint can't be satisfied.
+*/
+
+static void
+set_mro_error(PyObject *to_merge, int *remain)
+{
+ Py_ssize_t i, n, off, to_merge_size;
+ char buf[1000];
+ PyObject *k, *v;
+ PyObject *set = PyDict_New();
+ if (!set) return;
+
+ to_merge_size = PyList_GET_SIZE(to_merge);
+ for (i = 0; i < to_merge_size; i++) {
+ PyObject *L = PyList_GET_ITEM(to_merge, i);
+ if (remain[i] < PyList_GET_SIZE(L)) {
+ PyObject *c = PyList_GET_ITEM(L, remain[i]);
+ if (PyDict_SetItem(set, c, Py_None) < 0) {
+ Py_DECREF(set);
+ return;
+ }
+ }
+ }
+ n = PyDict_Size(set);
+
+ off = PyOS_snprintf(buf, sizeof(buf), "Cannot create a \
+consistent method resolution\norder (MRO) for bases");
+ i = 0;
+ while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) {
+ PyObject *name = class_name(k);
+ off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s",
+ name ? PyString_AS_STRING(name) : "?");
+ Py_XDECREF(name);
+ if (--n && (size_t)(off+1) < sizeof(buf)) {
+ buf[off++] = ',';
+ buf[off] = '\0';
+ }
+ }
+ PyErr_SetString(PyExc_TypeError, buf);
+ Py_DECREF(set);
+}
+
+static int
+pmerge(PyObject *acc, PyObject* to_merge) {
+ Py_ssize_t i, j, to_merge_size, empty_cnt;
+ int *remain;
+ int ok;
+
+ to_merge_size = PyList_GET_SIZE(to_merge);
+
+ /* remain stores an index into each sublist of to_merge.
+ remain[i] is the index of the next base in to_merge[i]
+ that is not included in acc.
+ */
+ remain = (int *)PyMem_MALLOC(SIZEOF_INT*to_merge_size);
+ if (remain == NULL)
+ return -1;
+ for (i = 0; i < to_merge_size; i++)
+ remain[i] = 0;
+
+ again:
+ empty_cnt = 0;
+ for (i = 0; i < to_merge_size; i++) {
+ PyObject *candidate;
+
+ PyObject *cur_list = PyList_GET_ITEM(to_merge, i);
+
+ if (remain[i] >= PyList_GET_SIZE(cur_list)) {
+ empty_cnt++;
+ continue;
+ }
+
+ /* Choose next candidate for MRO.
+
+ The input sequences alone can determine the choice.
+ If not, choose the class which appears in the MRO
+ of the earliest direct superclass of the new class.
+ */
+
+ candidate = PyList_GET_ITEM(cur_list, remain[i]);
+ for (j = 0; j < to_merge_size; j++) {
+ PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+ if (tail_contains(j_lst, remain[j], candidate)) {
+ goto skip; /* continue outer loop */
+ }
+ }
+ ok = PyList_Append(acc, candidate);
+ if (ok < 0) {
+ PyMem_Free(remain);
+ return -1;
+ }
+ for (j = 0; j < to_merge_size; j++) {
+ PyObject *j_lst = PyList_GET_ITEM(to_merge, j);
+ if (remain[j] < PyList_GET_SIZE(j_lst) &&
+ PyList_GET_ITEM(j_lst, remain[j]) == candidate) {
+ remain[j]++;
+ }
+ }
+ goto again;
+ skip: ;
+ }
+
+ if (empty_cnt == to_merge_size) {
+ PyMem_FREE(remain);
+ return 0;
+ }
+ set_mro_error(to_merge, remain);
+ PyMem_FREE(remain);
+ return -1;
+}
+
+static PyObject *
+mro_implementation(PyTypeObject *type)
+{
+ Py_ssize_t i, n;
+ int ok;
+ PyObject *bases, *result;
+ PyObject *to_merge, *bases_aslist;
+
+ if (type->tp_dict == NULL) {
+ if (PyType_Ready(type) < 0)
+ return NULL;
+ }
+
+ /* Find a superclass linearization that honors the constraints
+ of the explicit lists of bases and the constraints implied by
+ each base class.
+
+ to_merge is a list of lists, where each list is a superclass
+ linearization implied by a base class. The last element of
+ to_merge is the declared list of bases.
+ */
+
+ bases = type->tp_bases;
+ n = PyTuple_GET_SIZE(bases);
+
+ to_merge = PyList_New(n+1);
+ if (to_merge == NULL)
+ return NULL;
+
+ for (i = 0; i < n; i++) {
+ PyObject *base = PyTuple_GET_ITEM(bases, i);
+ PyObject *parentMRO;
+ if (PyType_Check(base))
+ parentMRO = PySequence_List(
+ ((PyTypeObject*)base)->tp_mro);
+ else
+ parentMRO = classic_mro(base);
+ if (parentMRO == NULL) {
+ Py_DECREF(to_merge);
+ return NULL;
+ }
+
+ PyList_SET_ITEM(to_merge, i, parentMRO);
+ }
+
+ bases_aslist = PySequence_List(bases);
+ if (bases_aslist == NULL) {
+ Py_DECREF(to_merge);
+ return NULL;
+ }
+ /* This is just a basic sanity check. */
+ if (check_duplicates(bases_aslist) < 0) {
+ Py_DECREF(to_merge);
+ Py_DECREF(bases_aslist);
+ return NULL;
+ }
+ PyList_SET_ITEM(to_merge, n, bases_aslist);
+
+ result = Py_BuildValue("[O]", (PyObject *)type);
+ if (result == NULL) {
+ Py_DECREF(to_merge);
+ return NULL;
+ }
+
+ ok = pmerge(result, to_merge);
+ Py_DECREF(to_merge);
+ if (ok < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+static PyObject *
+mro_external(PyObject *self)
+{
+ PyTypeObject *type = (PyTypeObject *)self;
+
+ return mro_implementation(type);
+}
+
+static int
+mro_internal(PyTypeObject *type)
+{
+ PyObject *mro, *result, *tuple;
+ int checkit = 0;
+
+ if (Py_TYPE(type) == &PyType_Type) {
+ result = mro_implementation(type);
+ }
+ else {
+ static PyObject *mro_str;
+ checkit = 1;
+ mro = lookup_method((PyObject *)type, "mro", &mro_str);
+ if (mro == NULL)
+ return -1;
+ result = PyObject_CallObject(mro, NULL);
+ Py_DECREF(mro);
+ }
+ if (result == NULL)
+ return -1;
+ tuple = PySequence_Tuple(result);
+ Py_DECREF(result);
+ if (tuple == NULL)
+ return -1;
+ if (checkit) {
+ Py_ssize_t i, len;
+ PyObject *cls;
+ PyTypeObject *solid;
+
+ solid = solid_base(type);
+
+ len = PyTuple_GET_SIZE(tuple);
+
+ for (i = 0; i < len; i++) {
+ PyTypeObject *t;
+ cls = PyTuple_GET_ITEM(tuple, i);
+ if (PyClass_Check(cls))
+ continue;
+ else if (!PyType_Check(cls)) {
+ PyErr_Format(PyExc_TypeError,
+ "mro() returned a non-class ('%.500s')",
+ Py_TYPE(cls)->tp_name);
+ Py_DECREF(tuple);
+ return -1;
+ }
+ t = (PyTypeObject*)cls;
+ if (!PyType_IsSubtype(solid, solid_base(t))) {
+ PyErr_Format(PyExc_TypeError,
+ "mro() returned base with unsuitable layout ('%.500s')",
+ t->tp_name);
+ Py_DECREF(tuple);
+ return -1;
+ }
+ }
+ }
+ type->tp_mro = tuple;
+
+ type_mro_modified(type, type->tp_mro);
+ /* corner case: the old-style super class might have been hidden
+ from the custom MRO */
+ type_mro_modified(type, type->tp_bases);
+
+ PyType_Modified(type);
+
+ return 0;
+}
+
+
+/* Calculate the best base amongst multiple base classes.
+ This is the first one that's on the path to the "solid base". */
+
+static PyTypeObject *
+best_base(PyObject *bases)
+{
+ Py_ssize_t i, n;
+ PyTypeObject *base, *winner, *candidate, *base_i;
+ PyObject *base_proto;
+
+ assert(PyTuple_Check(bases));
+ n = PyTuple_GET_SIZE(bases);
+ assert(n > 0);
+ base = NULL;
+ winner = NULL;
+ for (i = 0; i < n; i++) {
+ base_proto = PyTuple_GET_ITEM(bases, i);
+ if (PyClass_Check(base_proto))
+ continue;
+ if (!PyType_Check(base_proto)) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "bases must be types");
+ return NULL;
+ }
+ base_i = (PyTypeObject *)base_proto;
+ if (base_i->tp_dict == NULL) {
+ if (PyType_Ready(base_i) < 0)
+ return NULL;
+ }
+ candidate = solid_base(base_i);
+ if (winner == NULL) {
+ winner = candidate;
+ base = base_i;
+ }
+ else if (PyType_IsSubtype(winner, candidate))
+ ;
+ else if (PyType_IsSubtype(candidate, winner)) {
+ winner = candidate;
+ base = base_i;
+ }
+ else {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "multiple bases have "
+ "instance lay-out conflict");
+ return NULL;
+ }
+ }
+ if (base == NULL)
+ PyErr_SetString(PyExc_TypeError,
+ "a new-style class can't have only classic bases");
+ return base;
+}
+
+static int
+extra_ivars(PyTypeObject *type, PyTypeObject *base)
+{
+ size_t t_size = type->tp_basicsize;
+ size_t b_size = base->tp_basicsize;
+
+ assert(t_size >= b_size); /* Else type smaller than base! */
+ if (type->tp_itemsize || base->tp_itemsize) {
+ /* If itemsize is involved, stricter rules */
+ return t_size != b_size ||
+ type->tp_itemsize != base->tp_itemsize;
+ }
+ if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 &&
+ type->tp_weaklistoffset + sizeof(PyObject *) == t_size &&
+ type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ t_size -= sizeof(PyObject *);
+ if (type->tp_dictoffset && base->tp_dictoffset == 0 &&
+ type->tp_dictoffset + sizeof(PyObject *) == t_size &&
+ type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ t_size -= sizeof(PyObject *);
+
+ return t_size != b_size;
+}
+
+static PyTypeObject *
+solid_base(PyTypeObject *type)
+{
+ PyTypeObject *base;
+
+ if (type->tp_base)
+ base = solid_base(type->tp_base);
+ else
+ base = &PyBaseObject_Type;
+ if (extra_ivars(type, base))
+ return type;
+ else
+ return base;
+}
+
+static void object_dealloc(PyObject *);
+static int object_init(PyObject *, PyObject *, PyObject *);
+static int update_slot(PyTypeObject *, PyObject *);
+static void fixup_slot_dispatchers(PyTypeObject *);
+
+/*
+ * Helpers for __dict__ descriptor. We don't want to expose the dicts
+ * inherited from various builtin types. The builtin base usually provides
+ * its own __dict__ descriptor, so we use that when we can.
+ */
+static PyTypeObject *
+get_builtin_base_with_dict(PyTypeObject *type)
+{
+ while (type->tp_base != NULL) {
+ if (type->tp_dictoffset != 0 &&
+ !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ return type;
+ type = type->tp_base;
+ }
+ return NULL;
+}
+
+static PyObject *
+get_dict_descriptor(PyTypeObject *type)
+{
+ static PyObject *dict_str;
+ PyObject *descr;
+
+ if (dict_str == NULL) {
+ dict_str = PyString_InternFromString("__dict__");
+ if (dict_str == NULL)
+ return NULL;
+ }
+ descr = _PyType_Lookup(type, dict_str);
+ if (descr == NULL || !PyDescr_IsData(descr))
+ return NULL;
+
+ return descr;
+}
+
+static void
+raise_dict_descr_error(PyObject *obj)
+{
+ PyErr_Format(PyExc_TypeError,
+ "this __dict__ descriptor does not support "
+ "'%.200s' objects", obj->ob_type->tp_name);
+}
+
+static PyObject *
+subtype_dict(PyObject *obj, void *context)
+{
+ PyObject **dictptr;
+ PyObject *dict;
+ PyTypeObject *base;
+
+ base = get_builtin_base_with_dict(obj->ob_type);
+ if (base != NULL) {
+ descrgetfunc func;
+ PyObject *descr = get_dict_descriptor(base);
+ if (descr == NULL) {
+ raise_dict_descr_error(obj);
+ return NULL;
+ }
+ func = descr->ob_type->tp_descr_get;
+ if (func == NULL) {
+ raise_dict_descr_error(obj);
+ return NULL;
+ }
+ return func(descr, obj, (PyObject *)(obj->ob_type));
+ }
+
+ dictptr = _PyObject_GetDictPtr(obj);
+ if (dictptr == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "This object has no __dict__");
+ return NULL;
+ }
+ dict = *dictptr;
+ if (dict == NULL)
+ *dictptr = dict = PyDict_New();
+ Py_XINCREF(dict);
+ return dict;
+}
+
+static int
+subtype_setdict(PyObject *obj, PyObject *value, void *context)
+{
+ PyObject **dictptr;
+ PyObject *dict;
+ PyTypeObject *base;
+
+ base = get_builtin_base_with_dict(obj->ob_type);
+ if (base != NULL) {
+ descrsetfunc func;
+ PyObject *descr = get_dict_descriptor(base);
+ if (descr == NULL) {
+ raise_dict_descr_error(obj);
+ return -1;
+ }
+ func = descr->ob_type->tp_descr_set;
+ if (func == NULL) {
+ raise_dict_descr_error(obj);
+ return -1;
+ }
+ return func(descr, obj, value);
+ }
+
+ dictptr = _PyObject_GetDictPtr(obj);
+ if (dictptr == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "This object has no __dict__");
+ return -1;
+ }
+ if (value != NULL && !PyDict_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "__dict__ must be set to a dictionary, "
+ "not a '%.200s'", Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ dict = *dictptr;
+ Py_XINCREF(value);
+ *dictptr = value;
+ Py_XDECREF(dict);
+ return 0;
+}
+
+static PyObject *
+subtype_getweakref(PyObject *obj, void *context)
+{
+ PyObject **weaklistptr;
+ PyObject *result;
+
+ if (Py_TYPE(obj)->tp_weaklistoffset == 0) {
+ PyErr_SetString(PyExc_AttributeError,
+ "This object has no __weakref__");
+ return NULL;
+ }
+ assert(Py_TYPE(obj)->tp_weaklistoffset > 0);
+ assert(Py_TYPE(obj)->tp_weaklistoffset + sizeof(PyObject *) <=
+ (size_t)(Py_TYPE(obj)->tp_basicsize));
+ weaklistptr = (PyObject **)
+ ((char *)obj + Py_TYPE(obj)->tp_weaklistoffset);
+ if (*weaklistptr == NULL)
+ result = Py_None;
+ else
+ result = *weaklistptr;
+ Py_INCREF(result);
+ return result;
+}
+
+/* Three variants on the subtype_getsets list. */
+
+static PyGetSetDef subtype_getsets_full[] = {
+ {"__dict__", subtype_dict, subtype_setdict,
+ PyDoc_STR("dictionary for instance variables (if defined)")},
+ {"__weakref__", subtype_getweakref, NULL,
+ PyDoc_STR("list of weak references to the object (if defined)")},
+ {0}
+};
+
+static PyGetSetDef subtype_getsets_dict_only[] = {
+ {"__dict__", subtype_dict, subtype_setdict,
+ PyDoc_STR("dictionary for instance variables (if defined)")},
+ {0}
+};
+
+static PyGetSetDef subtype_getsets_weakref_only[] = {
+ {"__weakref__", subtype_getweakref, NULL,
+ PyDoc_STR("list of weak references to the object (if defined)")},
+ {0}
+};
+
+static int
+valid_identifier(PyObject *s)
+{
+ unsigned char *p;
+ Py_ssize_t i, n;
+
+ if (!PyString_Check(s)) {
+ PyErr_Format(PyExc_TypeError,
+ "__slots__ items must be strings, not '%.200s'",
+ Py_TYPE(s)->tp_name);
+ return 0;
+ }
+ p = (unsigned char *) PyString_AS_STRING(s);
+ n = PyString_GET_SIZE(s);
+ /* We must reject an empty name. As a hack, we bump the
+ length to 1 so that the loop will balk on the trailing \0. */
+ if (n == 0)
+ n = 1;
+ for (i = 0; i < n; i++, p++) {
+ if (!(i == 0 ? isalpha(*p) : isalnum(*p)) && *p != '_') {
+ PyErr_SetString(PyExc_TypeError,
+ "__slots__ must be identifiers");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#ifdef Py_USING_UNICODE
+/* Replace Unicode objects in slots. */
+
+static PyObject *
+_unicode_to_string(PyObject *slots, Py_ssize_t nslots)
+{
+ PyObject *tmp = NULL;
+ PyObject *slot_name, *new_name;
+ Py_ssize_t i;
+
+ for (i = 0; i < nslots; i++) {
+ if (PyUnicode_Check(slot_name = PyTuple_GET_ITEM(slots, i))) {
+ if (tmp == NULL) {
+ tmp = PySequence_List(slots);
+ if (tmp == NULL)
+ return NULL;
+ }
+ new_name = _PyUnicode_AsDefaultEncodedString(slot_name,
+ NULL);
+ if (new_name == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ Py_INCREF(new_name);
+ PyList_SET_ITEM(tmp, i, new_name);
+ Py_DECREF(slot_name);
+ }
+ }
+ if (tmp != NULL) {
+ slots = PyList_AsTuple(tmp);
+ Py_DECREF(tmp);
+ }
+ return slots;
+}
+#endif
+
+/* Forward */
+static int
+object_init(PyObject *self, PyObject *args, PyObject *kwds);
+
+static int
+type_init(PyObject *cls, PyObject *args, PyObject *kwds)
+{
+ int res;
+
+ assert(args != NULL && PyTuple_Check(args));
+ assert(kwds == NULL || PyDict_Check(kwds));
+
+ if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds) != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "type.__init__() takes no keyword arguments");
+ return -1;
+ }
+
+ if (args != NULL && PyTuple_Check(args) &&
+ (PyTuple_GET_SIZE(args) != 1 && PyTuple_GET_SIZE(args) != 3)) {
+ PyErr_SetString(PyExc_TypeError,
+ "type.__init__() takes 1 or 3 arguments");
+ return -1;
+ }
+
+ /* Call object.__init__(self) now. */
+ /* XXX Could call super(type, cls).__init__() but what's the point? */
+ args = PyTuple_GetSlice(args, 0, 0);
+ res = object_init(cls, args, NULL);
+ Py_DECREF(args);
+ return res;
+}
+
+static PyObject *
+type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
+{
+ PyObject *name, *bases, *dict;
+ static char *kwlist[] = {"name", "bases", "dict", 0};
+ PyObject *slots, *tmp, *newslots;
+ PyTypeObject *type, *base, *tmptype, *winner;
+ PyHeapTypeObject *et;
+ PyMemberDef *mp;
+ Py_ssize_t i, nbases, nslots, slotoffset, add_dict, add_weak;
+ int j, may_add_dict, may_add_weak;
+
+ assert(args != NULL && PyTuple_Check(args));
+ assert(kwds == NULL || PyDict_Check(kwds));
+
+ /* Special case: type(x) should return x->ob_type */
+ {
+ const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+ const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds);
+
+ if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
+ PyObject *x = PyTuple_GET_ITEM(args, 0);
+ Py_INCREF(Py_TYPE(x));
+ return (PyObject *) Py_TYPE(x);
+ }
+
+ /* SF bug 475327 -- if that didn't trigger, we need 3
+ arguments. but PyArg_ParseTupleAndKeywords below may give
+ a msg saying type() needs exactly 3. */
+ if (nargs + nkwds != 3) {
+ PyErr_SetString(PyExc_TypeError,
+ "type() takes 1 or 3 arguments");
+ return NULL;
+ }
+ }
+
+ /* Check arguments: (name, bases, dict) */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "SO!O!:type", kwlist,
+ &name,
+ &PyTuple_Type, &bases,
+ &PyDict_Type, &dict))
+ return NULL;
+
+ /* Determine the proper metatype to deal with this,
+ and check for metatype conflicts while we're at it.
+ Note that if some other metatype wins to contract,
+ it's possible that its instances are not types. */
+ nbases = PyTuple_GET_SIZE(bases);
+ winner = metatype;
+ for (i = 0; i < nbases; i++) {
+ tmp = PyTuple_GET_ITEM(bases, i);
+ tmptype = tmp->ob_type;
+ if (tmptype == &PyClass_Type)
+ continue; /* Special case classic classes */
+ if (PyType_IsSubtype(winner, tmptype))
+ continue;
+ if (PyType_IsSubtype(tmptype, winner)) {
+ winner = tmptype;
+ continue;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases");
+ return NULL;
+ }
+ if (winner != metatype) {
+ if (winner->tp_new != type_new) /* Pass it to the winner */
+ return winner->tp_new(winner, args, kwds);
+ metatype = winner;
+ }
+
+ /* Adjust for empty tuple bases */
+ if (nbases == 0) {
+ bases = PyTuple_Pack(1, &PyBaseObject_Type);
+ if (bases == NULL)
+ return NULL;
+ nbases = 1;
+ }
+ else
+ Py_INCREF(bases);
+
+ /* XXX From here until type is allocated, "return NULL" leaks bases! */
+
+ /* Calculate best base, and check that all bases are type objects */
+ base = best_base(bases);
+ if (base == NULL) {
+ Py_DECREF(bases);
+ return NULL;
+ }
+ if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {
+ PyErr_Format(PyExc_TypeError,
+ "type '%.100s' is not an acceptable base type",
+ base->tp_name);
+ Py_DECREF(bases);
+ return NULL;
+ }
+
+ /* Check for a __slots__ sequence variable in dict, and count it */
+ slots = PyDict_GetItemString(dict, "__slots__");
+ nslots = 0;
+ add_dict = 0;
+ add_weak = 0;
+ may_add_dict = base->tp_dictoffset == 0;
+ may_add_weak = base->tp_weaklistoffset == 0 && base->tp_itemsize == 0;
+ if (slots == NULL) {
+ if (may_add_dict) {
+ add_dict++;
+ }
+ if (may_add_weak) {
+ add_weak++;
+ }
+ }
+ else {
+ /* Have slots */
+
+ /* Make it into a tuple */
+ if (PyString_Check(slots) || PyUnicode_Check(slots))
+ slots = PyTuple_Pack(1, slots);
+ else
+ slots = PySequence_Tuple(slots);
+ if (slots == NULL) {
+ Py_DECREF(bases);
+ return NULL;
+ }
+ assert(PyTuple_Check(slots));
+
+ /* Are slots allowed? */
+ nslots = PyTuple_GET_SIZE(slots);
+ if (nslots > 0 && base->tp_itemsize != 0) {
+ PyErr_Format(PyExc_TypeError,
+ "nonempty __slots__ "
+ "not supported for subtype of '%s'",
+ base->tp_name);
+ bad_slots:
+ Py_DECREF(bases);
+ Py_DECREF(slots);
+ return NULL;
+ }
+
+#ifdef Py_USING_UNICODE
+ tmp = _unicode_to_string(slots, nslots);
+ if (tmp == NULL)
+ goto bad_slots;
+ if (tmp != slots) {
+ Py_DECREF(slots);
+ slots = tmp;
+ }
+#endif
+ /* Check for valid slot names and two special cases */
+ for (i = 0; i < nslots; i++) {
+ PyObject *tmp = PyTuple_GET_ITEM(slots, i);
+ char *s;
+ if (!valid_identifier(tmp))
+ goto bad_slots;
+ assert(PyString_Check(tmp));
+ s = PyString_AS_STRING(tmp);
+ if (strcmp(s, "__dict__") == 0) {
+ if (!may_add_dict || add_dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "__dict__ slot disallowed: "
+ "we already got one");
+ goto bad_slots;
+ }
+ add_dict++;
+ }
+ if (strcmp(s, "__weakref__") == 0) {
+ if (!may_add_weak || add_weak) {
+ PyErr_SetString(PyExc_TypeError,
+ "__weakref__ slot disallowed: "
+ "either we already got one, "
+ "or __itemsize__ != 0");
+ goto bad_slots;
+ }
+ add_weak++;
+ }
+ }
+
+ /* Copy slots into a list, mangle names and sort them.
+ Sorted names are needed for __class__ assignment.
+ Convert them back to tuple at the end.
+ */
+ newslots = PyList_New(nslots - add_dict - add_weak);
+ if (newslots == NULL)
+ goto bad_slots;
+ for (i = j = 0; i < nslots; i++) {
+ char *s;
+ tmp = PyTuple_GET_ITEM(slots, i);
+ s = PyString_AS_STRING(tmp);
+ if ((add_dict && strcmp(s, "__dict__") == 0) ||
+ (add_weak && strcmp(s, "__weakref__") == 0))
+ continue;
+ tmp =_Py_Mangle(name, tmp);
+ if (!tmp) {
+ Py_DECREF(newslots);
+ goto bad_slots;
+ }
+ PyList_SET_ITEM(newslots, j, tmp);
+ j++;
+ }
+ assert(j == nslots - add_dict - add_weak);
+ nslots = j;
+ Py_DECREF(slots);
+ if (PyList_Sort(newslots) == -1) {
+ Py_DECREF(bases);
+ Py_DECREF(newslots);
+ return NULL;
+ }
+ slots = PyList_AsTuple(newslots);
+ Py_DECREF(newslots);
+ if (slots == NULL) {
+ Py_DECREF(bases);
+ return NULL;
+ }
+
+ /* Secondary bases may provide weakrefs or dict */
+ if (nbases > 1 &&
+ ((may_add_dict && !add_dict) ||
+ (may_add_weak && !add_weak))) {
+ for (i = 0; i < nbases; i++) {
+ tmp = PyTuple_GET_ITEM(bases, i);
+ if (tmp == (PyObject *)base)
+ continue; /* Skip primary base */
+ if (PyClass_Check(tmp)) {
+ /* Classic base class provides both */
+ if (may_add_dict && !add_dict)
+ add_dict++;
+ if (may_add_weak && !add_weak)
+ add_weak++;
+ break;
+ }
+ assert(PyType_Check(tmp));
+ tmptype = (PyTypeObject *)tmp;
+ if (may_add_dict && !add_dict &&
+ tmptype->tp_dictoffset != 0)
+ add_dict++;
+ if (may_add_weak && !add_weak &&
+ tmptype->tp_weaklistoffset != 0)
+ add_weak++;
+ if (may_add_dict && !add_dict)
+ continue;
+ if (may_add_weak && !add_weak)
+ continue;
+ /* Nothing more to check */
+ break;
+ }
+ }
+ }
+
+ /* XXX From here until type is safely allocated,
+ "return NULL" may leak slots! */
+
+ /* Allocate the type object */
+ type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);
+ if (type == NULL) {
+ Py_XDECREF(slots);
+ Py_DECREF(bases);
+ return NULL;
+ }
+
+ /* Keep name and slots alive in the extended type object */
+ et = (PyHeapTypeObject *)type;
+ Py_INCREF(name);
+ et->ht_name = name;
+ et->ht_slots = slots;
+
+ /* Initialize tp_flags */
+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
+ Py_TPFLAGS_BASETYPE;
+ if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+ if (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER)
+ type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
+
+ /* It's a new-style number unless it specifically inherits any
+ old-style numeric behavior */
+ if ((base->tp_flags & Py_TPFLAGS_CHECKTYPES) ||
+ (base->tp_as_number == NULL))
+ type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
+
+ /* Initialize essential fields */
+ type->tp_as_number = &et->as_number;
+ type->tp_as_sequence = &et->as_sequence;
+ type->tp_as_mapping = &et->as_mapping;
+ type->tp_as_buffer = &et->as_buffer;
+ type->tp_name = PyString_AS_STRING(name);
+
+ /* Set tp_base and tp_bases */
+ type->tp_bases = bases;
+ Py_INCREF(base);
+ type->tp_base = base;
+
+ /* Initialize tp_dict from passed-in dict */
+ type->tp_dict = dict = PyDict_Copy(dict);
+ if (dict == NULL) {
+ Py_DECREF(type);
+ return NULL;
+ }
+
+ /* Set __module__ in the dict */
+ if (PyDict_GetItemString(dict, "__module__") == NULL) {
+ tmp = PyEval_GetGlobals();
+ if (tmp != NULL) {
+ tmp = PyDict_GetItemString(tmp, "__name__");
+ if (tmp != NULL) {
+ if (PyDict_SetItemString(dict, "__module__",
+ tmp) < 0)
+ return NULL;
+ }
+ }
+ }
+
+ /* Set tp_doc to a copy of dict['__doc__'], if the latter is there
+ and is a string. The __doc__ accessor will first look for tp_doc;
+ if that fails, it will still look into __dict__.
+ */
+ {
+ PyObject *doc = PyDict_GetItemString(dict, "__doc__");
+ if (doc != NULL && PyString_Check(doc)) {
+ const size_t n = (size_t)PyString_GET_SIZE(doc);
+ char *tp_doc = (char *)PyObject_MALLOC(n+1);
+ if (tp_doc == NULL) {
+ Py_DECREF(type);
+ return NULL;
+ }
+ memcpy(tp_doc, PyString_AS_STRING(doc), n+1);
+ type->tp_doc = tp_doc;
+ }
+ }
+
+ /* Special-case __new__: if it's a plain function,
+ make it a static function */
+ tmp = PyDict_GetItemString(dict, "__new__");
+ if (tmp != NULL && PyFunction_Check(tmp)) {
+ tmp = PyStaticMethod_New(tmp);
+ if (tmp == NULL) {
+ Py_DECREF(type);
+ return NULL;
+ }
+ PyDict_SetItemString(dict, "__new__", tmp);
+ Py_DECREF(tmp);
+ }
+
+ /* Add descriptors for custom slots from __slots__, or for __dict__ */
+ mp = PyHeapType_GET_MEMBERS(et);
+ slotoffset = base->tp_basicsize;
+ if (slots != NULL) {
+ for (i = 0; i < nslots; i++, mp++) {
+ mp->name = PyString_AS_STRING(
+ PyTuple_GET_ITEM(slots, i));
+ mp->type = T_OBJECT_EX;
+ mp->offset = slotoffset;
+
+ /* __dict__ and __weakref__ are already filtered out */
+ assert(strcmp(mp->name, "__dict__") != 0);
+ assert(strcmp(mp->name, "__weakref__") != 0);
+
+ slotoffset += sizeof(PyObject *);
+ }
+ }
+ if (add_dict) {
+ if (base->tp_itemsize)
+ type->tp_dictoffset = -(long)sizeof(PyObject *);
+ else
+ type->tp_dictoffset = slotoffset;
+ slotoffset += sizeof(PyObject *);
+ }
+ if (add_weak) {
+ assert(!base->tp_itemsize);
+ type->tp_weaklistoffset = slotoffset;
+ slotoffset += sizeof(PyObject *);
+ }
+ type->tp_basicsize = slotoffset;
+ type->tp_itemsize = base->tp_itemsize;
+ type->tp_members = PyHeapType_GET_MEMBERS(et);
+
+ if (type->tp_weaklistoffset && type->tp_dictoffset)
+ type->tp_getset = subtype_getsets_full;
+ else if (type->tp_weaklistoffset && !type->tp_dictoffset)
+ type->tp_getset = subtype_getsets_weakref_only;
+ else if (!type->tp_weaklistoffset && type->tp_dictoffset)
+ type->tp_getset = subtype_getsets_dict_only;
+ else
+ type->tp_getset = NULL;
+
+ /* Special case some slots */
+ if (type->tp_dictoffset != 0 || nslots > 0) {
+ if (base->tp_getattr == NULL && base->tp_getattro == NULL)
+ type->tp_getattro = PyObject_GenericGetAttr;
+ if (base->tp_setattr == NULL && base->tp_setattro == NULL)
+ type->tp_setattro = PyObject_GenericSetAttr;
+ }
+ type->tp_dealloc = subtype_dealloc;
+
+ /* Enable GC unless there are really no instance variables possible */
+ if (!(type->tp_basicsize == sizeof(PyObject) &&
+ type->tp_itemsize == 0))
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+
+ /* Always override allocation strategy to use regular heap */
+ type->tp_alloc = PyType_GenericAlloc;
+ if (type->tp_flags & Py_TPFLAGS_HAVE_GC) {
+ type->tp_free = PyObject_GC_Del;
+ type->tp_traverse = subtype_traverse;
+ type->tp_clear = subtype_clear;
+ }
+ else
+ type->tp_free = PyObject_Del;
+
+ /* Initialize the rest */
+ if (PyType_Ready(type) < 0) {
+ Py_DECREF(type);
+ return NULL;
+ }
+
+ /* Put the proper slots in place */
+ fixup_slot_dispatchers(type);
+
+ return (PyObject *)type;
+}
+
+/* Internal API to look for a name through the MRO.
+ This returns a borrowed reference, and doesn't set an exception! */
+PyObject *
+_PyType_Lookup(PyTypeObject *type, PyObject *name)
+{
+ Py_ssize_t i, n;
+ PyObject *mro, *res, *base, *dict;
+ unsigned int h;
+
+ if (MCACHE_CACHEABLE_NAME(name) &&
+ PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {
+ /* fast path */
+ h = MCACHE_HASH_METHOD(type, name);
+ if (method_cache[h].version == type->tp_version_tag &&
+ method_cache[h].name == name)
+ return method_cache[h].value;
+ }
+
+ /* Look in tp_dict of types in MRO */
+ mro = type->tp_mro;
+
+ /* If mro is NULL, the type is either not yet initialized
+ by PyType_Ready(), or already cleared by type_clear().
+ Either way the safest thing to do is to return NULL. */
+ if (mro == NULL)
+ return NULL;
+
+ res = NULL;
+ assert(PyTuple_Check(mro));
+ n = PyTuple_GET_SIZE(mro);
+ for (i = 0; i < n; i++) {
+ base = PyTuple_GET_ITEM(mro, i);
+ if (PyClass_Check(base))
+ dict = ((PyClassObject *)base)->cl_dict;
+ else {
+ assert(PyType_Check(base));
+ dict = ((PyTypeObject *)base)->tp_dict;
+ }
+ assert(dict && PyDict_Check(dict));
+ res = PyDict_GetItem(dict, name);
+ if (res != NULL)
+ break;
+ }
+
+ if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) {
+ h = MCACHE_HASH_METHOD(type, name);
+ method_cache[h].version = type->tp_version_tag;
+ method_cache[h].value = res; /* borrowed */
+ Py_INCREF(name);
+ Py_DECREF(method_cache[h].name);
+ method_cache[h].name = name;
+ }
+ return res;
+}
+
+/* This is similar to PyObject_GenericGetAttr(),
+ but uses _PyType_Lookup() instead of just looking in type->tp_dict. */
+static PyObject *
+type_getattro(PyTypeObject *type, PyObject *name)
+{
+ PyTypeObject *metatype = Py_TYPE(type);
+ PyObject *meta_attribute, *attribute;
+ descrgetfunc meta_get;
+
+ if (!PyString_Check(name)) {
+ PyErr_Format(PyExc_TypeError,
+ "attribute name must be string, not '%.200s'",
+ name->ob_type->tp_name);
+ return NULL;
+ }
+
+ /* Initialize this type (we'll assume the metatype is initialized) */
+ if (type->tp_dict == NULL) {
+ if (PyType_Ready(type) < 0)
+ return NULL;
+ }
+
+ /* No readable descriptor found yet */
+ meta_get = NULL;
+
+ /* Look for the attribute in the metatype */
+ meta_attribute = _PyType_Lookup(metatype, name);
+
+ if (meta_attribute != NULL) {
+ meta_get = Py_TYPE(meta_attribute)->tp_descr_get;
+
+ if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
+ /* Data descriptors implement tp_descr_set to intercept
+ * writes. Assume the attribute is not overridden in
+ * type's tp_dict (and bases): call the descriptor now.
+ */
+ return meta_get(meta_attribute, (PyObject *)type,
+ (PyObject *)metatype);
+ }
+ Py_INCREF(meta_attribute);
+ }
+
+ /* No data descriptor found on metatype. Look in tp_dict of this
+ * type and its bases */
+ attribute = _PyType_Lookup(type, name);
+ if (attribute != NULL) {
+ /* Implement descriptor functionality, if any */
+ descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get;
+
+ Py_XDECREF(meta_attribute);
+
+ if (local_get != NULL) {
+ /* NULL 2nd argument indicates the descriptor was
+ * found on the target object itself (or a base) */
+ return local_get(attribute, (PyObject *)NULL,
+ (PyObject *)type);
+ }
+
+ Py_INCREF(attribute);
+ return attribute;
+ }
+
+ /* No attribute found in local __dict__ (or bases): use the
+ * descriptor from the metatype, if any */
+ if (meta_get != NULL) {
+ PyObject *res;
+ res = meta_get(meta_attribute, (PyObject *)type,
+ (PyObject *)metatype);
+ Py_DECREF(meta_attribute);
+ return res;
+ }
+
+ /* If an ordinary attribute was found on the metatype, return it now */
+ if (meta_attribute != NULL) {
+ return meta_attribute;
+ }
+
+ /* Give up */
+ PyErr_Format(PyExc_AttributeError,
+ "type object '%.50s' has no attribute '%.400s'",
+ type->tp_name, PyString_AS_STRING(name));
+ return NULL;
+}
+
+static int
+type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
+{
+ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "can't set attributes of built-in/extension type '%s'",
+ type->tp_name);
+ return -1;
+ }
+ if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
+ return -1;
+ return update_slot(type, name);
+}
+
+static void
+type_dealloc(PyTypeObject *type)
+{
+ PyHeapTypeObject *et;
+
+ /* Assert this is a heap-allocated type object */
+ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+ _PyObject_GC_UNTRACK(type);
+ PyObject_ClearWeakRefs((PyObject *)type);
+ et = (PyHeapTypeObject *)type;
+ Py_XDECREF(type->tp_base);
+ Py_XDECREF(type->tp_dict);
+ Py_XDECREF(type->tp_bases);
+ Py_XDECREF(type->tp_mro);
+ Py_XDECREF(type->tp_cache);
+ Py_XDECREF(type->tp_subclasses);
+ /* A type's tp_doc is heap allocated, unlike the tp_doc slots
+ * of most other objects. It's okay to cast it to char *.
+ */
+ PyObject_Free((char *)type->tp_doc);
+ Py_XDECREF(et->ht_name);
+ Py_XDECREF(et->ht_slots);
+ Py_TYPE(type)->tp_free((PyObject *)type);
+}
+
+static PyObject *
+type_subclasses(PyTypeObject *type, PyObject *args_ignored)
+{
+ PyObject *list, *raw, *ref;
+ Py_ssize_t i, n;
+
+ list = PyList_New(0);
+ if (list == NULL)
+ return NULL;
+ raw = type->tp_subclasses;
+ if (raw == NULL)
+ return list;
+ assert(PyList_Check(raw));
+ n = PyList_GET_SIZE(raw);
+ for (i = 0; i < n; i++) {
+ ref = PyList_GET_ITEM(raw, i);
+ assert(PyWeakref_CheckRef(ref));
+ ref = PyWeakref_GET_OBJECT(ref);
+ if (ref != Py_None) {
+ if (PyList_Append(list, ref) < 0) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ }
+ }
+ return list;
+}
+
+static PyMethodDef type_methods[] = {
+ {"mro", (PyCFunction)mro_external, METH_NOARGS,
+ PyDoc_STR("mro() -> list\nreturn a type's method resolution order")},
+ {"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS,
+ PyDoc_STR("__subclasses__() -> list of immediate subclasses")},
+ {"__instancecheck__", type___instancecheck__, METH_O,
+ PyDoc_STR("__instancecheck__() -> bool\ncheck if an object is an instance")},
+ {"__subclasscheck__", type___subclasscheck__, METH_O,
+ PyDoc_STR("__subclasscheck__() -> bool\ncheck if a class is a subclass")},
+ {0}
+};
+
+PyDoc_STRVAR(type_doc,
+"type(object) -> the object's type\n"
+"type(name, bases, dict) -> a new type");
+
+static int
+type_traverse(PyTypeObject *type, visitproc visit, void *arg)
+{
+ /* Because of type_is_gc(), the collector only calls this
+ for heaptypes. */
+ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+ Py_VISIT(type->tp_dict);
+ Py_VISIT(type->tp_cache);
+ Py_VISIT(type->tp_mro);
+ Py_VISIT(type->tp_bases);
+ Py_VISIT(type->tp_base);
+
+ /* There's no need to visit type->tp_subclasses or
+ ((PyHeapTypeObject *)type)->ht_slots, because they can't be involved
+ in cycles; tp_subclasses is a list of weak references,
+ and slots is a tuple of strings. */
+
+ return 0;
+}
+
+static int
+type_clear(PyTypeObject *type)
+{
+ /* Because of type_is_gc(), the collector only calls this
+ for heaptypes. */
+ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+
+ /* We need to invalidate the method cache carefully before clearing
+ the dict, so that other objects caught in a reference cycle
+ don't start calling destroyed methods.
+
+ Otherwise, the only field we need to clear is tp_mro, which is
+ part of a hard cycle (its first element is the class itself) that
+ won't be broken otherwise (it's a tuple and tuples don't have a
+ tp_clear handler). None of the other fields need to be
+ cleared, and here's why:
+
+ tp_cache:
+ Not used; if it were, it would be a dict.
+
+ tp_bases, tp_base:
+ If these are involved in a cycle, there must be at least
+ one other, mutable object in the cycle, e.g. a base
+ class's dict; the cycle will be broken that way.
+
+ tp_subclasses:
+ A list of weak references can't be part of a cycle; and
+ lists have their own tp_clear.
+
+ slots (in PyHeapTypeObject):
+ A tuple of strings can't be part of a cycle.
+ */
+
+ PyType_Modified(type);
+ if (type->tp_dict)
+ PyDict_Clear(type->tp_dict);
+ Py_CLEAR(type->tp_mro);
+
+ return 0;
+}
+
+static int
+type_is_gc(PyTypeObject *type)
+{
+ return type->tp_flags & Py_TPFLAGS_HEAPTYPE;
+}
+
+PyTypeObject PyType_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "type", /* tp_name */
+ sizeof(PyHeapTypeObject), /* tp_basicsize */
+ sizeof(PyMemberDef), /* tp_itemsize */
+ (destructor)type_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)type_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)_Py_HashPointer, /* tp_hash */
+ (ternaryfunc)type_call, /* tp_call */
+ 0, /* tp_str */
+ (getattrofunc)type_getattro, /* tp_getattro */
+ (setattrofunc)type_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS, /* tp_flags */
+ type_doc, /* tp_doc */
+ (traverseproc)type_traverse, /* tp_traverse */
+ (inquiry)type_clear, /* tp_clear */
+ type_richcompare, /* tp_richcompare */
+ offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ type_methods, /* tp_methods */
+ type_members, /* tp_members */
+ type_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */
+ type_init, /* tp_init */
+ 0, /* tp_alloc */
+ type_new, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+ (inquiry)type_is_gc, /* tp_is_gc */
+};
+
+
+/* The base type of all types (eventually)... except itself. */
+
+/* You may wonder why object.__new__() only complains about arguments
+ when object.__init__() is not overridden, and vice versa.
+
+ Consider the use cases:
+
+ 1. When neither is overridden, we want to hear complaints about
+ excess (i.e., any) arguments, since their presence could
+ indicate there's a bug.
+
+ 2. When defining an Immutable type, we are likely to override only
+ __new__(), since __init__() is called too late to initialize an
+ Immutable object. Since __new__() defines the signature for the
+ type, it would be a pain to have to override __init__() just to
+ stop it from complaining about excess arguments.
+
+ 3. When defining a Mutable type, we are likely to override only
+ __init__(). So here the converse reasoning applies: we don't
+ want to have to override __new__() just to stop it from
+ complaining.
+
+ 4. When __init__() is overridden, and the subclass __init__() calls
+ object.__init__(), the latter should complain about excess
+ arguments; ditto for __new__().
+
+ Use cases 2 and 3 make it unattractive to unconditionally check for
+ excess arguments. The best solution that addresses all four use
+ cases is as follows: __init__() complains about excess arguments
+ unless __new__() is overridden and __init__() is not overridden
+ (IOW, if __init__() is overridden or __new__() is not overridden);
+ symmetrically, __new__() complains about excess arguments unless
+ __init__() is overridden and __new__() is not overridden
+ (IOW, if __new__() is overridden or __init__() is not overridden).
+
+ However, for backwards compatibility, this breaks too much code.
+ Therefore, in 2.6, we'll *warn* about excess arguments when both
+ methods are overridden; for all other cases we'll use the above
+ rules.
+
+*/
+
+/* Forward */
+static PyObject *
+object_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static int
+excess_args(PyObject *args, PyObject *kwds)
+{
+ return PyTuple_GET_SIZE(args) ||
+ (kwds && PyDict_Check(kwds) && PyDict_Size(kwds));
+}
+
+static int
+object_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ int err = 0;
+ if (excess_args(args, kwds)) {
+ PyTypeObject *type = Py_TYPE(self);
+ if (type->tp_init != object_init &&
+ type->tp_new != object_new)
+ {
+ err = PyErr_WarnEx(PyExc_DeprecationWarning,
+ "object.__init__() takes no parameters",
+ 1);
+ }
+ else if (type->tp_init != object_init ||
+ type->tp_new == object_new)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "object.__init__() takes no parameters");
+ err = -1;
+ }
+ }
+ return err;
+}
+
+static PyObject *
+object_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int err = 0;
+ if (excess_args(args, kwds)) {
+ if (type->tp_new != object_new &&
+ type->tp_init != object_init)
+ {
+ err = PyErr_WarnEx(PyExc_DeprecationWarning,
+ "object() takes no parameters",
+ 1);
+ }
+ else if (type->tp_new != object_new ||
+ type->tp_init == object_init)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "object() takes no parameters");
+ err = -1;
+ }
+ }
+ if (err < 0)
+ return NULL;
+
+ if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) {
+ static PyObject *comma = NULL;
+ PyObject *abstract_methods = NULL;
+ PyObject *builtins;
+ PyObject *sorted;
+ PyObject *sorted_methods = NULL;
+ PyObject *joined = NULL;
+ const char *joined_str;
+
+ /* Compute ", ".join(sorted(type.__abstractmethods__))
+ into joined. */
+ abstract_methods = type_abstractmethods(type, NULL);
+ if (abstract_methods == NULL)
+ goto error;
+ builtins = PyEval_GetBuiltins();
+ if (builtins == NULL)
+ goto error;
+ sorted = PyDict_GetItemString(builtins, "sorted");
+ if (sorted == NULL)
+ goto error;
+ sorted_methods = PyObject_CallFunctionObjArgs(sorted,
+ abstract_methods,
+ NULL);
+ if (sorted_methods == NULL)
+ goto error;
+ if (comma == NULL) {
+ comma = PyString_InternFromString(", ");
+ if (comma == NULL)
+ goto error;
+ }
+ joined = PyObject_CallMethod(comma, "join",
+ "O", sorted_methods);
+ if (joined == NULL)
+ goto error;
+ joined_str = PyString_AsString(joined);
+ if (joined_str == NULL)
+ goto error;
+
+ PyErr_Format(PyExc_TypeError,
+ "Can't instantiate abstract class %s "
+ "with abstract methods %s",
+ type->tp_name,
+ joined_str);
+ error:
+ Py_XDECREF(joined);
+ Py_XDECREF(sorted_methods);
+ Py_XDECREF(abstract_methods);
+ return NULL;
+ }
+ return type->tp_alloc(type, 0);
+}
+
+static void
+object_dealloc(PyObject *self)
+{
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+object_repr(PyObject *self)
+{
+ PyTypeObject *type;
+ PyObject *mod, *name, *rtn;
+
+ type = Py_TYPE(self);
+ mod = type_module(type, NULL);
+ if (mod == NULL)
+ PyErr_Clear();
+ else if (!PyString_Check(mod)) {
+ Py_DECREF(mod);
+ mod = NULL;
+ }
+ name = type_name(type, NULL);
+ if (name == NULL) {
+ Py_XDECREF(mod);
+ return NULL;
+ }
+ if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__"))
+ rtn = PyString_FromFormat("<%s.%s object at %p>",
+ PyString_AS_STRING(mod),
+ PyString_AS_STRING(name),
+ self);
+ else
+ rtn = PyString_FromFormat("<%s object at %p>",
+ type->tp_name, self);
+ Py_XDECREF(mod);
+ Py_DECREF(name);
+ return rtn;
+}
+
+static PyObject *
+object_str(PyObject *self)
+{
+ unaryfunc f;
+
+ f = Py_TYPE(self)->tp_repr;
+ if (f == NULL)
+ f = object_repr;
+ return f(self);
+}
+
+static PyObject *
+object_get_class(PyObject *self, void *closure)
+{
+ Py_INCREF(Py_TYPE(self));
+ return (PyObject *)(Py_TYPE(self));
+}
+
+static int
+equiv_structs(PyTypeObject *a, PyTypeObject *b)
+{
+ return a == b ||
+ (a != NULL &&
+ b != NULL &&
+ a->tp_basicsize == b->tp_basicsize &&
+ a->tp_itemsize == b->tp_itemsize &&
+ a->tp_dictoffset == b->tp_dictoffset &&
+ a->tp_weaklistoffset == b->tp_weaklistoffset &&
+ ((a->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+ (b->tp_flags & Py_TPFLAGS_HAVE_GC)));
+}
+
+static int
+same_slots_added(PyTypeObject *a, PyTypeObject *b)
+{
+ PyTypeObject *base = a->tp_base;
+ Py_ssize_t size;
+ PyObject *slots_a, *slots_b;
+
+ assert(base == b->tp_base);
+ size = base->tp_basicsize;
+ if (a->tp_dictoffset == size && b->tp_dictoffset == size)
+ size += sizeof(PyObject *);
+ if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size)
+ size += sizeof(PyObject *);
+
+ /* Check slots compliance */
+ slots_a = ((PyHeapTypeObject *)a)->ht_slots;
+ slots_b = ((PyHeapTypeObject *)b)->ht_slots;
+ if (slots_a && slots_b) {
+ if (PyObject_Compare(slots_a, slots_b) != 0)
+ return 0;
+ size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a);
+ }
+ return size == a->tp_basicsize && size == b->tp_basicsize;
+}
+
+static int
+compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr)
+{
+ PyTypeObject *newbase, *oldbase;
+
+ if (newto->tp_dealloc != oldto->tp_dealloc ||
+ newto->tp_free != oldto->tp_free)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s assignment: "
+ "'%s' deallocator differs from '%s'",
+ attr,
+ newto->tp_name,
+ oldto->tp_name);
+ return 0;
+ }
+ newbase = newto;
+ oldbase = oldto;
+ while (equiv_structs(newbase, newbase->tp_base))
+ newbase = newbase->tp_base;
+ while (equiv_structs(oldbase, oldbase->tp_base))
+ oldbase = oldbase->tp_base;
+ if (newbase != oldbase &&
+ (newbase->tp_base != oldbase->tp_base ||
+ !same_slots_added(newbase, oldbase))) {
+ PyErr_Format(PyExc_TypeError,
+ "%s assignment: "
+ "'%s' object layout differs from '%s'",
+ attr,
+ newto->tp_name,
+ oldto->tp_name);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+object_set_class(PyObject *self, PyObject *value, void *closure)
+{
+ PyTypeObject *oldto = Py_TYPE(self);
+ PyTypeObject *newto;
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't delete __class__ attribute");
+ return -1;
+ }
+ if (!PyType_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "__class__ must be set to new-style class, not '%s' object",
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
+ newto = (PyTypeObject *)value;
+ if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) ||
+ !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "__class__ assignment: only for heap types");
+ return -1;
+ }
+ if (compatible_for_assignment(newto, oldto, "__class__")) {
+ Py_INCREF(newto);
+ Py_TYPE(self) = newto;
+ Py_DECREF(oldto);
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+static PyGetSetDef object_getsets[] = {
+ {"__class__", object_get_class, object_set_class,
+ PyDoc_STR("the object's class")},
+ {0}
+};
+
+
+/* Stuff to implement __reduce_ex__ for pickle protocols >= 2.
+ We fall back to helpers in copy_reg for:
+ - pickle protocols < 2
+ - calculating the list of slot names (done only once per class)
+ - the __newobj__ function (which is used as a token but never called)
+*/
+
+static PyObject *
+import_copyreg(void)
+{
+ static PyObject *copyreg_str;
+
+ if (!copyreg_str) {
+ copyreg_str = PyString_InternFromString("copy_reg");
+ if (copyreg_str == NULL)
+ return NULL;
+ }
+
+ return PyImport_Import(copyreg_str);
+}
+
+static PyObject *
+slotnames(PyObject *cls)
+{
+ PyObject *clsdict;
+ PyObject *copyreg;
+ PyObject *slotnames;
+
+ if (!PyType_Check(cls)) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ clsdict = ((PyTypeObject *)cls)->tp_dict;
+ slotnames = PyDict_GetItemString(clsdict, "__slotnames__");
+ if (slotnames != NULL && PyList_Check(slotnames)) {
+ Py_INCREF(slotnames);
+ return slotnames;
+ }
+
+ copyreg = import_copyreg();
+ if (copyreg == NULL)
+ return NULL;
+
+ slotnames = PyObject_CallMethod(copyreg, "_slotnames", "O", cls);
+ Py_DECREF(copyreg);
+ if (slotnames != NULL &&
+ slotnames != Py_None &&
+ !PyList_Check(slotnames))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "copy_reg._slotnames didn't return a list or None");
+ Py_DECREF(slotnames);
+ slotnames = NULL;
+ }
+
+ return slotnames;
+}
+
+static PyObject *
+reduce_2(PyObject *obj)
+{
+ PyObject *cls, *getnewargs;
+ PyObject *args = NULL, *args2 = NULL;
+ PyObject *getstate = NULL, *state = NULL, *names = NULL;
+ PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL;
+ PyObject *copyreg = NULL, *newobj = NULL, *res = NULL;
+ Py_ssize_t i, n;
+
+ cls = PyObject_GetAttrString(obj, "__class__");
+ if (cls == NULL)
+ return NULL;
+
+ getnewargs = PyObject_GetAttrString(obj, "__getnewargs__");
+ if (getnewargs != NULL) {
+ args = PyObject_CallObject(getnewargs, NULL);
+ Py_DECREF(getnewargs);
+ if (args != NULL && !PyTuple_Check(args)) {
+ PyErr_Format(PyExc_TypeError,
+ "__getnewargs__ should return a tuple, "
+ "not '%.200s'", Py_TYPE(args)->tp_name);
+ goto end;
+ }
+ }
+ else {
+ PyErr_Clear();
+ args = PyTuple_New(0);
+ }
+ if (args == NULL)
+ goto end;
+
+ getstate = PyObject_GetAttrString(obj, "__getstate__");
+ if (getstate != NULL) {
+ state = PyObject_CallObject(getstate, NULL);
+ Py_DECREF(getstate);
+ if (state == NULL)
+ goto end;
+ }
+ else {
+ PyErr_Clear();
+ state = PyObject_GetAttrString(obj, "__dict__");
+ if (state == NULL) {
+ PyErr_Clear();
+ state = Py_None;
+ Py_INCREF(state);
+ }
+ names = slotnames(cls);
+ if (names == NULL)
+ goto end;
+ if (names != Py_None) {
+ assert(PyList_Check(names));
+ slots = PyDict_New();
+ if (slots == NULL)
+ goto end;
+ n = 0;
+ /* Can't pre-compute the list size; the list
+ is stored on the class so accessible to other
+ threads, which may be run by DECREF */
+ for (i = 0; i < PyList_GET_SIZE(names); i++) {
+ PyObject *name, *value;
+ name = PyList_GET_ITEM(names, i);
+ value = PyObject_GetAttr(obj, name);
+ if (value == NULL)
+ PyErr_Clear();
+ else {
+ int err = PyDict_SetItem(slots, name,
+ value);
+ Py_DECREF(value);
+ if (err)
+ goto end;
+ n++;
+ }
+ }
+ if (n) {
+ state = Py_BuildValue("(NO)", state, slots);
+ if (state == NULL)
+ goto end;
+ }
+ }
+ }
+
+ if (!PyList_Check(obj)) {
+ listitems = Py_None;
+ Py_INCREF(listitems);
+ }
+ else {
+ listitems = PyObject_GetIter(obj);
+ if (listitems == NULL)
+ goto end;
+ }
+
+ if (!PyDict_Check(obj)) {
+ dictitems = Py_None;
+ Py_INCREF(dictitems);
+ }
+ else {
+ dictitems = PyObject_CallMethod(obj, "iteritems", "");
+ if (dictitems == NULL)
+ goto end;
+ }
+
+ copyreg = import_copyreg();
+ if (copyreg == NULL)
+ goto end;
+ newobj = PyObject_GetAttrString(copyreg, "__newobj__");
+ if (newobj == NULL)
+ goto end;
+
+ n = PyTuple_GET_SIZE(args);
+ args2 = PyTuple_New(n+1);
+ if (args2 == NULL)
+ goto end;
+ PyTuple_SET_ITEM(args2, 0, cls);
+ cls = NULL;
+ for (i = 0; i < n; i++) {
+ PyObject *v = PyTuple_GET_ITEM(args, i);
+ Py_INCREF(v);
+ PyTuple_SET_ITEM(args2, i+1, v);
+ }
+
+ res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems);
+
+ end:
+ Py_XDECREF(cls);
+ Py_XDECREF(args);
+ Py_XDECREF(args2);
+ Py_XDECREF(slots);
+ Py_XDECREF(state);
+ Py_XDECREF(names);
+ Py_XDECREF(listitems);
+ Py_XDECREF(dictitems);
+ Py_XDECREF(copyreg);
+ Py_XDECREF(newobj);
+ return res;
+}
+
+/*
+ * There were two problems when object.__reduce__ and object.__reduce_ex__
+ * were implemented in the same function:
+ * - trying to pickle an object with a custom __reduce__ method that
+ * fell back to object.__reduce__ in certain circumstances led to
+ * infinite recursion at Python level and eventual RuntimeError.
+ * - Pickling objects that lied about their type by overwriting the
+ * __class__ descriptor could lead to infinite recursion at C level
+ * and eventual segfault.
+ *
+ * Because of backwards compatibility, the two methods still have to
+ * behave in the same way, even if this is not required by the pickle
+ * protocol. This common functionality was moved to the _common_reduce
+ * function.
+ */
+static PyObject *
+_common_reduce(PyObject *self, int proto)
+{
+ PyObject *copyreg, *res;
+
+ if (proto >= 2)
+ return reduce_2(self);
+
+ copyreg = import_copyreg();
+ if (!copyreg)
+ return NULL;
+
+ res = PyEval_CallMethod(copyreg, "_reduce_ex", "(Oi)", self, proto);
+ Py_DECREF(copyreg);
+
+ return res;
+}
+
+static PyObject *
+object_reduce(PyObject *self, PyObject *args)
+{
+ int proto = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto))
+ return NULL;
+
+ return _common_reduce(self, proto);
+}
+
+static PyObject *
+object_reduce_ex(PyObject *self, PyObject *args)
+{
+ PyObject *reduce, *res;
+ int proto = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
+ return NULL;
+
+ reduce = PyObject_GetAttrString(self, "__reduce__");
+ if (reduce == NULL)
+ PyErr_Clear();
+ else {
+ PyObject *cls, *clsreduce, *objreduce;
+ int override;
+ cls = PyObject_GetAttrString(self, "__class__");
+ if (cls == NULL) {
+ Py_DECREF(reduce);
+ return NULL;
+ }
+ clsreduce = PyObject_GetAttrString(cls, "__reduce__");
+ Py_DECREF(cls);
+ if (clsreduce == NULL) {
+ Py_DECREF(reduce);
+ return NULL;
+ }
+ objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict,
+ "__reduce__");
+ override = (clsreduce != objreduce);
+ Py_DECREF(clsreduce);
+ if (override) {
+ res = PyObject_CallObject(reduce, NULL);
+ Py_DECREF(reduce);
+ return res;
+ }
+ else
+ Py_DECREF(reduce);
+ }
+
+ return _common_reduce(self, proto);
+}
+
+static PyObject *
+object_subclasshook(PyObject *cls, PyObject *args)
+{
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+PyDoc_STRVAR(object_subclasshook_doc,
+"Abstract classes can override this to customize issubclass().\n"
+"\n"
+"This is invoked early on by abc.ABCMeta.__subclasscheck__().\n"
+"It should return True, False or NotImplemented. If it returns\n"
+"NotImplemented, the normal algorithm is used. Otherwise, it\n"
+"overrides the normal algorithm (and the outcome is cached).\n");
+
+/*
+ from PEP 3101, this code implements:
+
+ class object:
+ def __format__(self, format_spec):
+ if isinstance(format_spec, str):
+ return format(str(self), format_spec)
+ elif isinstance(format_spec, unicode):
+ return format(unicode(self), format_spec)
+*/
+static PyObject *
+object_format(PyObject *self, PyObject *args)
+{
+ PyObject *format_spec;
+ PyObject *self_as_str = NULL;
+ PyObject *result = NULL;
+ Py_ssize_t format_len;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(format_spec)) {
+ format_len = PyUnicode_GET_SIZE(format_spec);
+ self_as_str = PyObject_Unicode(self);
+ } else if (PyString_Check(format_spec)) {
+#else
+ if (PyString_Check(format_spec)) {
+#endif
+ format_len = PyString_GET_SIZE(format_spec);
+ self_as_str = PyObject_Str(self);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "argument to __format__ must be unicode or str");
+ return NULL;
+ }
+
+ if (self_as_str != NULL) {
+ /* Issue 7994: If we're converting to a string, we
+ should reject format specifications */
+ if (format_len > 0) {
+ if (PyErr_WarnEx(PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty format "
+ "string is deprecated", 1) < 0) {
+ goto done;
+ }
+ /* Eventually this will become an error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to object.__format__");
+ goto done;
+ */
+ }
+ result = PyObject_Format(self_as_str, format_spec);
+ }
+
+done:
+ Py_XDECREF(self_as_str);
+
+ return result;
+}
+
+static PyObject *
+object_sizeof(PyObject *self, PyObject *args)
+{
+ Py_ssize_t res, isize;
+
+ res = 0;
+ isize = self->ob_type->tp_itemsize;
+ if (isize > 0)
+ res = Py_SIZE(self) * isize;
+ res += self->ob_type->tp_basicsize;
+
+ return PyInt_FromSsize_t(res);
+}
+
+static PyMethodDef object_methods[] = {
+ {"__reduce_ex__", object_reduce_ex, METH_VARARGS,
+ PyDoc_STR("helper for pickle")},
+ {"__reduce__", object_reduce, METH_VARARGS,
+ PyDoc_STR("helper for pickle")},
+ {"__subclasshook__", object_subclasshook, METH_CLASS | METH_VARARGS,
+ object_subclasshook_doc},
+ {"__format__", object_format, METH_VARARGS,
+ PyDoc_STR("default object formatter")},
+ {"__sizeof__", object_sizeof, METH_NOARGS,
+ PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")},
+ {0}
+};
+
+
+PyTypeObject PyBaseObject_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "object", /* tp_name */
+ sizeof(PyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ object_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ object_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)_Py_HashPointer, /* tp_hash */
+ 0, /* tp_call */
+ object_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ PyDoc_STR("The most base type"), /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ object_methods, /* tp_methods */
+ 0, /* tp_members */
+ object_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ object_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ object_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+
+/* Initialize the __dict__ in a type object */
+
+static int
+add_methods(PyTypeObject *type, PyMethodDef *meth)
+{
+ PyObject *dict = type->tp_dict;
+
+ for (; meth->ml_name != NULL; meth++) {
+ PyObject *descr;
+ int err;
+ if (PyDict_GetItemString(dict, meth->ml_name) &&
+ !(meth->ml_flags & METH_COEXIST))
+ continue;
+ if (meth->ml_flags & METH_CLASS) {
+ if (meth->ml_flags & METH_STATIC) {
+ PyErr_SetString(PyExc_ValueError,
+ "method cannot be both class and static");
+ return -1;
+ }
+ descr = PyDescr_NewClassMethod(type, meth);
+ }
+ else if (meth->ml_flags & METH_STATIC) {
+ PyObject *cfunc = PyCFunction_New(meth, NULL);
+ if (cfunc == NULL)
+ return -1;
+ descr = PyStaticMethod_New(cfunc);
+ Py_DECREF(cfunc);
+ }
+ else {
+ descr = PyDescr_NewMethod(type, meth);
+ }
+ if (descr == NULL)
+ return -1;
+ err = PyDict_SetItemString(dict, meth->ml_name, descr);
+ Py_DECREF(descr);
+ if (err < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+add_members(PyTypeObject *type, PyMemberDef *memb)
+{
+ PyObject *dict = type->tp_dict;
+
+ for (; memb->name != NULL; memb++) {
+ PyObject *descr;
+ if (PyDict_GetItemString(dict, memb->name))
+ continue;
+ descr = PyDescr_NewMember(type, memb);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, memb->name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
+}
+
+static int
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
+{
+ PyObject *dict = type->tp_dict;
+
+ for (; gsp->name != NULL; gsp++) {
+ PyObject *descr;
+ if (PyDict_GetItemString(dict, gsp->name))
+ continue;
+ descr = PyDescr_NewGetSet(type, gsp);
+
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ return 0;
+}
+
+#define BUFFER_FLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
+
+static void
+inherit_special(PyTypeObject *type, PyTypeObject *base)
+{
+ Py_ssize_t oldsize, newsize;
+
+ /* Special flag magic */
+ if (!type->tp_as_buffer && base->tp_as_buffer) {
+ type->tp_flags &= ~BUFFER_FLAGS;
+ type->tp_flags |=
+ base->tp_flags & BUFFER_FLAGS;
+ }
+ if (!type->tp_as_sequence && base->tp_as_sequence) {
+ type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
+ type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
+ }
+ if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
+ (base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
+ if ((!type->tp_as_number && base->tp_as_number) ||
+ (!type->tp_as_sequence && base->tp_as_sequence)) {
+ type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
+ if (!type->tp_as_number && !type->tp_as_sequence) {
+ type->tp_flags |= base->tp_flags &
+ Py_TPFLAGS_HAVE_INPLACEOPS;
+ }
+ }
+ /* Wow */
+ }
+ if (!type->tp_as_number && base->tp_as_number) {
+ type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
+ type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
+ }
+
+ /* Copying basicsize is connected to the GC flags */
+ oldsize = base->tp_basicsize;
+ newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
+ if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+ (base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+ (type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
+ (!type->tp_traverse && !type->tp_clear)) {
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+ if (type->tp_traverse == NULL)
+ type->tp_traverse = base->tp_traverse;
+ if (type->tp_clear == NULL)
+ type->tp_clear = base->tp_clear;
+ }
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+ /* The condition below could use some explanation.
+ It appears that tp_new is not inherited for static types
+ whose base class is 'object'; this seems to be a precaution
+ so that old extension types don't suddenly become
+ callable (object.__new__ wouldn't insure the invariants
+ that the extension type's own factory function ensures).
+ Heap types, of course, are under our control, so they do
+ inherit tp_new; static extension types that specify some
+ other built-in type as the default are considered
+ new-style-aware so they also inherit object.__new__. */
+ if (base != &PyBaseObject_Type ||
+ (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ if (type->tp_new == NULL)
+ type->tp_new = base->tp_new;
+ }
+ }
+ type->tp_basicsize = newsize;
+
+ /* Copy other non-function slots */
+
+#undef COPYVAL
+#define COPYVAL(SLOT) \
+ if (type->SLOT == 0) type->SLOT = base->SLOT
+
+ COPYVAL(tp_itemsize);
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) {
+ COPYVAL(tp_weaklistoffset);
+ }
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+ COPYVAL(tp_dictoffset);
+ }
+
+ /* Setup fast subclass flags */
+ if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException))
+ type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyType_Type))
+ type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyInt_Type))
+ type->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyLong_Type))
+ type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyString_Type))
+ type->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS;
+#ifdef Py_USING_UNICODE
+ else if (PyType_IsSubtype(base, &PyUnicode_Type))
+ type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS;
+#endif
+ else if (PyType_IsSubtype(base, &PyTuple_Type))
+ type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyList_Type))
+ type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
+ else if (PyType_IsSubtype(base, &PyDict_Type))
+ type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
+}
+
+static int
+overrides_name(PyTypeObject *type, char *name)
+{
+ PyObject *dict = type->tp_dict;
+
+ assert(dict != NULL);
+ if (PyDict_GetItemString(dict, name) != NULL) {
+ return 1;
+ }
+ return 0;
+}
+
+#define OVERRIDES_HASH(x) overrides_name(x, "__hash__")
+#define OVERRIDES_EQ(x) overrides_name(x, "__eq__")
+
+static void
+inherit_slots(PyTypeObject *type, PyTypeObject *base)
+{
+ PyTypeObject *basebase;
+
+#undef SLOTDEFINED
+#undef COPYSLOT
+#undef COPYNUM
+#undef COPYSEQ
+#undef COPYMAP
+#undef COPYBUF
+
+#define SLOTDEFINED(SLOT) \
+ (base->SLOT != 0 && \
+ (basebase == NULL || base->SLOT != basebase->SLOT))
+
+#define COPYSLOT(SLOT) \
+ if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->SLOT
+
+#define COPYNUM(SLOT) COPYSLOT(tp_as_number->SLOT)
+#define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT)
+#define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT)
+#define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT)
+
+ /* This won't inherit indirect slots (from tp_as_number etc.)
+ if type doesn't provide the space. */
+
+ if (type->tp_as_number != NULL && base->tp_as_number != NULL) {
+ basebase = base->tp_base;
+ if (basebase->tp_as_number == NULL)
+ basebase = NULL;
+ COPYNUM(nb_add);
+ COPYNUM(nb_subtract);
+ COPYNUM(nb_multiply);
+ COPYNUM(nb_divide);
+ COPYNUM(nb_remainder);
+ COPYNUM(nb_divmod);
+ COPYNUM(nb_power);
+ COPYNUM(nb_negative);
+ COPYNUM(nb_positive);
+ COPYNUM(nb_absolute);
+ COPYNUM(nb_nonzero);
+ COPYNUM(nb_invert);
+ COPYNUM(nb_lshift);
+ COPYNUM(nb_rshift);
+ COPYNUM(nb_and);
+ COPYNUM(nb_xor);
+ COPYNUM(nb_or);
+ COPYNUM(nb_coerce);
+ COPYNUM(nb_int);
+ COPYNUM(nb_long);
+ COPYNUM(nb_float);
+ COPYNUM(nb_oct);
+ COPYNUM(nb_hex);
+ COPYNUM(nb_inplace_add);
+ COPYNUM(nb_inplace_subtract);
+ COPYNUM(nb_inplace_multiply);
+ COPYNUM(nb_inplace_divide);
+ COPYNUM(nb_inplace_remainder);
+ COPYNUM(nb_inplace_power);
+ COPYNUM(nb_inplace_lshift);
+ COPYNUM(nb_inplace_rshift);
+ COPYNUM(nb_inplace_and);
+ COPYNUM(nb_inplace_xor);
+ COPYNUM(nb_inplace_or);
+ if (base->tp_flags & Py_TPFLAGS_CHECKTYPES) {
+ COPYNUM(nb_true_divide);
+ COPYNUM(nb_floor_divide);
+ COPYNUM(nb_inplace_true_divide);
+ COPYNUM(nb_inplace_floor_divide);
+ }
+ if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) {
+ COPYNUM(nb_index);
+ }
+ }
+
+ if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
+ basebase = base->tp_base;
+ if (basebase->tp_as_sequence == NULL)
+ basebase = NULL;
+ COPYSEQ(sq_length);
+ COPYSEQ(sq_concat);
+ COPYSEQ(sq_repeat);
+ COPYSEQ(sq_item);
+ COPYSEQ(sq_slice);
+ COPYSEQ(sq_ass_item);
+ COPYSEQ(sq_ass_slice);
+ COPYSEQ(sq_contains);
+ COPYSEQ(sq_inplace_concat);
+ COPYSEQ(sq_inplace_repeat);
+ }
+
+ if (type->tp_as_mapping != NULL && base->tp_as_mapping != NULL) {
+ basebase = base->tp_base;
+ if (basebase->tp_as_mapping == NULL)
+ basebase = NULL;
+ COPYMAP(mp_length);
+ COPYMAP(mp_subscript);
+ COPYMAP(mp_ass_subscript);
+ }
+
+ if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) {
+ basebase = base->tp_base;
+ if (basebase->tp_as_buffer == NULL)
+ basebase = NULL;
+ COPYBUF(bf_getreadbuffer);
+ COPYBUF(bf_getwritebuffer);
+ COPYBUF(bf_getsegcount);
+ COPYBUF(bf_getcharbuffer);
+ COPYBUF(bf_getbuffer);
+ COPYBUF(bf_releasebuffer);
+ }
+
+ basebase = base->tp_base;
+
+ COPYSLOT(tp_dealloc);
+ COPYSLOT(tp_print);
+ if (type->tp_getattr == NULL && type->tp_getattro == NULL) {
+ type->tp_getattr = base->tp_getattr;
+ type->tp_getattro = base->tp_getattro;
+ }
+ if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
+ type->tp_setattr = base->tp_setattr;
+ type->tp_setattro = base->tp_setattro;
+ }
+ /* tp_compare see tp_richcompare */
+ COPYSLOT(tp_repr);
+ /* tp_hash see tp_richcompare */
+ COPYSLOT(tp_call);
+ COPYSLOT(tp_str);
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
+ if (type->tp_compare == NULL &&
+ type->tp_richcompare == NULL &&
+ type->tp_hash == NULL)
+ {
+ type->tp_compare = base->tp_compare;
+ type->tp_richcompare = base->tp_richcompare;
+ type->tp_hash = base->tp_hash;
+ /* Check for changes to inherited methods in Py3k*/
+ if (Py_Py3kWarningFlag) {
+ if (base->tp_hash &&
+ (base->tp_hash != PyObject_HashNotImplemented) &&
+ !OVERRIDES_HASH(type)) {
+ if (OVERRIDES_EQ(type)) {
+ if (PyErr_WarnPy3k("Overriding "
+ "__eq__ blocks inheritance "
+ "of __hash__ in 3.x",
+ 1) < 0)
+ /* XXX This isn't right. If the warning is turned
+ into an exception, we should be communicating
+ the error back to the caller, but figuring out
+ how to clean up in that case is tricky. See
+ issue 8627 for more. */
+ PyErr_Clear();
+ }
+ }
+ }
+ }
+ }
+ else {
+ COPYSLOT(tp_compare);
+ }
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_ITER) {
+ COPYSLOT(tp_iter);
+ COPYSLOT(tp_iternext);
+ }
+ if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
+ COPYSLOT(tp_descr_get);
+ COPYSLOT(tp_descr_set);
+ COPYSLOT(tp_dictoffset);
+ COPYSLOT(tp_init);
+ COPYSLOT(tp_alloc);
+ COPYSLOT(tp_is_gc);
+ if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) ==
+ (base->tp_flags & Py_TPFLAGS_HAVE_GC)) {
+ /* They agree about gc. */
+ COPYSLOT(tp_free);
+ }
+ else if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
+ type->tp_free == NULL &&
+ base->tp_free == _PyObject_Del) {
+ /* A bit of magic to plug in the correct default
+ * tp_free function when a derived class adds gc,
+ * didn't define tp_free, and the base uses the
+ * default non-gc tp_free.
+ */
+ type->tp_free = PyObject_GC_Del;
+ }
+ /* else they didn't agree about gc, and there isn't something
+ * obvious to be done -- the type is on its own.
+ */
+ }
+}
+
+static int add_operators(PyTypeObject *);
+
+int
+PyType_Ready(PyTypeObject *type)
+{
+ PyObject *dict, *bases;
+ PyTypeObject *base;
+ Py_ssize_t i, n;
+
+ if (type->tp_flags & Py_TPFLAGS_READY) {
+ assert(type->tp_dict != NULL);
+ return 0;
+ }
+ assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
+
+ type->tp_flags |= Py_TPFLAGS_READYING;
+
+#ifdef Py_TRACE_REFS
+ /* PyType_Ready is the closest thing we have to a choke point
+ * for type objects, so is the best place I can think of to try
+ * to get type objects into the doubly-linked list of all objects.
+ * Still, not all type objects go thru PyType_Ready.
+ */
+ _Py_AddToAllObjects((PyObject *)type, 0);
+#endif
+
+ /* Initialize tp_base (defaults to BaseObject unless that's us) */
+ base = type->tp_base;
+ if (base == NULL && type != &PyBaseObject_Type) {
+ base = type->tp_base = &PyBaseObject_Type;
+ Py_INCREF(base);
+ }
+
+ /* Now the only way base can still be NULL is if type is
+ * &PyBaseObject_Type.
+ */
+
+ /* Initialize the base class */
+ if (base && base->tp_dict == NULL) {
+ if (PyType_Ready(base) < 0)
+ goto error;
+ }
+
+ /* Initialize ob_type if NULL. This means extensions that want to be
+ compilable separately on Windows can call PyType_Ready() instead of
+ initializing the ob_type field of their type objects. */
+ /* The test for base != NULL is really unnecessary, since base is only
+ NULL when type is &PyBaseObject_Type, and we know its ob_type is
+ not NULL (it's initialized to &PyType_Type). But coverity doesn't
+ know that. */
+ if (Py_TYPE(type) == NULL && base != NULL)
+ Py_TYPE(type) = Py_TYPE(base);
+
+ /* Initialize tp_bases */
+ bases = type->tp_bases;
+ if (bases == NULL) {
+ if (base == NULL)
+ bases = PyTuple_New(0);
+ else
+ bases = PyTuple_Pack(1, base);
+ if (bases == NULL)
+ goto error;
+ type->tp_bases = bases;
+ }
+
+ /* Initialize tp_dict */
+ dict = type->tp_dict;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ if (dict == NULL)
+ goto error;
+ type->tp_dict = dict;
+ }
+
+ /* Add type-specific descriptors to tp_dict */
+ if (add_operators(type) < 0)
+ goto error;
+ if (type->tp_methods != NULL) {
+ if (add_methods(type, type->tp_methods) < 0)
+ goto error;
+ }
+ if (type->tp_members != NULL) {
+ if (add_members(type, type->tp_members) < 0)
+ goto error;
+ }
+ if (type->tp_getset != NULL) {
+ if (add_getset(type, type->tp_getset) < 0)
+ goto error;
+ }
+
+ /* Calculate method resolution order */
+ if (mro_internal(type) < 0) {
+ goto error;
+ }
+
+ /* Inherit special flags from dominant base */
+ if (type->tp_base != NULL)
+ inherit_special(type, type->tp_base);
+
+ /* Initialize tp_dict properly */
+ bases = type->tp_mro;
+ assert(bases != NULL);
+ assert(PyTuple_Check(bases));
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 1; i < n; i++) {
+ PyObject *b = PyTuple_GET_ITEM(bases, i);
+ if (PyType_Check(b))
+ inherit_slots(type, (PyTypeObject *)b);
+ }
+
+ /* All bases of statically allocated type should be statically allocated */
+ if (Py_Py3kWarningFlag && !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ for (i = 0; i < n; i++) {
+ PyObject *b = PyTuple_GET_ITEM(bases, i);
+ if (PyType_Check(b) &&
+ (((PyTypeObject *)b)->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
+ char buf[300];
+ PyOS_snprintf(buf, sizeof(buf),
+ "type '%.100s' is not dynamically allocated but "
+ "its base type '%.100s' is dynamically allocated",
+ type->tp_name, ((PyTypeObject *)b)->tp_name);
+ if (PyErr_WarnPy3k(buf, 1) < 0)
+ goto error;
+ break;
+ }
+ }
+
+ /* Sanity check for tp_free. */
+ if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&
+ (type->tp_free == NULL || type->tp_free == PyObject_Del)) {
+ /* This base class needs to call tp_free, but doesn't have
+ * one, or its tp_free is for non-gc'ed objects.
+ */
+ PyErr_Format(PyExc_TypeError, "type '%.100s' participates in "
+ "gc and is a base type but has inappropriate "
+ "tp_free slot",
+ type->tp_name);
+ goto error;
+ }
+
+ /* if the type dictionary doesn't contain a __doc__, set it from
+ the tp_doc slot.
+ */
+ if (PyDict_GetItemString(type->tp_dict, "__doc__") == NULL) {
+ if (type->tp_doc != NULL) {
+ PyObject *doc = PyString_FromString(type->tp_doc);
+ if (doc == NULL)
+ goto error;
+ PyDict_SetItemString(type->tp_dict, "__doc__", doc);
+ Py_DECREF(doc);
+ } else {
+ PyDict_SetItemString(type->tp_dict,
+ "__doc__", Py_None);
+ }
+ }
+
+ /* Some more special stuff */
+ base = type->tp_base;
+ if (base != NULL) {
+ if (type->tp_as_number == NULL)
+ type->tp_as_number = base->tp_as_number;
+ if (type->tp_as_sequence == NULL)
+ type->tp_as_sequence = base->tp_as_sequence;
+ if (type->tp_as_mapping == NULL)
+ type->tp_as_mapping = base->tp_as_mapping;
+ if (type->tp_as_buffer == NULL)
+ type->tp_as_buffer = base->tp_as_buffer;
+ }
+
+ /* Link into each base class's list of subclasses */
+ bases = type->tp_bases;
+ n = PyTuple_GET_SIZE(bases);
+ for (i = 0; i < n; i++) {
+ PyObject *b = PyTuple_GET_ITEM(bases, i);
+ if (PyType_Check(b) &&
+ add_subclass((PyTypeObject *)b, type) < 0)
+ goto error;
+ }
+
+ /* All done -- set the ready flag */
+ assert(type->tp_dict != NULL);
+ type->tp_flags =
+ (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
+ return 0;
+
+ error:
+ type->tp_flags &= ~Py_TPFLAGS_READYING;
+ return -1;
+}
+
+static int
+add_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+ Py_ssize_t i;
+ int result;
+ PyObject *list, *ref, *newobj;
+
+ list = base->tp_subclasses;
+ if (list == NULL) {
+ base->tp_subclasses = list = PyList_New(0);
+ if (list == NULL)
+ return -1;
+ }
+ assert(PyList_Check(list));
+ newobj = PyWeakref_NewRef((PyObject *)type, NULL);
+ i = PyList_GET_SIZE(list);
+ while (--i >= 0) {
+ ref = PyList_GET_ITEM(list, i);
+ assert(PyWeakref_CheckRef(ref));
+ if (PyWeakref_GET_OBJECT(ref) == Py_None)
+ return PyList_SetItem(list, i, newobj);
+ }
+ result = PyList_Append(list, newobj);
+ Py_DECREF(newobj);
+ return result;
+}
+
+static void
+remove_subclass(PyTypeObject *base, PyTypeObject *type)
+{
+ Py_ssize_t i;
+ PyObject *list, *ref;
+
+ list = base->tp_subclasses;
+ if (list == NULL) {
+ return;
+ }
+ assert(PyList_Check(list));
+ i = PyList_GET_SIZE(list);
+ while (--i >= 0) {
+ ref = PyList_GET_ITEM(list, i);
+ assert(PyWeakref_CheckRef(ref));
+ if (PyWeakref_GET_OBJECT(ref) == (PyObject*)type) {
+ /* this can't fail, right? */
+ PySequence_DelItem(list, i);
+ return;
+ }
+ }
+}
+
+static int
+check_num_args(PyObject *ob, int n)
+{
+ if (!PyTuple_CheckExact(ob)) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyArg_UnpackTuple() argument list is not a tuple");
+ return 0;
+ }
+ if (n == PyTuple_GET_SIZE(ob))
+ return 1;
+ PyErr_Format(
+ PyExc_TypeError,
+ "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob));
+ return 0;
+}
+
+/* Generic wrappers for overloadable 'operators' such as __getitem__ */
+
+/* There's a wrapper *function* for each distinct function typedef used
+ for type object slots (e.g. binaryfunc, ternaryfunc, etc.). There's a
+ wrapper *table* for each distinct operation (e.g. __len__, __add__).
+ Most tables have only one entry; the tables for binary operators have two
+ entries, one regular and one with reversed arguments. */
+
+static PyObject *
+wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ lenfunc func = (lenfunc)wrapped;
+ Py_ssize_t res;
+
+ if (!check_num_args(args, 0))
+ return NULL;
+ res = (*func)(self);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ return PyInt_FromLong((long)res);
+}
+
+static PyObject *
+wrap_inquirypred(PyObject *self, PyObject *args, void *wrapped)
+{
+ inquiry func = (inquiry)wrapped;
+ int res;
+
+ if (!check_num_args(args, 0))
+ return NULL;
+ res = (*func)(self);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ return PyBool_FromLong((long)res);
+}
+
+static PyObject *
+wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ binaryfunc func = (binaryfunc)wrapped;
+ PyObject *other;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped)
+{
+ binaryfunc func = (binaryfunc)wrapped;
+ PyObject *other;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+ !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return (*func)(self, other);
+}
+
+static PyObject *
+wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+ binaryfunc func = (binaryfunc)wrapped;
+ PyObject *other;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
+ !PyType_IsSubtype(other->ob_type, self->ob_type)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return (*func)(other, self);
+}
+
+static PyObject *
+wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ coercion func = (coercion)wrapped;
+ PyObject *other, *res;
+ int ok;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ ok = func(&self, &other);
+ if (ok < 0)
+ return NULL;
+ if (ok > 0) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ res = PyTuple_New(2);
+ if (res == NULL) {
+ Py_DECREF(self);
+ Py_DECREF(other);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(res, 0, self);
+ PyTuple_SET_ITEM(res, 1, other);
+ return res;
+}
+
+static PyObject *
+wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ ternaryfunc func = (ternaryfunc)wrapped;
+ PyObject *other;
+ PyObject *third = Py_None;
+
+ /* Note: This wrapper only works for __pow__() */
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+ return NULL;
+ return (*func)(self, other, third);
+}
+
+static PyObject *
+wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
+{
+ ternaryfunc func = (ternaryfunc)wrapped;
+ PyObject *other;
+ PyObject *third = Py_None;
+
+ /* Note: This wrapper only works for __pow__() */
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third))
+ return NULL;
+ return (*func)(other, self, third);
+}
+
+static PyObject *
+wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ unaryfunc func = (unaryfunc)wrapped;
+
+ if (!check_num_args(args, 0))
+ return NULL;
+ return (*func)(self);
+}
+
+static PyObject *
+wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizeargfunc func = (ssizeargfunc)wrapped;
+ PyObject* o;
+ Py_ssize_t i;
+
+ if (!PyArg_UnpackTuple(args, "", 1, 1, &o))
+ return NULL;
+ i = PyNumber_AsSsize_t(o, PyExc_OverflowError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ return (*func)(self, i);
+}
+
+static Py_ssize_t
+getindex(PyObject *self, PyObject *arg)
+{
+ Py_ssize_t i;
+
+ i = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0) {
+ PySequenceMethods *sq = Py_TYPE(self)->tp_as_sequence;
+ if (sq && sq->sq_length) {
+ Py_ssize_t n = (*sq->sq_length)(self);
+ if (n < 0)
+ return -1;
+ i += n;
+ }
+ }
+ return i;
+}
+
+static PyObject *
+wrap_sq_item(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizeargfunc func = (ssizeargfunc)wrapped;
+ PyObject *arg;
+ Py_ssize_t i;
+
+ if (PyTuple_GET_SIZE(args) == 1) {
+ arg = PyTuple_GET_ITEM(args, 0);
+ i = getindex(self, arg);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ return (*func)(self, i);
+ }
+ check_num_args(args, 1);
+ assert(PyErr_Occurred());
+ return NULL;
+}
+
+static PyObject *
+wrap_ssizessizeargfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
+ Py_ssize_t i, j;
+
+ if (!PyArg_ParseTuple(args, "nn", &i, &j))
+ return NULL;
+ return (*func)(self, i, j);
+}
+
+static PyObject *
+wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizeobjargproc func = (ssizeobjargproc)wrapped;
+ Py_ssize_t i;
+ int res;
+ PyObject *arg, *value;
+
+ if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
+ return NULL;
+ i = getindex(self, arg);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ res = (*func)(self, i, value);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizeobjargproc func = (ssizeobjargproc)wrapped;
+ Py_ssize_t i;
+ int res;
+ PyObject *arg;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ arg = PyTuple_GET_ITEM(args, 0);
+ i = getindex(self, arg);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ res = (*func)(self, i, NULL);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_ssizessizeobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+ Py_ssize_t i, j;
+ int res;
+ PyObject *value;
+
+ if (!PyArg_ParseTuple(args, "nnO", &i, &j, &value))
+ return NULL;
+ res = (*func)(self, i, j, value);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
+{
+ ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
+ Py_ssize_t i, j;
+ int res;
+
+ if (!PyArg_ParseTuple(args, "nn", &i, &j))
+ return NULL;
+ res = (*func)(self, i, j, NULL);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* XXX objobjproc is a misnomer; should be objargpred */
+static PyObject *
+wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
+{
+ objobjproc func = (objobjproc)wrapped;
+ int res;
+ PyObject *value;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ value = PyTuple_GET_ITEM(args, 0);
+ res = (*func)(self, value);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ else
+ return PyBool_FromLong(res);
+}
+
+static PyObject *
+wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped)
+{
+ objobjargproc func = (objobjargproc)wrapped;
+ int res;
+ PyObject *key, *value;
+
+ if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
+ return NULL;
+ res = (*func)(self, key, value);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
+{
+ objobjargproc func = (objobjargproc)wrapped;
+ int res;
+ PyObject *key;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ key = PyTuple_GET_ITEM(args, 0);
+ res = (*func)(self, key, NULL);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ cmpfunc func = (cmpfunc)wrapped;
+ int res;
+ PyObject *other;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ if (Py_TYPE(other)->tp_compare != func &&
+ !PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s.__cmp__(x,y) requires y to be a '%s', not a '%s'",
+ Py_TYPE(self)->tp_name,
+ Py_TYPE(self)->tp_name,
+ Py_TYPE(other)->tp_name);
+ return NULL;
+ }
+ res = (*func)(self, other);
+ if (PyErr_Occurred())
+ return NULL;
+ return PyInt_FromLong((long)res);
+}
+
+/* Helper to check for object.__setattr__ or __delattr__ applied to a type.
+ This is called the Carlo Verre hack after its discoverer. */
+static int
+hackcheck(PyObject *self, setattrofunc func, char *what)
+{
+ PyTypeObject *type = Py_TYPE(self);
+ while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
+ type = type->tp_base;
+ /* If type is NULL now, this is a really weird type.
+ In the spirit of backwards compatibility (?), just shut up. */
+ if (type && type->tp_setattro != func) {
+ PyErr_Format(PyExc_TypeError,
+ "can't apply this %s to %s object",
+ what,
+ type->tp_name);
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
+{
+ setattrofunc func = (setattrofunc)wrapped;
+ int res;
+ PyObject *name, *value;
+
+ if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
+ return NULL;
+ if (!hackcheck(self, func, "__setattr__"))
+ return NULL;
+ res = (*func)(self, name, value);
+ if (res < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
+{
+ setattrofunc func = (setattrofunc)wrapped;
+ int res;
+ PyObject *name;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ name = PyTuple_GET_ITEM(args, 0);
+ if (!hackcheck(self, func, "__delattr__"))
+ return NULL;
+ res = (*func)(self, name, NULL);
+ if (res < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
+{
+ hashfunc func = (hashfunc)wrapped;
+ long res;
+
+ if (!check_num_args(args, 0))
+ return NULL;
+ res = (*func)(self);
+ if (res == -1 && PyErr_Occurred())
+ return NULL;
+ return PyInt_FromLong(res);
+}
+
+static PyObject *
+wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+ ternaryfunc func = (ternaryfunc)wrapped;
+
+ return (*func)(self, args, kwds);
+}
+
+static PyObject *
+wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op)
+{
+ richcmpfunc func = (richcmpfunc)wrapped;
+ PyObject *other;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ other = PyTuple_GET_ITEM(args, 0);
+ return (*func)(self, other, op);
+}
+
+#undef RICHCMP_WRAPPER
+#define RICHCMP_WRAPPER(NAME, OP) \
+static PyObject * \
+richcmp_##NAME(PyObject *self, PyObject *args, void *wrapped) \
+{ \
+ return wrap_richcmpfunc(self, args, wrapped, OP); \
+}
+
+RICHCMP_WRAPPER(lt, Py_LT)
+RICHCMP_WRAPPER(le, Py_LE)
+RICHCMP_WRAPPER(eq, Py_EQ)
+RICHCMP_WRAPPER(ne, Py_NE)
+RICHCMP_WRAPPER(gt, Py_GT)
+RICHCMP_WRAPPER(ge, Py_GE)
+
+static PyObject *
+wrap_next(PyObject *self, PyObject *args, void *wrapped)
+{
+ unaryfunc func = (unaryfunc)wrapped;
+ PyObject *res;
+
+ if (!check_num_args(args, 0))
+ return NULL;
+ res = (*func)(self);
+ if (res == NULL && !PyErr_Occurred())
+ PyErr_SetNone(PyExc_StopIteration);
+ return res;
+}
+
+static PyObject *
+wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
+{
+ descrgetfunc func = (descrgetfunc)wrapped;
+ PyObject *obj;
+ PyObject *type = NULL;
+
+ if (!PyArg_UnpackTuple(args, "", 1, 2, &obj, &type))
+ return NULL;
+ if (obj == Py_None)
+ obj = NULL;
+ if (type == Py_None)
+ type = NULL;
+ if (type == NULL &&obj == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "__get__(None, None) is invalid");
+ return NULL;
+ }
+ return (*func)(self, obj, type);
+}
+
+static PyObject *
+wrap_descr_set(PyObject *self, PyObject *args, void *wrapped)
+{
+ descrsetfunc func = (descrsetfunc)wrapped;
+ PyObject *obj, *value;
+ int ret;
+
+ if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
+ return NULL;
+ ret = (*func)(self, obj, value);
+ if (ret < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
+{
+ descrsetfunc func = (descrsetfunc)wrapped;
+ PyObject *obj;
+ int ret;
+
+ if (!check_num_args(args, 1))
+ return NULL;
+ obj = PyTuple_GET_ITEM(args, 0);
+ ret = (*func)(self, obj, NULL);
+ if (ret < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
+{
+ initproc func = (initproc)wrapped;
+
+ if (func(self, args, kwds) < 0)
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyTypeObject *type, *subtype, *staticbase;
+ PyObject *arg0, *res;
+
+ if (self == NULL || !PyType_Check(self))
+ Py_FatalError("__new__() called with non-type 'self'");
+ type = (PyTypeObject *)self;
+ if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) {
+ PyErr_Format(PyExc_TypeError,
+ "%s.__new__(): not enough arguments",
+ type->tp_name);
+ return NULL;
+ }
+ arg0 = PyTuple_GET_ITEM(args, 0);
+ if (!PyType_Check(arg0)) {
+ PyErr_Format(PyExc_TypeError,
+ "%s.__new__(X): X is not a type object (%s)",
+ type->tp_name,
+ Py_TYPE(arg0)->tp_name);
+ return NULL;
+ }
+ subtype = (PyTypeObject *)arg0;
+ if (!PyType_IsSubtype(subtype, type)) {
+ PyErr_Format(PyExc_TypeError,
+ "%s.__new__(%s): %s is not a subtype of %s",
+ type->tp_name,
+ subtype->tp_name,
+ subtype->tp_name,
+ type->tp_name);
+ return NULL;
+ }
+
+ /* Check that the use doesn't do something silly and unsafe like
+ object.__new__(dict). To do this, we check that the
+ most derived base that's not a heap type is this type. */
+ staticbase = subtype;
+ while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ staticbase = staticbase->tp_base;
+ /* If staticbase is NULL now, it is a really weird type.
+ In the spirit of backwards compatibility (?), just shut up. */
+ if (staticbase && staticbase->tp_new != type->tp_new) {
+ PyErr_Format(PyExc_TypeError,
+ "%s.__new__(%s) is not safe, use %s.__new__()",
+ type->tp_name,
+ subtype->tp_name,
+ staticbase->tp_name);
+ return NULL;
+ }
+
+ args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+ if (args == NULL)
+ return NULL;
+ res = type->tp_new(subtype, args, kwds);
+ Py_DECREF(args);
+ return res;
+}
+
+static struct PyMethodDef tp_new_methoddef[] = {
+ {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS,
+ PyDoc_STR("T.__new__(S, ...) -> "
+ "a new object with type S, a subtype of T")},
+ {0}
+};
+
+static int
+add_tp_new_wrapper(PyTypeObject *type)
+{
+ PyObject *func;
+
+ if (PyDict_GetItemString(type->tp_dict, "__new__") != NULL)
+ return 0;
+ func = PyCFunction_New(tp_new_methoddef, (PyObject *)type);
+ if (func == NULL)
+ return -1;
+ if (PyDict_SetItemString(type->tp_dict, "__new__", func)) {
+ Py_DECREF(func);
+ return -1;
+ }
+ Py_DECREF(func);
+ return 0;
+}
+
+/* Slot wrappers that call the corresponding __foo__ slot. See comments
+ below at override_slots() for more explanation. */
+
+#define SLOT0(FUNCNAME, OPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self) \
+{ \
+ static PyObject *cache_str; \
+ return call_method(self, OPSTR, &cache_str, "()"); \
+}
+
+#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1) \
+{ \
+ static PyObject *cache_str; \
+ return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
+}
+
+/* Boolean helper for SLOT1BINFULL().
+ right.__class__ is a nontrivial subclass of left.__class__. */
+static int
+method_is_overloaded(PyObject *left, PyObject *right, char *name)
+{
+ PyObject *a, *b;
+ int ok;
+
+ b = PyObject_GetAttrString((PyObject *)(Py_TYPE(right)), name);
+ if (b == NULL) {
+ PyErr_Clear();
+ /* If right doesn't have it, it's not overloaded */
+ return 0;
+ }
+
+ a = PyObject_GetAttrString((PyObject *)(Py_TYPE(left)), name);
+ if (a == NULL) {
+ PyErr_Clear();
+ Py_DECREF(b);
+ /* If right has it but left doesn't, it's overloaded */
+ return 1;
+ }
+
+ ok = PyObject_RichCompareBool(a, b, Py_NE);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ if (ok < 0) {
+ PyErr_Clear();
+ return 0;
+ }
+
+ return ok;
+}
+
+
+#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
+static PyObject * \
+FUNCNAME(PyObject *self, PyObject *other) \
+{ \
+ static PyObject *cache_str, *rcache_str; \
+ int do_other = Py_TYPE(self) != Py_TYPE(other) && \
+ Py_TYPE(other)->tp_as_number != NULL && \
+ Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \
+ if (Py_TYPE(self)->tp_as_number != NULL && \
+ Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \
+ PyObject *r; \
+ if (do_other && \
+ PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \
+ method_is_overloaded(self, other, ROPSTR)) { \
+ r = call_maybe( \
+ other, ROPSTR, &rcache_str, "(O)", self); \
+ if (r != Py_NotImplemented) \
+ return r; \
+ Py_DECREF(r); \
+ do_other = 0; \
+ } \
+ r = call_maybe( \
+ self, OPSTR, &cache_str, "(O)", other); \
+ if (r != Py_NotImplemented || \
+ Py_TYPE(other) == Py_TYPE(self)) \
+ return r; \
+ Py_DECREF(r); \
+ } \
+ if (do_other) { \
+ return call_maybe( \
+ other, ROPSTR, &rcache_str, "(O)", self); \
+ } \
+ Py_INCREF(Py_NotImplemented); \
+ return Py_NotImplemented; \
+}
+
+#define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \
+ SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR)
+
+#define SLOT2(FUNCNAME, OPSTR, ARG1TYPE, ARG2TYPE, ARGCODES) \
+static PyObject * \
+FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \
+{ \
+ static PyObject *cache_str; \
+ return call_method(self, OPSTR, &cache_str, \
+ "(" ARGCODES ")", arg1, arg2); \
+}
+
+static Py_ssize_t
+slot_sq_length(PyObject *self)
+{
+ static PyObject *len_str;
+ PyObject *res = call_method(self, "__len__", &len_str, "()");
+ Py_ssize_t len;
+
+ if (res == NULL)
+ return -1;
+ len = PyInt_AsSsize_t(res);
+ Py_DECREF(res);
+ if (len < 0) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_ValueError,
+ "__len__() should return >= 0");
+ return -1;
+ }
+ return len;
+}
+
+/* Super-optimized version of slot_sq_item.
+ Other slots could do the same... */
+static PyObject *
+slot_sq_item(PyObject *self, Py_ssize_t i)
+{
+ static PyObject *getitem_str;
+ PyObject *func, *args = NULL, *ival = NULL, *retval = NULL;
+ descrgetfunc f;
+
+ if (getitem_str == NULL) {
+ getitem_str = PyString_InternFromString("__getitem__");
+ if (getitem_str == NULL)
+ return NULL;
+ }
+ func = _PyType_Lookup(Py_TYPE(self), getitem_str);
+ if (func != NULL) {
+ if ((f = Py_TYPE(func)->tp_descr_get) == NULL)
+ Py_INCREF(func);
+ else {
+ func = f(func, self, (PyObject *)(Py_TYPE(self)));
+ if (func == NULL) {
+ return NULL;
+ }
+ }
+ ival = PyInt_FromSsize_t(i);
+ if (ival != NULL) {
+ args = PyTuple_New(1);
+ if (args != NULL) {
+ PyTuple_SET_ITEM(args, 0, ival);
+ retval = PyObject_Call(func, args, NULL);
+ Py_XDECREF(args);
+ Py_XDECREF(func);
+ return retval;
+ }
+ }
+ }
+ else {
+ PyErr_SetObject(PyExc_AttributeError, getitem_str);
+ }
+ Py_XDECREF(args);
+ Py_XDECREF(ival);
+ Py_XDECREF(func);
+ return NULL;
+}
+
+static PyObject*
+slot_sq_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j)
+{
+ static PyObject *getslice_str;
+
+ if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
+ "use __getitem__", 1) < 0)
+ return NULL;
+ return call_method(self, "__getslice__", &getslice_str,
+ "nn", i, j);
+}
+
+static int
+slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
+{
+ PyObject *res;
+ static PyObject *delitem_str, *setitem_str;
+
+ if (value == NULL)
+ res = call_method(self, "__delitem__", &delitem_str,
+ "(n)", index);
+ else
+ res = call_method(self, "__setitem__", &setitem_str,
+ "(nO)", index, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static int
+slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+ PyObject *res;
+ static PyObject *delslice_str, *setslice_str;
+
+ if (value == NULL) {
+ if (PyErr_WarnPy3k("in 3.x, __delslice__ has been removed; "
+ "use __delitem__", 1) < 0)
+ return -1;
+ res = call_method(self, "__delslice__", &delslice_str,
+ "(nn)", i, j);
+ }
+ else {
+ if (PyErr_WarnPy3k("in 3.x, __setslice__ has been removed; "
+ "use __setitem__", 1) < 0)
+ return -1;
+ res = call_method(self, "__setslice__", &setslice_str,
+ "(nnO)", i, j, value);
+ }
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static int
+slot_sq_contains(PyObject *self, PyObject *value)
+{
+ PyObject *func, *res, *args;
+ int result = -1;
+
+ static PyObject *contains_str;
+
+ func = lookup_maybe(self, "__contains__", &contains_str);
+ if (func != NULL) {
+ args = PyTuple_Pack(1, value);
+ if (args == NULL)
+ res = NULL;
+ else {
+ res = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ }
+ Py_DECREF(func);
+ if (res != NULL) {
+ result = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ }
+ }
+ else if (! PyErr_Occurred()) {
+ /* Possible results: -1 and 1 */
+ result = (int)_PySequence_IterSearch(self, value,
+ PY_ITERSEARCH_CONTAINS);
+ }
+ return result;
+}
+
+#define slot_mp_length slot_sq_length
+
+SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O")
+
+static int
+slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value)
+{
+ PyObject *res;
+ static PyObject *delitem_str, *setitem_str;
+
+ if (value == NULL)
+ res = call_method(self, "__delitem__", &delitem_str,
+ "(O)", key);
+ else
+ res = call_method(self, "__setitem__", &setitem_str,
+ "(OO)", key, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__")
+SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__")
+SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__")
+SLOT1BIN(slot_nb_divide, nb_divide, "__div__", "__rdiv__")
+SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__")
+SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__")
+
+static PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *);
+
+SLOT1BINFULL(slot_nb_power_binary, slot_nb_power,
+ nb_power, "__pow__", "__rpow__")
+
+static PyObject *
+slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
+{
+ static PyObject *pow_str;
+
+ if (modulus == Py_None)
+ return slot_nb_power_binary(self, other);
+ /* Three-arg power doesn't use __rpow__. But ternary_op
+ can call this when the second argument's type uses
+ slot_nb_power, so check before calling self.__pow__. */
+ if (Py_TYPE(self)->tp_as_number != NULL &&
+ Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) {
+ return call_method(self, "__pow__", &pow_str,
+ "(OO)", other, modulus);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+SLOT0(slot_nb_negative, "__neg__")
+SLOT0(slot_nb_positive, "__pos__")
+SLOT0(slot_nb_absolute, "__abs__")
+
+static int
+slot_nb_nonzero(PyObject *self)
+{
+ PyObject *func, *args;
+ static PyObject *nonzero_str, *len_str;
+ int result = -1;
+ int using_len = 0;
+
+ func = lookup_maybe(self, "__nonzero__", &nonzero_str);
+ if (func == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ func = lookup_maybe(self, "__len__", &len_str);
+ if (func == NULL)
+ return PyErr_Occurred() ? -1 : 1;
+ using_len = 1;
+ }
+ args = PyTuple_New(0);
+ if (args != NULL) {
+ PyObject *temp = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ if (temp != NULL) {
+ if (PyInt_CheckExact(temp) || PyBool_Check(temp))
+ result = PyObject_IsTrue(temp);
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%s should return "
+ "bool or int, returned %s",
+ (using_len ? "__len__"
+ : "__nonzero__"),
+ temp->ob_type->tp_name);
+ result = -1;
+ }
+ Py_DECREF(temp);
+ }
+ }
+ Py_DECREF(func);
+ return result;
+}
+
+
+static PyObject *
+slot_nb_index(PyObject *self)
+{
+ static PyObject *index_str;
+ return call_method(self, "__index__", &index_str, "()");
+}
+
+
+SLOT0(slot_nb_invert, "__invert__")
+SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
+SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
+SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__")
+SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__")
+SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")
+
+static int
+slot_nb_coerce(PyObject **a, PyObject **b)
+{
+ static PyObject *coerce_str;
+ PyObject *self = *a, *other = *b;
+
+ if (self->ob_type->tp_as_number != NULL &&
+ self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+ PyObject *r;
+ r = call_maybe(
+ self, "__coerce__", &coerce_str, "(O)", other);
+ if (r == NULL)
+ return -1;
+ if (r == Py_NotImplemented) {
+ Py_DECREF(r);
+ }
+ else {
+ if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "__coerce__ didn't return a 2-tuple");
+ Py_DECREF(r);
+ return -1;
+ }
+ *a = PyTuple_GET_ITEM(r, 0);
+ Py_INCREF(*a);
+ *b = PyTuple_GET_ITEM(r, 1);
+ Py_INCREF(*b);
+ Py_DECREF(r);
+ return 0;
+ }
+ }
+ if (other->ob_type->tp_as_number != NULL &&
+ other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
+ PyObject *r;
+ r = call_maybe(
+ other, "__coerce__", &coerce_str, "(O)", self);
+ if (r == NULL)
+ return -1;
+ if (r == Py_NotImplemented) {
+ Py_DECREF(r);
+ return 1;
+ }
+ if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "__coerce__ didn't return a 2-tuple");
+ Py_DECREF(r);
+ return -1;
+ }
+ *a = PyTuple_GET_ITEM(r, 1);
+ Py_INCREF(*a);
+ *b = PyTuple_GET_ITEM(r, 0);
+ Py_INCREF(*b);
+ Py_DECREF(r);
+ return 0;
+ }
+ return 1;
+}
+
+SLOT0(slot_nb_int, "__int__")
+SLOT0(slot_nb_long, "__long__")
+SLOT0(slot_nb_float, "__float__")
+SLOT0(slot_nb_oct, "__oct__")
+SLOT0(slot_nb_hex, "__hex__")
+SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
+SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
+SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
+SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O")
+/* Can't use SLOT1 here, because nb_inplace_power is ternary */
+static PyObject *
+slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2)
+{
+ static PyObject *cache_str;
+ return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1);
+}
+SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O")
+SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O")
+SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *, "O")
+SLOT1(slot_nb_inplace_or, "__ior__", PyObject *, "O")
+SLOT1BIN(slot_nb_floor_divide, nb_floor_divide,
+ "__floordiv__", "__rfloordiv__")
+SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__")
+SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O")
+SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O")
+
+static int
+half_compare(PyObject *self, PyObject *other)
+{
+ PyObject *func, *args, *res;
+ static PyObject *cmp_str;
+ Py_ssize_t c;
+
+ func = lookup_method(self, "__cmp__", &cmp_str);
+ if (func == NULL) {
+ PyErr_Clear();
+ }
+ else {
+ args = PyTuple_Pack(1, other);
+ if (args == NULL)
+ res = NULL;
+ else {
+ res = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ }
+ Py_DECREF(func);
+ if (res != Py_NotImplemented) {
+ if (res == NULL)
+ return -2;
+ c = PyInt_AsLong(res);
+ Py_DECREF(res);
+ if (c == -1 && PyErr_Occurred())
+ return -2;
+ return (c < 0) ? -1 : (c > 0) ? 1 : 0;
+ }
+ Py_DECREF(res);
+ }
+ return 2;
+}
+
+/* This slot is published for the benefit of try_3way_compare in object.c */
+int
+_PyObject_SlotCompare(PyObject *self, PyObject *other)
+{
+ int c;
+
+ if (Py_TYPE(self)->tp_compare == _PyObject_SlotCompare) {
+ c = half_compare(self, other);
+ if (c <= 1)
+ return c;
+ }
+ if (Py_TYPE(other)->tp_compare == _PyObject_SlotCompare) {
+ c = half_compare(other, self);
+ if (c < -1)
+ return -2;
+ if (c <= 1)
+ return -c;
+ }
+ return (void *)self < (void *)other ? -1 :
+ (void *)self > (void *)other ? 1 : 0;
+}
+
+static PyObject *
+slot_tp_repr(PyObject *self)
+{
+ PyObject *func, *res;
+ static PyObject *repr_str;
+
+ func = lookup_method(self, "__repr__", &repr_str);
+ if (func != NULL) {
+ res = PyEval_CallObject(func, NULL);
+ Py_DECREF(func);
+ return res;
+ }
+ PyErr_Clear();
+ return PyString_FromFormat("<%s object at %p>",
+ Py_TYPE(self)->tp_name, self);
+}
+
+static PyObject *
+slot_tp_str(PyObject *self)
+{
+ PyObject *func, *res;
+ static PyObject *str_str;
+
+ func = lookup_method(self, "__str__", &str_str);
+ if (func != NULL) {
+ res = PyEval_CallObject(func, NULL);
+ Py_DECREF(func);
+ return res;
+ }
+ else {
+ PyErr_Clear();
+ return slot_tp_repr(self);
+ }
+}
+
+static long
+slot_tp_hash(PyObject *self)
+{
+ PyObject *func;
+ static PyObject *hash_str, *eq_str, *cmp_str;
+ long h;
+
+ func = lookup_method(self, "__hash__", &hash_str);
+
+ if (func != NULL && func != Py_None) {
+ PyObject *res = PyEval_CallObject(func, NULL);
+ Py_DECREF(func);
+ if (res == NULL)
+ return -1;
+ if (PyLong_Check(res))
+ h = PyLong_Type.tp_hash(res);
+ else
+ h = PyInt_AsLong(res);
+ Py_DECREF(res);
+ }
+ else {
+ Py_XDECREF(func); /* may be None */
+ PyErr_Clear();
+ func = lookup_method(self, "__eq__", &eq_str);
+ if (func == NULL) {
+ PyErr_Clear();
+ func = lookup_method(self, "__cmp__", &cmp_str);
+ }
+ if (func != NULL) {
+ Py_DECREF(func);
+ return PyObject_HashNotImplemented(self);
+ }
+ PyErr_Clear();
+ h = _Py_HashPointer((void *)self);
+ }
+ if (h == -1 && !PyErr_Occurred())
+ h = -2;
+ return h;
+}
+
+static PyObject *
+slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static PyObject *call_str;
+ PyObject *meth = lookup_method(self, "__call__", &call_str);
+ PyObject *res;
+
+ if (meth == NULL)
+ return NULL;
+
+ res = PyObject_Call(meth, args, kwds);
+
+ Py_DECREF(meth);
+ return res;
+}
+
+/* There are two slot dispatch functions for tp_getattro.
+
+ - slot_tp_getattro() is used when __getattribute__ is overridden
+ but no __getattr__ hook is present;
+
+ - slot_tp_getattr_hook() is used when a __getattr__ hook is present.
+
+ The code in update_one_slot() always installs slot_tp_getattr_hook(); this
+ detects the absence of __getattr__ and then installs the simpler slot if
+ necessary. */
+
+static PyObject *
+slot_tp_getattro(PyObject *self, PyObject *name)
+{
+ static PyObject *getattribute_str = NULL;
+ return call_method(self, "__getattribute__", &getattribute_str,
+ "(O)", name);
+}
+
+static PyObject *
+call_attribute(PyObject *self, PyObject *attr, PyObject *name)
+{
+ PyObject *res, *descr = NULL;
+ descrgetfunc f = Py_TYPE(attr)->tp_descr_get;
+
+ if (f != NULL) {
+ descr = f(attr, self, (PyObject *)(Py_TYPE(self)));
+ if (descr == NULL)
+ return NULL;
+ else
+ attr = descr;
+ }
+ res = PyObject_CallFunctionObjArgs(attr, name, NULL);
+ Py_XDECREF(descr);
+ return res;
+}
+
+static PyObject *
+slot_tp_getattr_hook(PyObject *self, PyObject *name)
+{
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject *getattr, *getattribute, *res;
+ static PyObject *getattribute_str = NULL;
+ static PyObject *getattr_str = NULL;
+
+ if (getattr_str == NULL) {
+ getattr_str = PyString_InternFromString("__getattr__");
+ if (getattr_str == NULL)
+ return NULL;
+ }
+ if (getattribute_str == NULL) {
+ getattribute_str =
+ PyString_InternFromString("__getattribute__");
+ if (getattribute_str == NULL)
+ return NULL;
+ }
+ /* speed hack: we could use lookup_maybe, but that would resolve the
+ method fully for each attribute lookup for classes with
+ __getattr__, even when the attribute is present. So we use
+ _PyType_Lookup and create the method only when needed, with
+ call_attribute. */
+ getattr = _PyType_Lookup(tp, getattr_str);
+ if (getattr == NULL) {
+ /* No __getattr__ hook: use a simpler dispatcher */
+ tp->tp_getattro = slot_tp_getattro;
+ return slot_tp_getattro(self, name);
+ }
+ Py_INCREF(getattr);
+ /* speed hack: we could use lookup_maybe, but that would resolve the
+ method fully for each attribute lookup for classes with
+ __getattr__, even when self has the default __getattribute__
+ method. So we use _PyType_Lookup and create the method only when
+ needed, with call_attribute. */
+ getattribute = _PyType_Lookup(tp, getattribute_str);
+ if (getattribute == NULL ||
+ (Py_TYPE(getattribute) == &PyWrapperDescr_Type &&
+ ((PyWrapperDescrObject *)getattribute)->d_wrapped ==
+ (void *)PyObject_GenericGetAttr))
+ res = PyObject_GenericGetAttr(self, name);
+ else {
+ Py_INCREF(getattribute);
+ res = call_attribute(self, getattribute, name);
+ Py_DECREF(getattribute);
+ }
+ if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ res = call_attribute(self, getattr, name);
+ }
+ Py_DECREF(getattr);
+ return res;
+}
+
+static int
+slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value)
+{
+ PyObject *res;
+ static PyObject *delattr_str, *setattr_str;
+
+ if (value == NULL)
+ res = call_method(self, "__delattr__", &delattr_str,
+ "(O)", name);
+ else
+ res = call_method(self, "__setattr__", &setattr_str,
+ "(OO)", name, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static char *name_op[] = {
+ "__lt__",
+ "__le__",
+ "__eq__",
+ "__ne__",
+ "__gt__",
+ "__ge__",
+};
+
+static PyObject *
+half_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *func, *args, *res;
+ static PyObject *op_str[6];
+
+ func = lookup_method(self, name_op[op], &op_str[op]);
+ if (func == NULL) {
+ PyErr_Clear();
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ args = PyTuple_Pack(1, other);
+ if (args == NULL)
+ res = NULL;
+ else {
+ res = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ }
+ Py_DECREF(func);
+ return res;
+}
+
+static PyObject *
+slot_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *res;
+
+ if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {
+ res = half_richcompare(self, other, op);
+ if (res != Py_NotImplemented)
+ return res;
+ Py_DECREF(res);
+ }
+ if (Py_TYPE(other)->tp_richcompare == slot_tp_richcompare) {
+ res = half_richcompare(other, self, _Py_SwappedOp[op]);
+ if (res != Py_NotImplemented) {
+ return res;
+ }
+ Py_DECREF(res);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+static PyObject *
+slot_tp_iter(PyObject *self)
+{
+ PyObject *func, *res;
+ static PyObject *iter_str, *getitem_str;
+
+ func = lookup_method(self, "__iter__", &iter_str);
+ if (func != NULL) {
+ PyObject *args;
+ args = res = PyTuple_New(0);
+ if (args != NULL) {
+ res = PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ }
+ Py_DECREF(func);
+ return res;
+ }
+ PyErr_Clear();
+ func = lookup_method(self, "__getitem__", &getitem_str);
+ if (func == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not iterable",
+ Py_TYPE(self)->tp_name);
+ return NULL;
+ }
+ Py_DECREF(func);
+ return PySeqIter_New(self);
+}
+
+static PyObject *
+slot_tp_iternext(PyObject *self)
+{
+ static PyObject *next_str;
+ return call_method(self, "next", &next_str, "()");
+}
+
+static PyObject *
+slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject *get;
+ static PyObject *get_str = NULL;
+
+ if (get_str == NULL) {
+ get_str = PyString_InternFromString("__get__");
+ if (get_str == NULL)
+ return NULL;
+ }
+ get = _PyType_Lookup(tp, get_str);
+ if (get == NULL) {
+ /* Avoid further slowdowns */
+ if (tp->tp_descr_get == slot_tp_descr_get)
+ tp->tp_descr_get = NULL;
+ Py_INCREF(self);
+ return self;
+ }
+ if (obj == NULL)
+ obj = Py_None;
+ if (type == NULL)
+ type = Py_None;
+ return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL);
+}
+
+static int
+slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value)
+{
+ PyObject *res;
+ static PyObject *del_str, *set_str;
+
+ if (value == NULL)
+ res = call_method(self, "__delete__", &del_str,
+ "(O)", target);
+ else
+ res = call_method(self, "__set__", &set_str,
+ "(OO)", target, value);
+ if (res == NULL)
+ return -1;
+ Py_DECREF(res);
+ return 0;
+}
+
+static int
+slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static PyObject *init_str;
+ PyObject *meth = lookup_method(self, "__init__", &init_str);
+ PyObject *res;
+
+ if (meth == NULL)
+ return -1;
+ res = PyObject_Call(meth, args, kwds);
+ Py_DECREF(meth);
+ if (res == NULL)
+ return -1;
+ if (res != Py_None) {
+ PyErr_Format(PyExc_TypeError,
+ "__init__() should return None, not '%.200s'",
+ Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return -1;
+ }
+ Py_DECREF(res);
+ return 0;
+}
+
+static PyObject *
+slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ static PyObject *new_str;
+ PyObject *func;
+ PyObject *newargs, *x;
+ Py_ssize_t i, n;
+
+ if (new_str == NULL) {
+ new_str = PyString_InternFromString("__new__");
+ if (new_str == NULL)
+ return NULL;
+ }
+ func = PyObject_GetAttr((PyObject *)type, new_str);
+ if (func == NULL)
+ return NULL;
+ assert(PyTuple_Check(args));
+ n = PyTuple_GET_SIZE(args);
+ newargs = PyTuple_New(n+1);
+ if (newargs == NULL)
+ return NULL;
+ Py_INCREF(type);
+ PyTuple_SET_ITEM(newargs, 0, (PyObject *)type);
+ for (i = 0; i < n; i++) {
+ x = PyTuple_GET_ITEM(args, i);
+ Py_INCREF(x);
+ PyTuple_SET_ITEM(newargs, i+1, x);
+ }
+ x = PyObject_Call(func, newargs, kwds);
+ Py_DECREF(newargs);
+ Py_DECREF(func);
+ return x;
+}
+
+static void
+slot_tp_del(PyObject *self)
+{
+ static PyObject *del_str = NULL;
+ PyObject *del, *res;
+ PyObject *error_type, *error_value, *error_traceback;
+
+ /* Temporarily resurrect the object. */
+ assert(self->ob_refcnt == 0);
+ self->ob_refcnt = 1;
+
+ /* Save the current exception, if any. */
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+
+ /* Execute __del__ method, if any. */
+ del = lookup_maybe(self, "__del__", &del_str);
+ if (del != NULL) {
+ res = PyEval_CallObject(del, NULL);
+ if (res == NULL)
+ PyErr_WriteUnraisable(del);
+ else
+ Py_DECREF(res);
+ Py_DECREF(del);
+ }
+
+ /* Restore the saved exception. */
+ PyErr_Restore(error_type, error_value, error_traceback);
+
+ /* Undo the temporary resurrection; can't use DECREF here, it would
+ * cause a recursive call.
+ */
+ assert(self->ob_refcnt > 0);
+ if (--self->ob_refcnt == 0)
+ return; /* this is the normal path out */
+
+ /* __del__ resurrected it! Make it look like the original Py_DECREF
+ * never happened.
+ */
+ {
+ Py_ssize_t refcnt = self->ob_refcnt;
+ _Py_NewReference(self);
+ self->ob_refcnt = refcnt;
+ }
+ assert(!PyType_IS_GC(Py_TYPE(self)) ||
+ _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+ /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+ * we need to undo that. */
+ _Py_DEC_REFTOTAL;
+ /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+ * chain, so no more to do there.
+ * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+ * _Py_NewReference bumped tp_allocs: both of those need to be
+ * undone.
+ */
+#ifdef COUNT_ALLOCS
+ --Py_TYPE(self)->tp_frees;
+ --Py_TYPE(self)->tp_allocs;
+#endif
+}
+
+
+/*
+Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper functions.
+
+The table is ordered by offsets relative to the 'PyHeapTypeObject' structure,
+which incorporates the additional structures used for numbers, sequences and
+mappings. Note that multiple names may map to the same slot (e.g. __eq__,
+__ne__ etc. all map to tp_richcompare) and one name may map to multiple slots
+(e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with
+an all-zero entry. (This table is further initialized in init_slotdefs().)
+*/
+
+typedef struct wrapperbase slotdef;
+
+#undef TPSLOT
+#undef FLSLOT
+#undef ETSLOT
+#undef SQSLOT
+#undef MPSLOT
+#undef NBSLOT
+#undef UNSLOT
+#undef IBSLOT
+#undef BINSLOT
+#undef RBINSLOT
+
+#define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+ PyDoc_STR(DOC)}
+#define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \
+ {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+ PyDoc_STR(DOC), FLAGS}
+#define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \
+ PyDoc_STR(DOC)}
+#define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
+#define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
+#define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
+#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+ "x." NAME "() <==> " DOC)
+#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
+ "x." NAME "(y) <==> x" DOC "y")
+#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+ "x." NAME "(y) <==> x" DOC "y")
+#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+ "x." NAME "(y) <==> y" DOC "x")
+#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
+ "x." NAME "(y) <==> " DOC)
+#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
+ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
+ "x." NAME "(y) <==> " DOC)
+
+static slotdef slotdefs[] = {
+ TPSLOT("__str__", tp_print, NULL, NULL, ""),
+ TPSLOT("__repr__", tp_print, NULL, NULL, ""),
+ TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
+ TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
+ TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
+ TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
+ TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc,
+ "x.__cmp__(y) <==> cmp(x,y)"),
+ TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
+ "x.__repr__() <==> repr(x)"),
+ TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
+ "x.__hash__() <==> hash(x)"),
+ FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
+ "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS),
+ TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
+ "x.__str__() <==> str(x)"),
+ TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
+ wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
+ TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
+ TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
+ "x.__setattr__('name', value) <==> x.name = value"),
+ TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
+ "x.__delattr__('name') <==> del x.name"),
+ TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
+ "x.__lt__(y) <==> x<y"),
+ TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
+ "x.__le__(y) <==> x<=y"),
+ TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
+ "x.__eq__(y) <==> x==y"),
+ TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
+ "x.__ne__(y) <==> x!=y"),
+ TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
+ "x.__gt__(y) <==> x>y"),
+ TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
+ "x.__ge__(y) <==> x>=y"),
+ TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
+ "x.__iter__() <==> iter(x)"),
+ TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
+ "x.next() -> the next value, or raise StopIteration"),
+ TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
+ "descr.__get__(obj[, type]) -> value"),
+ TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
+ "descr.__set__(obj, value)"),
+ TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
+ wrap_descr_delete, "descr.__delete__(obj)"),
+ FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
+ "x.__init__(...) initializes x; "
+ "see help(type(x)) for signature",
+ PyWrapperFlag_KEYWORDS),
+ TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
+ TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""),
+ BINSLOT("__add__", nb_add, slot_nb_add,
+ "+"),
+ RBINSLOT("__radd__", nb_add, slot_nb_add,
+ "+"),
+ BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
+ "-"),
+ RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
+ "-"),
+ BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
+ "*"),
+ RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
+ "*"),
+ BINSLOT("__div__", nb_divide, slot_nb_divide,
+ "/"),
+ RBINSLOT("__rdiv__", nb_divide, slot_nb_divide,
+ "/"),
+ BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
+ "%"),
+ RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
+ "%"),
+ BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod,
+ "divmod(x, y)"),
+ RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
+ "divmod(y, x)"),
+ NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
+ "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
+ NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
+ "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
+ UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
+ UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
+ UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
+ "abs(x)"),
+ UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred,
+ "x != 0"),
+ UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
+ BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
+ RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
+ BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
+ RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"),
+ BINSLOT("__and__", nb_and, slot_nb_and, "&"),
+ RBINSLOT("__rand__", nb_and, slot_nb_and, "&"),
+ BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"),
+ RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"),
+ BINSLOT("__or__", nb_or, slot_nb_or, "|"),
+ RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
+ NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc,
+ "x.__coerce__(y) <==> coerce(x, y)"),
+ UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
+ "int(x)"),
+ UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc,
+ "long(x)"),
+ UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
+ "float(x)"),
+ UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc,
+ "oct(x)"),
+ UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
+ "hex(x)"),
+ IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
+ wrap_binaryfunc, "+="),
+ IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
+ wrap_binaryfunc, "-="),
+ IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply,
+ wrap_binaryfunc, "*="),
+ IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide,
+ wrap_binaryfunc, "/="),
+ IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder,
+ wrap_binaryfunc, "%="),
+ IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power,
+ wrap_binaryfunc, "**="),
+ IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift,
+ wrap_binaryfunc, "<<="),
+ IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift,
+ wrap_binaryfunc, ">>="),
+ IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and,
+ wrap_binaryfunc, "&="),
+ IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor,
+ wrap_binaryfunc, "^="),
+ IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or,
+ wrap_binaryfunc, "|="),
+ BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+ RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
+ BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"),
+ RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"),
+ IBSLOT("__ifloordiv__", nb_inplace_floor_divide,
+ slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="),
+ IBSLOT("__itruediv__", nb_inplace_true_divide,
+ slot_nb_inplace_true_divide, wrap_binaryfunc, "/="),
+ NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
+ "x[y:z] <==> x[y.__index__():z.__index__()]"),
+ MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
+ "x.__len__() <==> len(x)"),
+ MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
+ wrap_binaryfunc,
+ "x.__getitem__(y) <==> x[y]"),
+ MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
+ wrap_objobjargproc,
+ "x.__setitem__(i, y) <==> x[i]=y"),
+ MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
+ wrap_delitem,
+ "x.__delitem__(y) <==> del x[y]"),
+ SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
+ "x.__len__() <==> len(x)"),
+ /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
+ The logic in abstract.c always falls back to nb_add/nb_multiply in
+ this case. Defining both the nb_* and the sq_* slots to call the
+ user-defined methods has unexpected side-effects, as shown by
+ test_descr.notimplemented() */
+ SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
+ "x.__add__(y) <==> x+y"),
+ SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
+ "x.__mul__(n) <==> x*n"),
+ SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
+ "x.__rmul__(n) <==> n*x"),
+ SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
+ "x.__getitem__(y) <==> x[y]"),
+ SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
+ "x.__getslice__(i, j) <==> x[i:j]\n\
+ \n\
+ Use of negative indices is not supported."),
+ SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
+ "x.__setitem__(i, y) <==> x[i]=y"),
+ SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
+ "x.__delitem__(y) <==> del x[y]"),
+ SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
+ wrap_ssizessizeobjargproc,
+ "x.__setslice__(i, j, y) <==> x[i:j]=y\n\
+ \n\
+ Use of negative indices is not supported."),
+ SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
+ "x.__delslice__(i, j) <==> del x[i:j]\n\
+ \n\
+ Use of negative indices is not supported."),
+ SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
+ "x.__contains__(y) <==> y in x"),
+ SQSLOT("__iadd__", sq_inplace_concat, NULL,
+ wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
+ SQSLOT("__imul__", sq_inplace_repeat, NULL,
+ wrap_indexargfunc, "x.__imul__(y) <==> x*=y"),
+ {NULL}
+};
+
+/* Given a type pointer and an offset gotten from a slotdef entry, return a
+ pointer to the actual slot. This is not quite the same as simply adding
+ the offset to the type pointer, since it takes care to indirect through the
+ proper indirection pointer (as_buffer, etc.); it returns NULL if the
+ indirection pointer is NULL. */
+static void **
+slotptr(PyTypeObject *type, int ioffset)
+{
+ char *ptr;
+ long offset = ioffset;
+
+ /* Note: this depends on the order of the members of PyHeapTypeObject! */
+ assert(offset >= 0);
+ assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer));
+ if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) {
+ ptr = (char *)type->tp_as_sequence;
+ offset -= offsetof(PyHeapTypeObject, as_sequence);
+ }
+ else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_mapping)) {
+ ptr = (char *)type->tp_as_mapping;
+ offset -= offsetof(PyHeapTypeObject, as_mapping);
+ }
+ else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_number)) {
+ ptr = (char *)type->tp_as_number;
+ offset -= offsetof(PyHeapTypeObject, as_number);
+ }
+ else {
+ ptr = (char *)type;
+ }
+ if (ptr != NULL)
+ ptr += offset;
+ return (void **)ptr;
+}
+
+/* Length of array of slotdef pointers used to store slots with the
+ same __name__. There should be at most MAX_EQUIV-1 slotdef entries with
+ the same __name__, for any __name__. Since that's a static property, it is
+ appropriate to declare fixed-size arrays for this. */
+#define MAX_EQUIV 10
+
+/* Return a slot pointer for a given name, but ONLY if the attribute has
+ exactly one slot function. The name must be an interned string. */
+static void **
+resolve_slotdups(PyTypeObject *type, PyObject *name)
+{
+ /* XXX Maybe this could be optimized more -- but is it worth it? */
+
+ /* pname and ptrs act as a little cache */
+ static PyObject *pname;
+ static slotdef *ptrs[MAX_EQUIV];
+ slotdef *p, **pp;
+ void **res, **ptr;
+
+ if (pname != name) {
+ /* Collect all slotdefs that match name into ptrs. */
+ pname = name;
+ pp = ptrs;
+ for (p = slotdefs; p->name_strobj; p++) {
+ if (p->name_strobj == name)
+ *pp++ = p;
+ }
+ *pp = NULL;
+ }
+
+ /* Look in all matching slots of the type; if exactly one of these has
+ a filled-in slot, return its value. Otherwise return NULL. */
+ res = NULL;
+ for (pp = ptrs; *pp; pp++) {
+ ptr = slotptr(type, (*pp)->offset);
+ if (ptr == NULL || *ptr == NULL)
+ continue;
+ if (res != NULL)
+ return NULL;
+ res = ptr;
+ }
+ return res;
+}
+
+/* Common code for update_slots_callback() and fixup_slot_dispatchers(). This
+ does some incredibly complex thinking and then sticks something into the
+ slot. (It sees if the adjacent slotdefs for the same slot have conflicting
+ interests, and then stores a generic wrapper or a specific function into
+ the slot.) Return a pointer to the next slotdef with a different offset,
+ because that's convenient for fixup_slot_dispatchers(). */
+static slotdef *
+update_one_slot(PyTypeObject *type, slotdef *p)
+{
+ PyObject *descr;
+ PyWrapperDescrObject *d;
+ void *generic = NULL, *specific = NULL;
+ int use_generic = 0;
+ int offset = p->offset;
+ void **ptr = slotptr(type, offset);
+
+ if (ptr == NULL) {
+ do {
+ ++p;
+ } while (p->offset == offset);
+ return p;
+ }
+ do {
+ descr = _PyType_Lookup(type, p->name_strobj);
+ if (descr == NULL) {
+ if (ptr == (void**)&type->tp_iternext) {
+ specific = _PyObject_NextNotImplemented;
+ }
+ continue;
+ }
+ if (Py_TYPE(descr) == &PyWrapperDescr_Type &&
+ ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_strobj) {
+ void **tptr = resolve_slotdups(type, p->name_strobj);
+ if (tptr == NULL || tptr == ptr)
+ generic = p->function;
+ d = (PyWrapperDescrObject *)descr;
+ if (d->d_base->wrapper == p->wrapper &&
+ PyType_IsSubtype(type, d->d_type))
+ {
+ if (specific == NULL ||
+ specific == d->d_wrapped)
+ specific = d->d_wrapped;
+ else
+ use_generic = 1;
+ }
+ }
+ else if (Py_TYPE(descr) == &PyCFunction_Type &&
+ PyCFunction_GET_FUNCTION(descr) ==
+ (PyCFunction)tp_new_wrapper &&
+ ptr == (void**)&type->tp_new)
+ {
+ /* The __new__ wrapper is not a wrapper descriptor,
+ so must be special-cased differently.
+ If we don't do this, creating an instance will
+ always use slot_tp_new which will look up
+ __new__ in the MRO which will call tp_new_wrapper
+ which will look through the base classes looking
+ for a static base and call its tp_new (usually
+ PyType_GenericNew), after performing various
+ sanity checks and constructing a new argument
+ list. Cut all that nonsense short -- this speeds
+ up instance creation tremendously. */
+ specific = (void *)type->tp_new;
+ /* XXX I'm not 100% sure that there isn't a hole
+ in this reasoning that requires additional
+ sanity checks. I'll buy the first person to
+ point out a bug in this reasoning a beer. */
+ }
+ else if (descr == Py_None &&
+ ptr == (void**)&type->tp_hash) {
+ /* We specifically allow __hash__ to be set to None
+ to prevent inheritance of the default
+ implementation from object.__hash__ */
+ specific = PyObject_HashNotImplemented;
+ }
+ else {
+ use_generic = 1;
+ generic = p->function;
+ }
+ } while ((++p)->offset == offset);
+ if (specific && !use_generic)
+ *ptr = specific;
+ else
+ *ptr = generic;
+ return p;
+}
+
+/* In the type, update the slots whose slotdefs are gathered in the pp array.
+ This is a callback for update_subclasses(). */
+static int
+update_slots_callback(PyTypeObject *type, void *data)
+{
+ slotdef **pp = (slotdef **)data;
+
+ for (; *pp; pp++)
+ update_one_slot(type, *pp);
+ return 0;
+}
+
+/* Initialize the slotdefs table by adding interned string objects for the
+ names and sorting the entries. */
+static void
+init_slotdefs(void)
+{
+ slotdef *p;
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ for (p = slotdefs; p->name; p++) {
+ /* Slots must be ordered by their offset in the PyHeapTypeObject. */
+ assert(!p[1].name || p->offset <= p[1].offset);
+ p->name_strobj = PyString_InternFromString(p->name);
+ if (!p->name_strobj)
+ Py_FatalError("Out of memory interning slotdef names");
+ }
+ initialized = 1;
+}
+
+/* Update the slots after assignment to a class (type) attribute. */
+static int
+update_slot(PyTypeObject *type, PyObject *name)
+{
+ slotdef *ptrs[MAX_EQUIV];
+ slotdef *p;
+ slotdef **pp;
+ int offset;
+
+ /* Clear the VALID_VERSION flag of 'type' and all its
+ subclasses. This could possibly be unified with the
+ update_subclasses() recursion below, but carefully:
+ they each have their own conditions on which to stop
+ recursing into subclasses. */
+ PyType_Modified(type);
+
+ init_slotdefs();
+ pp = ptrs;
+ for (p = slotdefs; p->name; p++) {
+ /* XXX assume name is interned! */
+ if (p->name_strobj == name)
+ *pp++ = p;
+ }
+ *pp = NULL;
+ for (pp = ptrs; *pp; pp++) {
+ p = *pp;
+ offset = p->offset;
+ while (p > slotdefs && (p-1)->offset == offset)
+ --p;
+ *pp = p;
+ }
+ if (ptrs[0] == NULL)
+ return 0; /* Not an attribute that affects any slots */
+ return update_subclasses(type, name,
+ update_slots_callback, (void *)ptrs);
+}
+
+/* Store the proper functions in the slot dispatches at class (type)
+ definition time, based upon which operations the class overrides in its
+ dict. */
+static void
+fixup_slot_dispatchers(PyTypeObject *type)
+{
+ slotdef *p;
+
+ init_slotdefs();
+ for (p = slotdefs; p->name; )
+ p = update_one_slot(type, p);
+}
+
+static void
+update_all_slots(PyTypeObject* type)
+{
+ slotdef *p;
+
+ init_slotdefs();
+ for (p = slotdefs; p->name; p++) {
+ /* update_slot returns int but can't actually fail */
+ update_slot(type, p->name_strobj);
+ }
+}
+
+/* recurse_down_subclasses() and update_subclasses() are mutually
+ recursive functions to call a callback for all subclasses,
+ but refraining from recursing into subclasses that define 'name'. */
+
+static int
+update_subclasses(PyTypeObject *type, PyObject *name,
+ update_callback callback, void *data)
+{
+ if (callback(type, data) < 0)
+ return -1;
+ return recurse_down_subclasses(type, name, callback, data);
+}
+
+static int
+recurse_down_subclasses(PyTypeObject *type, PyObject *name,
+ update_callback callback, void *data)
+{
+ PyTypeObject *subclass;
+ PyObject *ref, *subclasses, *dict;
+ Py_ssize_t i, n;
+
+ subclasses = type->tp_subclasses;
+ if (subclasses == NULL)
+ return 0;
+ assert(PyList_Check(subclasses));
+ n = PyList_GET_SIZE(subclasses);
+ for (i = 0; i < n; i++) {
+ ref = PyList_GET_ITEM(subclasses, i);
+ assert(PyWeakref_CheckRef(ref));
+ subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref);
+ assert(subclass != NULL);
+ if ((PyObject *)subclass == Py_None)
+ continue;
+ assert(PyType_Check(subclass));
+ /* Avoid recursing down into unaffected classes */
+ dict = subclass->tp_dict;
+ if (dict != NULL && PyDict_Check(dict) &&
+ PyDict_GetItem(dict, name) != NULL)
+ continue;
+ if (update_subclasses(subclass, name, callback, data) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/* This function is called by PyType_Ready() to populate the type's
+ dictionary with method descriptors for function slots. For each
+ function slot (like tp_repr) that's defined in the type, one or more
+ corresponding descriptors are added in the type's tp_dict dictionary
+ under the appropriate name (like __repr__). Some function slots
+ cause more than one descriptor to be added (for example, the nb_add
+ slot adds both __add__ and __radd__ descriptors) and some function
+ slots compete for the same descriptor (for example both sq_item and
+ mp_subscript generate a __getitem__ descriptor).
+
+ In the latter case, the first slotdef entry encountered wins. Since
+ slotdef entries are sorted by the offset of the slot in the
+ PyHeapTypeObject, this gives us some control over disambiguating
+ between competing slots: the members of PyHeapTypeObject are listed
+ from most general to least general, so the most general slot is
+ preferred. In particular, because as_mapping comes before as_sequence,
+ for a type that defines both mp_subscript and sq_item, mp_subscript
+ wins.
+
+ This only adds new descriptors and doesn't overwrite entries in
+ tp_dict that were previously defined. The descriptors contain a
+ reference to the C function they must call, so that it's safe if they
+ are copied into a subtype's __dict__ and the subtype has a different
+ C function in its slot -- calling the method defined by the
+ descriptor will call the C function that was used to create it,
+ rather than the C function present in the slot when it is called.
+ (This is important because a subtype may have a C function in the
+ slot that calls the method from the dictionary, and we want to avoid
+ infinite recursion here.) */
+
+static int
+add_operators(PyTypeObject *type)
+{
+ PyObject *dict = type->tp_dict;
+ slotdef *p;
+ PyObject *descr;
+ void **ptr;
+
+ init_slotdefs();
+ for (p = slotdefs; p->name; p++) {
+ if (p->wrapper == NULL)
+ continue;
+ ptr = slotptr(type, p->offset);
+ if (!ptr || !*ptr)
+ continue;
+ if (PyDict_GetItem(dict, p->name_strobj))
+ continue;
+ if (*ptr == PyObject_HashNotImplemented) {
+ /* Classes may prevent the inheritance of the tp_hash
+ slot by storing PyObject_HashNotImplemented in it. Make it
+ visible as a None value for the __hash__ attribute. */
+ if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0)
+ return -1;
+ }
+ else {
+ descr = PyDescr_NewWrapper(type, p, *ptr);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ }
+ if (type->tp_new != NULL) {
+ if (add_tp_new_wrapper(type) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+
+/* Cooperative 'super' */
+
+typedef struct {
+ PyObject_HEAD
+ PyTypeObject *type;
+ PyObject *obj;
+ PyTypeObject *obj_type;
+} superobject;
+
+static PyMemberDef super_members[] = {
+ {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY,
+ "the class invoking super()"},
+ {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY,
+ "the instance invoking super(); may be None"},
+ {"__self_class__", T_OBJECT, offsetof(superobject, obj_type), READONLY,
+ "the type of the instance invoking super(); may be None"},
+ {0}
+};
+
+static void
+super_dealloc(PyObject *self)
+{
+ superobject *su = (superobject *)self;
+
+ _PyObject_GC_UNTRACK(self);
+ Py_XDECREF(su->obj);
+ Py_XDECREF(su->type);
+ Py_XDECREF(su->obj_type);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+super_repr(PyObject *self)
+{
+ superobject *su = (superobject *)self;
+
+ if (su->obj_type)
+ return PyString_FromFormat(
+ "<super: <class '%s'>, <%s object>>",
+ su->type ? su->type->tp_name : "NULL",
+ su->obj_type->tp_name);
+ else
+ return PyString_FromFormat(
+ "<super: <class '%s'>, NULL>",
+ su->type ? su->type->tp_name : "NULL");
+}
+
+static PyObject *
+super_getattro(PyObject *self, PyObject *name)
+{
+ superobject *su = (superobject *)self;
+ int skip = su->obj_type == NULL;
+
+ if (!skip) {
+ /* We want __class__ to return the class of the super object
+ (i.e. super, or a subclass), not the class of su->obj. */
+ skip = (PyString_Check(name) &&
+ PyString_GET_SIZE(name) == 9 &&
+ strcmp(PyString_AS_STRING(name), "__class__") == 0);
+ }
+
+ if (!skip) {
+ PyObject *mro, *res, *tmp, *dict;
+ PyTypeObject *starttype;
+ descrgetfunc f;
+ Py_ssize_t i, n;
+
+ starttype = su->obj_type;
+ mro = starttype->tp_mro;
+
+ if (mro == NULL)
+ n = 0;
+ else {
+ assert(PyTuple_Check(mro));
+ n = PyTuple_GET_SIZE(mro);
+ }
+ for (i = 0; i < n; i++) {
+ if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i))
+ break;
+ }
+ i++;
+ res = NULL;
+ for (; i < n; i++) {
+ tmp = PyTuple_GET_ITEM(mro, i);
+ if (PyType_Check(tmp))
+ dict = ((PyTypeObject *)tmp)->tp_dict;
+ else if (PyClass_Check(tmp))
+ dict = ((PyClassObject *)tmp)->cl_dict;
+ else
+ continue;
+ res = PyDict_GetItem(dict, name);
+ if (res != NULL) {
+ Py_INCREF(res);
+ f = Py_TYPE(res)->tp_descr_get;
+ if (f != NULL) {
+ tmp = f(res,
+ /* Only pass 'obj' param if
+ this is instance-mode super
+ (See SF ID #743627)
+ */
+ (su->obj == (PyObject *)
+ su->obj_type
+ ? (PyObject *)NULL
+ : su->obj),
+ (PyObject *)starttype);
+ Py_DECREF(res);
+ res = tmp;
+ }
+ return res;
+ }
+ }
+ }
+ return PyObject_GenericGetAttr(self, name);
+}
+
+static PyTypeObject *
+supercheck(PyTypeObject *type, PyObject *obj)
+{
+ /* Check that a super() call makes sense. Return a type object.
+
+ obj can be a new-style class, or an instance of one:
+
+ - If it is a class, it must be a subclass of 'type'. This case is
+ used for class methods; the return value is obj.
+
+ - If it is an instance, it must be an instance of 'type'. This is
+ the normal case; the return value is obj.__class__.
+
+ But... when obj is an instance, we want to allow for the case where
+ Py_TYPE(obj) is not a subclass of type, but obj.__class__ is!
+ This will allow using super() with a proxy for obj.
+ */
+
+ /* Check for first bullet above (special case) */
+ if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) {
+ Py_INCREF(obj);
+ return (PyTypeObject *)obj;
+ }
+
+ /* Normal case */
+ if (PyType_IsSubtype(Py_TYPE(obj), type)) {
+ Py_INCREF(Py_TYPE(obj));
+ return Py_TYPE(obj);
+ }
+ else {
+ /* Try the slow way */
+ static PyObject *class_str = NULL;
+ PyObject *class_attr;
+
+ if (class_str == NULL) {
+ class_str = PyString_FromString("__class__");
+ if (class_str == NULL)
+ return NULL;
+ }
+
+ class_attr = PyObject_GetAttr(obj, class_str);
+
+ if (class_attr != NULL &&
+ PyType_Check(class_attr) &&
+ (PyTypeObject *)class_attr != Py_TYPE(obj))
+ {
+ int ok = PyType_IsSubtype(
+ (PyTypeObject *)class_attr, type);
+ if (ok)
+ return (PyTypeObject *)class_attr;
+ }
+
+ if (class_attr == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(class_attr);
+ }
+
+ PyErr_SetString(PyExc_TypeError,
+ "super(type, obj): "
+ "obj must be an instance or subtype of type");
+ return NULL;
+}
+
+static PyObject *
+super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ superobject *su = (superobject *)self;
+ superobject *newobj;
+
+ if (obj == NULL || obj == Py_None || su->obj != NULL) {
+ /* Not binding to an object, or already bound */
+ Py_INCREF(self);
+ return self;
+ }
+ if (Py_TYPE(su) != &PySuper_Type)
+ /* If su is an instance of a (strict) subclass of super,
+ call its type */
+ return PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(su),
+ su->type, obj, NULL);
+ else {
+ /* Inline the common case */
+ PyTypeObject *obj_type = supercheck(su->type, obj);
+ if (obj_type == NULL)
+ return NULL;
+ newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
+ NULL, NULL);
+ if (newobj == NULL)
+ return NULL;
+ Py_INCREF(su->type);
+ Py_INCREF(obj);
+ newobj->type = su->type;
+ newobj->obj = obj;
+ newobj->obj_type = obj_type;
+ return (PyObject *)newobj;
+ }
+}
+
+static int
+super_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ superobject *su = (superobject *)self;
+ PyTypeObject *type;
+ PyObject *obj = NULL;
+ PyTypeObject *obj_type = NULL;
+
+ if (!_PyArg_NoKeywords("super", kwds))
+ return -1;
+ if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj))
+ return -1;
+ if (obj == Py_None)
+ obj = NULL;
+ if (obj != NULL) {
+ obj_type = supercheck(type, obj);
+ if (obj_type == NULL)
+ return -1;
+ Py_INCREF(obj);
+ }
+ Py_INCREF(type);
+ su->type = type;
+ su->obj = obj;
+ su->obj_type = obj_type;
+ return 0;
+}
+
+PyDoc_STRVAR(super_doc,
+"super(type, obj) -> bound super object; requires isinstance(obj, type)\n"
+"super(type) -> unbound super object\n"
+"super(type, type2) -> bound super object; requires issubclass(type2, type)\n"
+"Typical use to call a cooperative superclass method:\n"
+"class C(B):\n"
+" def meth(self, arg):\n"
+" super(C, self).meth(arg)");
+
+static int
+super_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ superobject *su = (superobject *)self;
+
+ Py_VISIT(su->obj);
+ Py_VISIT(su->type);
+ Py_VISIT(su->obj_type);
+
+ return 0;
+}
+
+PyTypeObject PySuper_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "super", /* tp_name */
+ sizeof(superobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ super_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ super_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ super_getattro, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
+ super_doc, /* tp_doc */
+ super_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ super_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ super_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ super_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ PyObject_GC_Del, /* tp_free */
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodectype.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodectype.c
new file mode 100644
index 0000000000..ca44bce6e2
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodectype.c
@@ -0,0 +1,215 @@
+/*
+ Unicode character type helpers.
+
+ Written by Marc-Andre Lemburg (mal@lemburg.com).
+ Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com)
+
+ Copyright (c) Corporation for National Research Initiatives.
+
+*/
+
+#include "Python.h"
+#include "unicodeobject.h"
+
+#define ALPHA_MASK 0x01
+#define DECIMAL_MASK 0x02
+#define DIGIT_MASK 0x04
+#define LOWER_MASK 0x08
+#define LINEBREAK_MASK 0x10
+#define SPACE_MASK 0x20
+#define TITLE_MASK 0x40
+#define UPPER_MASK 0x80
+#define NODELTA_MASK 0x100
+#define NUMERIC_MASK 0x200
+
+typedef struct {
+ const Py_UNICODE upper;
+ const Py_UNICODE lower;
+ const Py_UNICODE title;
+ const unsigned char decimal;
+ const unsigned char digit;
+ const unsigned short flags;
+} _PyUnicode_TypeRecord;
+
+#include "unicodetype_db.h"
+
+static const _PyUnicode_TypeRecord *
+gettyperecord(Py_UNICODE code)
+{
+ int index;
+
+#ifdef Py_UNICODE_WIDE
+ if (code >= 0x110000)
+ index = 0;
+ else
+#endif
+ {
+ index = index1[(code>>SHIFT)];
+ index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+ }
+
+ return &_PyUnicode_TypeRecords[index];
+}
+
+/* Returns the titlecase Unicode characters corresponding to ch or just
+ ch if no titlecase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+ int delta = ctype->title;
+
+ if (ctype->flags & NODELTA_MASK)
+ return delta;
+
+ if (delta >= 32768)
+ delta -= 65536;
+
+ return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lt', 0
+ otherwise. */
+
+int _PyUnicode_IsTitlecase(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & TITLE_MASK) != 0;
+}
+
+/* Returns the integer decimal (0-9) for Unicode characters having
+ this property, -1 otherwise. */
+
+int _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
+}
+
+int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
+{
+ if (_PyUnicode_ToDecimalDigit(ch) < 0)
+ return 0;
+ return 1;
+}
+
+/* Returns the integer digit (0-9) for Unicode characters having
+ this property, -1 otherwise. */
+
+int _PyUnicode_ToDigit(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1;
+}
+
+int _PyUnicode_IsDigit(Py_UNICODE ch)
+{
+ if (_PyUnicode_ToDigit(ch) < 0)
+ return 0;
+ return 1;
+}
+
+/* Returns the numeric value as double for Unicode characters having
+ this property, -1.0 otherwise. */
+
+int _PyUnicode_IsNumeric(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & NUMERIC_MASK) != 0;
+}
+
+#ifndef WANT_WCTYPE_FUNCTIONS
+
+/* Returns 1 for Unicode characters having the category 'Ll', 0
+ otherwise. */
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & LOWER_MASK) != 0;
+}
+
+/* Returns 1 for Unicode characters having the category 'Lu', 0
+ otherwise. */
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & UPPER_MASK) != 0;
+}
+
+/* Returns the uppercase Unicode characters corresponding to ch or just
+ ch if no uppercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+ int delta = ctype->upper;
+ if (ctype->flags & NODELTA_MASK)
+ return delta;
+ if (delta >= 32768)
+ delta -= 65536;
+ return ch + delta;
+}
+
+/* Returns the lowercase Unicode characters corresponding to ch or just
+ ch if no lowercase mapping is known. */
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+ int delta = ctype->lower;
+ if (ctype->flags & NODELTA_MASK)
+ return delta;
+ if (delta >= 32768)
+ delta -= 65536;
+ return ch + delta;
+}
+
+/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt',
+ 'Lo' or 'Lm', 0 otherwise. */
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+ return (ctype->flags & ALPHA_MASK) != 0;
+}
+
+#else
+
+/* Export the interfaces using the wchar_t type for portability
+ reasons: */
+
+int _PyUnicode_IsLowercase(Py_UNICODE ch)
+{
+ return iswlower(ch);
+}
+
+int _PyUnicode_IsUppercase(Py_UNICODE ch)
+{
+ return iswupper(ch);
+}
+
+Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+{
+ return towlower(ch);
+}
+
+Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+{
+ return towupper(ch);
+}
+
+int _PyUnicode_IsAlpha(Py_UNICODE ch)
+{
+ return iswalpha(ch);
+}
+
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodeobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodeobject.c
new file mode 100644
index 0000000000..41b6f0ec1b
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodeobject.c
@@ -0,0 +1,8994 @@
+/*
+
+Unicode implementation based on original code by Fredrik Lundh,
+modified by Marc-Andre Lemburg <mal@lemburg.com> according to the
+Unicode Integration Proposal (see file Misc/unicode.txt).
+
+Major speed upgrades to the method implementations at the Reykjavik
+NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke.
+
+Copyright (c) Corporation for National Research Initiatives.
+
+--------------------------------------------------------------------
+The original string type implementation is:
+
+ Copyright (c) 1999 by Secret Labs AB
+ Copyright (c) 1999 by Fredrik Lundh
+
+By obtaining, using, and/or copying this software and/or its
+associated documentation, you agree that you have read, understood,
+and will comply with the following terms and conditions:
+
+Permission to use, copy, modify, and distribute this software and its
+associated documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies, and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Secret Labs
+AB or the author not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--------------------------------------------------------------------
+
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#include "unicodeobject.h"
+#include "ucnhash.h"
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/* Limit for the Unicode object free list */
+
+#define PyUnicode_MAXFREELIST 1024
+
+/* Limit for the Unicode object free list stay alive optimization.
+
+ The implementation will keep allocated Unicode memory intact for
+ all objects on the free list having a size less than this
+ limit. This reduces malloc() overhead for small Unicode objects.
+
+ At worst this will result in PyUnicode_MAXFREELIST *
+ (sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT +
+ malloc()-overhead) bytes of unused garbage.
+
+ Setting the limit to 0 effectively turns the feature off.
+
+ Note: This is an experimental feature ! If you get core dumps when
+ using Unicode objects, turn this feature off.
+
+*/
+
+#define KEEPALIVE_SIZE_LIMIT 9
+
+/* Endianness switches; defaults to little endian */
+
+#ifdef WORDS_BIGENDIAN
+# define BYTEORDER_IS_BIG_ENDIAN
+#else
+# define BYTEORDER_IS_LITTLE_ENDIAN
+#endif
+
+/* --- Globals ------------------------------------------------------------
+
+NOTE: In the interpreter's initialization phase, some globals are currently
+ initialized dynamically as needed. In the process Unicode objects may
+ be created before the Unicode type is ready.
+
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Free list for Unicode objects */
+static PyUnicodeObject *free_list = NULL;
+static int numfree = 0;
+
+/* The empty Unicode object is shared to improve performance. */
+static PyUnicodeObject *unicode_empty = NULL;
+
+#define _Py_RETURN_UNICODE_EMPTY() \
+ do { \
+ if (unicode_empty != NULL) \
+ Py_INCREF(unicode_empty); \
+ else { \
+ unicode_empty = _PyUnicode_New(0); \
+ if (unicode_empty != NULL) \
+ Py_INCREF(unicode_empty); \
+ } \
+ return (PyObject *)unicode_empty; \
+ } while (0)
+
+/* Single character Unicode strings in the Latin-1 range are being
+ shared as well. */
+static PyUnicodeObject *unicode_latin1[256] = {NULL};
+
+/* Default encoding to use and assume when NULL is passed as encoding
+ parameter; it is initialized by _PyUnicode_Init().
+
+ Always use the PyUnicode_SetDefaultEncoding() and
+ PyUnicode_GetDefaultEncoding() APIs to access this global.
+
+*/
+static char unicode_default_encoding[100 + 1] = "ascii";
+
+/* Fast detection of the most frequent whitespace characters */
+const unsigned char _Py_ascii_whitespace[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* case 0x0009: * CHARACTER TABULATION */
+/* case 0x000A: * LINE FEED */
+/* case 0x000B: * LINE TABULATION */
+/* case 0x000C: * FORM FEED */
+/* case 0x000D: * CARRIAGE RETURN */
+ 0, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* case 0x001C: * FILE SEPARATOR */
+/* case 0x001D: * GROUP SEPARATOR */
+/* case 0x001E: * RECORD SEPARATOR */
+/* case 0x001F: * UNIT SEPARATOR */
+ 0, 0, 0, 0, 1, 1, 1, 1,
+/* case 0x0020: * SPACE */
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Same for linebreaks */
+static unsigned char ascii_linebreak[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x000A, * LINE FEED */
+/* 0x000B, * LINE TABULATION */
+/* 0x000C, * FORM FEED */
+/* 0x000D, * CARRIAGE RETURN */
+ 0, 0, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x001C, * FILE SEPARATOR */
+/* 0x001D, * GROUP SEPARATOR */
+/* 0x001E, * RECORD SEPARATOR */
+ 0, 0, 0, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+Py_UNICODE
+PyUnicode_GetMax(void)
+{
+#ifdef Py_UNICODE_WIDE
+ return 0x10FFFF;
+#else
+ /* This is actually an illegal character, so it should
+ not be passed to unichr. */
+ return 0xFFFF;
+#endif
+}
+
+/* --- Bloom Filters ----------------------------------------------------- */
+
+/* stuff to implement simple "bloom filters" for Unicode characters.
+ to keep things simple, we use a single bitmask, using the least 5
+ bits from each unicode characters as the bit index. */
+
+/* the linebreak mask is set up by Unicode_Init below */
+
+#if LONG_BIT >= 128
+#define BLOOM_WIDTH 128
+#elif LONG_BIT >= 64
+#define BLOOM_WIDTH 64
+#elif LONG_BIT >= 32
+#define BLOOM_WIDTH 32
+#else
+#error "LONG_BIT is smaller than 32"
+#endif
+
+#define BLOOM_MASK unsigned long
+
+static BLOOM_MASK bloom_linebreak = ~(BLOOM_MASK)0;
+
+#define BLOOM_ADD(mask, ch) ((mask |= (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
+#define BLOOM(mask, ch) ((mask & (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
+
+#define BLOOM_LINEBREAK(ch) \
+ ((ch) < 128U ? ascii_linebreak[(ch)] : \
+ (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch)))
+
+Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len)
+{
+ /* calculate simple bloom-style bitmask for a given unicode string */
+
+ BLOOM_MASK mask;
+ Py_ssize_t i;
+
+ mask = 0;
+ for (i = 0; i < len; i++)
+ BLOOM_ADD(mask, ptr[i]);
+
+ return mask;
+}
+
+Py_LOCAL_INLINE(int) unicode_member(Py_UNICODE chr, Py_UNICODE* set, Py_ssize_t setlen)
+{
+ Py_ssize_t i;
+
+ for (i = 0; i < setlen; i++)
+ if (set[i] == chr)
+ return 1;
+
+ return 0;
+}
+
+#define BLOOM_MEMBER(mask, chr, set, setlen) \
+ BLOOM(mask, chr) && unicode_member(chr, set, setlen)
+
+/* --- Unicode Object ----------------------------------------------------- */
+
+static
+int unicode_resize(register PyUnicodeObject *unicode,
+ Py_ssize_t length)
+{
+ void *oldstr;
+
+ /* Shortcut if there's nothing much to do. */
+ if (unicode->length == length)
+ goto reset;
+
+ /* Resizing shared object (unicode_empty or single character
+ objects) in-place is not allowed. Use PyUnicode_Resize()
+ instead ! */
+
+ if (unicode == unicode_empty ||
+ (unicode->length == 1 &&
+ unicode->str[0] < 256U &&
+ unicode_latin1[unicode->str[0]] == unicode)) {
+ PyErr_SetString(PyExc_SystemError,
+ "can't resize shared unicode objects");
+ return -1;
+ }
+
+ /* We allocate one more byte to make sure the string is Ux0000 terminated.
+ The overallocation is also used by fastsearch, which assumes that it's
+ safe to look at str[length] (without making any assumptions about what
+ it contains). */
+
+ oldstr = unicode->str;
+ unicode->str = PyObject_REALLOC(unicode->str,
+ sizeof(Py_UNICODE) * (length + 1));
+ if (!unicode->str) {
+ unicode->str = (Py_UNICODE *)oldstr;
+ PyErr_NoMemory();
+ return -1;
+ }
+ unicode->str[length] = 0;
+ unicode->length = length;
+
+ reset:
+ /* Reset the object caches */
+ if (unicode->defenc) {
+ Py_CLEAR(unicode->defenc);
+ }
+ unicode->hash = -1;
+
+ return 0;
+}
+
+/* We allocate one more byte to make sure the string is
+ Ux0000 terminated; some code relies on that.
+
+ XXX This allocator could further be enhanced by assuring that the
+ free list never reduces its size below 1.
+
+*/
+
+static
+PyUnicodeObject *_PyUnicode_New(Py_ssize_t length)
+{
+ register PyUnicodeObject *unicode;
+
+ /* Optimization for empty strings */
+ if (length == 0 && unicode_empty != NULL) {
+ Py_INCREF(unicode_empty);
+ return unicode_empty;
+ }
+
+ /* Ensure we won't overflow the size. */
+ if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) {
+ return (PyUnicodeObject *)PyErr_NoMemory();
+ }
+
+ /* Unicode freelist & memory allocation */
+ if (free_list) {
+ unicode = free_list;
+ free_list = *(PyUnicodeObject **)unicode;
+ numfree--;
+ if (unicode->str) {
+ /* Keep-Alive optimization: we only upsize the buffer,
+ never downsize it. */
+ if ((unicode->length < length) &&
+ unicode_resize(unicode, length) < 0) {
+ PyObject_DEL(unicode->str);
+ unicode->str = NULL;
+ }
+ }
+ else {
+ size_t new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
+ unicode->str = (Py_UNICODE*) PyObject_MALLOC(new_size);
+ }
+ PyObject_INIT(unicode, &PyUnicode_Type);
+ }
+ else {
+ size_t new_size;
+ unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type);
+ if (unicode == NULL)
+ return NULL;
+ new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
+ unicode->str = (Py_UNICODE*) PyObject_MALLOC(new_size);
+ }
+
+ if (!unicode->str) {
+ PyErr_NoMemory();
+ goto onError;
+ }
+ /* Initialize the first element to guard against cases where
+ * the caller fails before initializing str -- unicode_resize()
+ * reads str[0], and the Keep-Alive optimization can keep memory
+ * allocated for str alive across a call to unicode_dealloc(unicode).
+ * We don't want unicode_resize to read uninitialized memory in
+ * that case.
+ */
+ unicode->str[0] = 0;
+ unicode->str[length] = 0;
+ unicode->length = length;
+ unicode->hash = -1;
+ unicode->defenc = NULL;
+ return unicode;
+
+ onError:
+ /* XXX UNREF/NEWREF interface should be more symmetrical */
+ _Py_DEC_REFTOTAL;
+ _Py_ForgetReference((PyObject *)unicode);
+ PyObject_Del(unicode);
+ return NULL;
+}
+
+static
+void unicode_dealloc(register PyUnicodeObject *unicode)
+{
+ if (PyUnicode_CheckExact(unicode) &&
+ numfree < PyUnicode_MAXFREELIST) {
+ /* Keep-Alive optimization */
+ if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {
+ PyObject_DEL(unicode->str);
+ unicode->str = NULL;
+ unicode->length = 0;
+ }
+ if (unicode->defenc) {
+ Py_CLEAR(unicode->defenc);
+ }
+ /* Add to free list */
+ *(PyUnicodeObject **)unicode = free_list;
+ free_list = unicode;
+ numfree++;
+ }
+ else {
+ PyObject_DEL(unicode->str);
+ Py_XDECREF(unicode->defenc);
+ Py_TYPE(unicode)->tp_free((PyObject *)unicode);
+ }
+}
+
+static
+int _PyUnicode_Resize(PyUnicodeObject **unicode, Py_ssize_t length)
+{
+ register PyUnicodeObject *v;
+
+ /* Argument checks */
+ if (unicode == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ v = *unicode;
+ if (v == NULL || !PyUnicode_Check(v) || Py_REFCNT(v) != 1 || length < 0) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ /* Resizing unicode_empty and single character objects is not
+ possible since these are being shared. We simply return a fresh
+ copy with the same Unicode content. */
+ if (v->length != length &&
+ (v == unicode_empty || v->length == 1)) {
+ PyUnicodeObject *w = _PyUnicode_New(length);
+ if (w == NULL)
+ return -1;
+ Py_UNICODE_COPY(w->str, v->str,
+ length < v->length ? length : v->length);
+ Py_DECREF(*unicode);
+ *unicode = w;
+ return 0;
+ }
+
+ /* Note that we don't have to modify *unicode for unshared Unicode
+ objects, since we can modify them in-place. */
+ return unicode_resize(v, length);
+}
+
+int PyUnicode_Resize(PyObject **unicode, Py_ssize_t length)
+{
+ return _PyUnicode_Resize((PyUnicodeObject **)unicode, length);
+}
+
+PyObject *PyUnicode_FromUnicode(const Py_UNICODE *u,
+ Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+
+ /* If the Unicode data is known at construction time, we can apply
+ some optimizations which share commonly used objects. */
+ if (u != NULL) {
+
+ /* Optimization for empty strings */
+ if (size == 0)
+ _Py_RETURN_UNICODE_EMPTY();
+
+ /* Single character Unicode objects in the Latin-1 range are
+ shared when using this constructor */
+ if (size == 1 && *u < 256) {
+ unicode = unicode_latin1[*u];
+ if (!unicode) {
+ unicode = _PyUnicode_New(1);
+ if (!unicode)
+ return NULL;
+ unicode->str[0] = *u;
+ unicode_latin1[*u] = unicode;
+ }
+ Py_INCREF(unicode);
+ return (PyObject *)unicode;
+ }
+ }
+
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+
+ /* Copy the Unicode data into the new object */
+ if (u != NULL)
+ Py_UNICODE_COPY(unicode->str, u, size);
+
+ return (PyObject *)unicode;
+}
+
+PyObject *PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+
+ if (size < 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "Negative size passed to PyUnicode_FromStringAndSize");
+ return NULL;
+ }
+
+ /* If the Unicode data is known at construction time, we can apply
+ some optimizations which share commonly used objects.
+ Also, this means the input must be UTF-8, so fall back to the
+ UTF-8 decoder at the end. */
+ if (u != NULL) {
+
+ /* Optimization for empty strings */
+ if (size == 0)
+ _Py_RETURN_UNICODE_EMPTY();
+
+ /* Single characters are shared when using this constructor.
+ Restrict to ASCII, since the input must be UTF-8. */
+ if (size == 1 && Py_CHARMASK(*u) < 128) {
+ unicode = unicode_latin1[Py_CHARMASK(*u)];
+ if (!unicode) {
+ unicode = _PyUnicode_New(1);
+ if (!unicode)
+ return NULL;
+ unicode->str[0] = Py_CHARMASK(*u);
+ unicode_latin1[Py_CHARMASK(*u)] = unicode;
+ }
+ Py_INCREF(unicode);
+ return (PyObject *)unicode;
+ }
+
+ return PyUnicode_DecodeUTF8(u, size, NULL);
+ }
+
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+
+ return (PyObject *)unicode;
+}
+
+PyObject *PyUnicode_FromString(const char *u)
+{
+ size_t size = strlen(u);
+ if (size > PY_SSIZE_T_MAX) {
+ PyErr_SetString(PyExc_OverflowError, "input too long");
+ return NULL;
+ }
+
+ return PyUnicode_FromStringAndSize(u, size);
+}
+
+/* _Py_UNICODE_NEXT is a private macro used to retrieve the character pointed
+ * by 'ptr', possibly combining surrogate pairs on narrow builds.
+ * 'ptr' and 'end' must be Py_UNICODE*, with 'ptr' pointing at the character
+ * that should be returned and 'end' pointing to the end of the buffer.
+ * ('end' is used on narrow builds to detect a lone surrogate at the
+ * end of the buffer that should be returned unchanged.)
+ * The ptr and end arguments should be side-effect free and ptr must an lvalue.
+ * The type of the returned char is always Py_UCS4.
+ *
+ * Note: the macro advances ptr to next char, so it might have side-effects
+ * (especially if used with other macros).
+ */
+
+/* helper macros used by _Py_UNICODE_NEXT */
+#define _Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= ch && ch <= 0xDBFF)
+#define _Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= ch && ch <= 0xDFFF)
+/* Join two surrogate characters and return a single Py_UCS4 value. */
+#define _Py_UNICODE_JOIN_SURROGATES(high, low) \
+ (((((Py_UCS4)(high) & 0x03FF) << 10) | \
+ ((Py_UCS4)(low) & 0x03FF)) + 0x10000)
+
+#ifdef Py_UNICODE_WIDE
+#define _Py_UNICODE_NEXT(ptr, end) *(ptr)++
+#else
+#define _Py_UNICODE_NEXT(ptr, end) \
+ (((_Py_UNICODE_IS_HIGH_SURROGATE(*(ptr)) && (ptr) < (end)) && \
+ _Py_UNICODE_IS_LOW_SURROGATE((ptr)[1])) ? \
+ ((ptr) += 2,_Py_UNICODE_JOIN_SURROGATES((ptr)[-2], (ptr)[-1])) : \
+ (Py_UCS4)*(ptr)++)
+#endif
+
+#ifdef HAVE_WCHAR_H
+
+#if (Py_UNICODE_SIZE == 2) && defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
+# define CONVERT_WCHAR_TO_SURROGATES
+#endif
+
+#ifdef CONVERT_WCHAR_TO_SURROGATES
+
+/* Here sizeof(wchar_t) is 4 but Py_UNICODE_SIZE == 2, so we need
+ to convert from UTF32 to UTF16. */
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+ Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+ register Py_ssize_t i;
+ Py_ssize_t alloc;
+ const wchar_t *orig_w;
+
+ if (w == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ alloc = size;
+ orig_w = w;
+ for (i = size; i > 0; i--) {
+ if (*w > 0xFFFF)
+ alloc++;
+ w++;
+ }
+ w = orig_w;
+ unicode = _PyUnicode_New(alloc);
+ if (!unicode)
+ return NULL;
+
+ /* Copy the wchar_t data into the new object */
+ {
+ register Py_UNICODE *u;
+ u = PyUnicode_AS_UNICODE(unicode);
+ for (i = size; i > 0; i--) {
+ if (*w > 0xFFFF) {
+ wchar_t ordinal = *w++;
+ ordinal -= 0x10000;
+ *u++ = 0xD800 | (ordinal >> 10);
+ *u++ = 0xDC00 | (ordinal & 0x3FF);
+ }
+ else
+ *u++ = *w++;
+ }
+ }
+ return (PyObject *)unicode;
+}
+
+#else
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+ Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+
+ if (w == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+
+ /* Copy the wchar_t data into the new object */
+#ifdef HAVE_USABLE_WCHAR_T
+ memcpy(unicode->str, w, size * sizeof(wchar_t));
+#else
+ {
+ register Py_UNICODE *u;
+ register Py_ssize_t i;
+ u = PyUnicode_AS_UNICODE(unicode);
+ for (i = size; i > 0; i--)
+ *u++ = *w++;
+ }
+#endif
+
+ return (PyObject *)unicode;
+}
+
+#endif /* CONVERT_WCHAR_TO_SURROGATES */
+
+#undef CONVERT_WCHAR_TO_SURROGATES
+
+static void
+makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c)
+{
+ *fmt++ = '%';
+ if (width) {
+ if (zeropad)
+ *fmt++ = '0';
+ fmt += sprintf(fmt, "%d", width);
+ }
+ if (precision)
+ fmt += sprintf(fmt, ".%d", precision);
+ if (longflag)
+ *fmt++ = 'l';
+ else if (size_tflag) {
+ char *f = PY_FORMAT_SIZE_T;
+ while (*f)
+ *fmt++ = *f++;
+ }
+ *fmt++ = c;
+ *fmt = '\0';
+}
+
+#define appendstring(string) \
+ do { \
+ for (copy = string;*copy; copy++) { \
+ *s++ = (unsigned char)*copy; \
+ } \
+ } while (0)
+
+PyObject *
+PyUnicode_FromFormatV(const char *format, va_list vargs)
+{
+ va_list count;
+ Py_ssize_t callcount = 0;
+ PyObject **callresults = NULL;
+ PyObject **callresult = NULL;
+ Py_ssize_t n = 0;
+ int width = 0;
+ int precision = 0;
+ int zeropad;
+ const char* f;
+ Py_UNICODE *s;
+ PyObject *string;
+ /* used by sprintf */
+ char buffer[21];
+ /* use abuffer instead of buffer, if we need more space
+ * (which can happen if there's a format specifier with width). */
+ char *abuffer = NULL;
+ char *realbuffer;
+ Py_ssize_t abuffersize = 0;
+ char fmt[60]; /* should be enough for %0width.precisionld */
+ const char *copy;
+
+#ifdef VA_LIST_IS_ARRAY
+ Py_MEMCPY(count, vargs, sizeof(va_list));
+#else
+#ifdef __va_copy
+ __va_copy(count, vargs);
+#else
+ count = vargs;
+#endif
+#endif
+ /* step 1: count the number of %S/%R/%s format specifications
+ * (we call PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() for these
+ * objects once during step 3 and put the result in an array) */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ f++;
+ while (*f && *f != '%' && !isalpha((unsigned)*f))
+ f++;
+ if (!*f)
+ break;
+ if (*f == 's' || *f=='S' || *f=='R')
+ ++callcount;
+ }
+ }
+ /* step 2: allocate memory for the results of
+ * PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() calls */
+ if (callcount) {
+ callresults = PyObject_Malloc(sizeof(PyObject *)*callcount);
+ if (!callresults) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ callresult = callresults;
+ }
+ /* step 3: figure out how large a buffer we need */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ width = 0;
+ while (isdigit((unsigned)*f))
+ width = (width*10) + *f++ - '0';
+ precision = 0;
+ if (*f == '.') {
+ f++;
+ while (isdigit((unsigned)*f))
+ precision = (precision*10) + *f++ - '0';
+ }
+
+ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+ * they don't affect the amount of space we reserve.
+ */
+ if ((*f == 'l' || *f == 'z') &&
+ (f[1] == 'd' || f[1] == 'u'))
+ ++f;
+
+ switch (*f) {
+ case 'c':
+ {
+ int ordinal = va_arg(count, int);
+#ifdef Py_UNICODE_WIDE
+ if (ordinal < 0 || ordinal > 0x10ffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x110000) "
+ "(wide Python build)");
+ goto fail;
+ }
+#else
+ if (ordinal < 0 || ordinal > 0xffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x10000) "
+ "(narrow Python build)");
+ goto fail;
+ }
+#endif
+ /* fall through... */
+ }
+ case '%':
+ n++;
+ break;
+ case 'd': case 'u': case 'i': case 'x':
+ (void) va_arg(count, int);
+ if (width < precision)
+ width = precision;
+ /* 20 bytes is enough to hold a 64-bit
+ integer. Decimal takes the most space.
+ This isn't enough for octal.
+ If a width is specified we need more
+ (which we allocate later). */
+ if (width < 20)
+ width = 20;
+ n += width;
+ if (abuffersize < width)
+ abuffersize = width;
+ break;
+ case 's':
+ {
+ /* UTF-8 */
+ const char *s = va_arg(count, const char*);
+ PyObject *str = PyUnicode_DecodeUTF8(s, strlen(s), "replace");
+ if (!str)
+ goto fail;
+ n += PyUnicode_GET_SIZE(str);
+ /* Remember the str and switch to the next slot */
+ *callresult++ = str;
+ break;
+ }
+ case 'U':
+ {
+ PyObject *obj = va_arg(count, PyObject *);
+ assert(obj && PyUnicode_Check(obj));
+ n += PyUnicode_GET_SIZE(obj);
+ break;
+ }
+ case 'V':
+ {
+ PyObject *obj = va_arg(count, PyObject *);
+ const char *str = va_arg(count, const char *);
+ assert(obj || str);
+ assert(!obj || PyUnicode_Check(obj));
+ if (obj)
+ n += PyUnicode_GET_SIZE(obj);
+ else
+ n += strlen(str);
+ break;
+ }
+ case 'S':
+ {
+ PyObject *obj = va_arg(count, PyObject *);
+ PyObject *str;
+ assert(obj);
+ str = PyObject_Str(obj);
+ if (!str)
+ goto fail;
+ n += PyString_GET_SIZE(str);
+ /* Remember the str and switch to the next slot */
+ *callresult++ = str;
+ break;
+ }
+ case 'R':
+ {
+ PyObject *obj = va_arg(count, PyObject *);
+ PyObject *repr;
+ assert(obj);
+ repr = PyObject_Repr(obj);
+ if (!repr)
+ goto fail;
+ n += PyUnicode_GET_SIZE(repr);
+ /* Remember the repr and switch to the next slot */
+ *callresult++ = repr;
+ break;
+ }
+ case 'p':
+ (void) va_arg(count, int);
+ /* maximum 64-bit pointer representation:
+ * 0xffffffffffffffff
+ * so 19 characters is enough.
+ * XXX I count 18 -- what's the extra for?
+ */
+ n += 19;
+ break;
+ default:
+ /* if we stumble upon an unknown
+ formatting code, copy the rest of
+ the format string to the output
+ string. (we cannot just skip the
+ code, since there's no way to know
+ what's in the argument list) */
+ n += strlen(p);
+ goto expand;
+ }
+ } else
+ n++;
+ }
+ expand:
+ if (abuffersize > 20) {
+ /* add 1 for sprintf's trailing null byte */
+ abuffer = PyObject_Malloc(abuffersize + 1);
+ if (!abuffer) {
+ PyErr_NoMemory();
+ goto fail;
+ }
+ realbuffer = abuffer;
+ }
+ else
+ realbuffer = buffer;
+ /* step 4: fill the buffer */
+ /* Since we've analyzed how much space we need for the worst case,
+ we don't have to resize the string.
+ There can be no errors beyond this point. */
+ string = PyUnicode_FromUnicode(NULL, n);
+ if (!string)
+ goto fail;
+
+ s = PyUnicode_AS_UNICODE(string);
+ callresult = callresults;
+
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ int longflag = 0;
+ int size_tflag = 0;
+ zeropad = (*f == '0');
+ /* parse the width.precision part */
+ width = 0;
+ while (isdigit((unsigned)*f))
+ width = (width*10) + *f++ - '0';
+ precision = 0;
+ if (*f == '.') {
+ f++;
+ while (isdigit((unsigned)*f))
+ precision = (precision*10) + *f++ - '0';
+ }
+ /* handle the long flag, but only for %ld and %lu.
+ others can be added when necessary. */
+ if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) {
+ longflag = 1;
+ ++f;
+ }
+ /* handle the size_t flag. */
+ if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ size_tflag = 1;
+ ++f;
+ }
+
+ switch (*f) {
+ case 'c':
+ *s++ = va_arg(vargs, int);
+ break;
+ case 'd':
+ makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'd');
+ if (longflag)
+ sprintf(realbuffer, fmt, va_arg(vargs, long));
+ else if (size_tflag)
+ sprintf(realbuffer, fmt, va_arg(vargs, Py_ssize_t));
+ else
+ sprintf(realbuffer, fmt, va_arg(vargs, int));
+ appendstring(realbuffer);
+ break;
+ case 'u':
+ makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'u');
+ if (longflag)
+ sprintf(realbuffer, fmt, va_arg(vargs, unsigned long));
+ else if (size_tflag)
+ sprintf(realbuffer, fmt, va_arg(vargs, size_t));
+ else
+ sprintf(realbuffer, fmt, va_arg(vargs, unsigned int));
+ appendstring(realbuffer);
+ break;
+ case 'i':
+ makefmt(fmt, 0, 0, zeropad, width, precision, 'i');
+ sprintf(realbuffer, fmt, va_arg(vargs, int));
+ appendstring(realbuffer);
+ break;
+ case 'x':
+ makefmt(fmt, 0, 0, zeropad, width, precision, 'x');
+ sprintf(realbuffer, fmt, va_arg(vargs, int));
+ appendstring(realbuffer);
+ break;
+ case 's':
+ {
+ /* unused, since we already have the result */
+ (void) va_arg(vargs, char *);
+ Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(*callresult),
+ PyUnicode_GET_SIZE(*callresult));
+ s += PyUnicode_GET_SIZE(*callresult);
+ /* We're done with the unicode()/repr() => forget it */
+ Py_DECREF(*callresult);
+ /* switch to next unicode()/repr() result */
+ ++callresult;
+ break;
+ }
+ case 'U':
+ {
+ PyObject *obj = va_arg(vargs, PyObject *);
+ Py_ssize_t size = PyUnicode_GET_SIZE(obj);
+ Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
+ s += size;
+ break;
+ }
+ case 'V':
+ {
+ PyObject *obj = va_arg(vargs, PyObject *);
+ const char *str = va_arg(vargs, const char *);
+ if (obj) {
+ Py_ssize_t size = PyUnicode_GET_SIZE(obj);
+ Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
+ s += size;
+ } else {
+ appendstring(str);
+ }
+ break;
+ }
+ case 'S':
+ case 'R':
+ {
+ const char *str = PyString_AS_STRING(*callresult);
+ /* unused, since we already have the result */
+ (void) va_arg(vargs, PyObject *);
+ appendstring(str);
+ /* We're done with the unicode()/repr() => forget it */
+ Py_DECREF(*callresult);
+ /* switch to next unicode()/repr() result */
+ ++callresult;
+ break;
+ }
+ case 'p':
+ sprintf(buffer, "%p", va_arg(vargs, void*));
+ /* %p is ill-defined: ensure leading 0x. */
+ if (buffer[1] == 'X')
+ buffer[1] = 'x';
+ else if (buffer[1] != 'x') {
+ memmove(buffer+2, buffer, strlen(buffer)+1);
+ buffer[0] = '0';
+ buffer[1] = 'x';
+ }
+ appendstring(buffer);
+ break;
+ case '%':
+ *s++ = '%';
+ break;
+ default:
+ appendstring(p);
+ goto end;
+ }
+ } else
+ *s++ = *f;
+ }
+
+ end:
+ if (callresults)
+ PyObject_Free(callresults);
+ if (abuffer)
+ PyObject_Free(abuffer);
+ PyUnicode_Resize(&string, s - PyUnicode_AS_UNICODE(string));
+ return string;
+ fail:
+ if (callresults) {
+ PyObject **callresult2 = callresults;
+ while (callresult2 < callresult) {
+ Py_DECREF(*callresult2);
+ ++callresult2;
+ }
+ PyObject_Free(callresults);
+ }
+ if (abuffer)
+ PyObject_Free(abuffer);
+ return NULL;
+}
+
+#undef appendstring
+
+PyObject *
+PyUnicode_FromFormat(const char *format, ...)
+{
+ PyObject* ret;
+ va_list vargs;
+
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, format);
+#else
+ va_start(vargs);
+#endif
+ ret = PyUnicode_FromFormatV(format, vargs);
+ va_end(vargs);
+ return ret;
+}
+
+Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
+ wchar_t *w,
+ Py_ssize_t size)
+{
+ if (unicode == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ /* If possible, try to copy the 0-termination as well */
+ if (size > PyUnicode_GET_SIZE(unicode))
+ size = PyUnicode_GET_SIZE(unicode) + 1;
+
+#ifdef HAVE_USABLE_WCHAR_T
+ memcpy(w, unicode->str, size * sizeof(wchar_t));
+#else
+ {
+ register Py_UNICODE *u;
+ register Py_ssize_t i;
+ u = PyUnicode_AS_UNICODE(unicode);
+ for (i = size; i > 0; i--)
+ *w++ = *u++;
+ }
+#endif
+
+ if (size > PyUnicode_GET_SIZE(unicode))
+ return PyUnicode_GET_SIZE(unicode);
+ else
+ return size;
+}
+
+#endif
+
+PyObject *PyUnicode_FromOrdinal(int ordinal)
+{
+ Py_UNICODE s[1];
+
+#ifdef Py_UNICODE_WIDE
+ if (ordinal < 0 || ordinal > 0x10ffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "unichr() arg not in range(0x110000) "
+ "(wide Python build)");
+ return NULL;
+ }
+#else
+ if (ordinal < 0 || ordinal > 0xffff) {
+ PyErr_SetString(PyExc_ValueError,
+ "unichr() arg not in range(0x10000) "
+ "(narrow Python build)");
+ return NULL;
+ }
+#endif
+
+ s[0] = (Py_UNICODE)ordinal;
+ return PyUnicode_FromUnicode(s, 1);
+}
+
+PyObject *PyUnicode_FromObject(register PyObject *obj)
+{
+ /* XXX Perhaps we should make this API an alias of
+ PyObject_Unicode() instead ?! */
+ if (PyUnicode_CheckExact(obj)) {
+ Py_INCREF(obj);
+ return obj;
+ }
+ if (PyUnicode_Check(obj)) {
+ /* For a Unicode subtype that's not a Unicode object,
+ return a true Unicode object with the same data. */
+ return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
+ PyUnicode_GET_SIZE(obj));
+ }
+ return PyUnicode_FromEncodedObject(obj, NULL, "strict");
+}
+
+PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
+ const char *encoding,
+ const char *errors)
+{
+ const char *s = NULL;
+ Py_ssize_t len;
+ PyObject *v;
+
+ if (obj == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+#if 0
+ /* For b/w compatibility we also accept Unicode objects provided
+ that no encodings is given and then redirect to
+ PyObject_Unicode() which then applies the additional logic for
+ Unicode subclasses.
+
+ NOTE: This API should really only be used for object which
+ represent *encoded* Unicode !
+
+ */
+ if (PyUnicode_Check(obj)) {
+ if (encoding) {
+ PyErr_SetString(PyExc_TypeError,
+ "decoding Unicode is not supported");
+ return NULL;
+ }
+ return PyObject_Unicode(obj);
+ }
+#else
+ if (PyUnicode_Check(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "decoding Unicode is not supported");
+ return NULL;
+ }
+#endif
+
+ /* Coerce object */
+ if (PyString_Check(obj)) {
+ s = PyString_AS_STRING(obj);
+ len = PyString_GET_SIZE(obj);
+ }
+ else if (PyByteArray_Check(obj)) {
+ /* Python 2.x specific */
+ PyErr_Format(PyExc_TypeError,
+ "decoding bytearray is not supported");
+ return NULL;
+ }
+ else if (PyObject_AsCharBuffer(obj, &s, &len)) {
+ /* Overwrite the error message with something more useful in
+ case of a TypeError. */
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError,
+ "coercing to Unicode: need string or buffer, "
+ "%.80s found",
+ Py_TYPE(obj)->tp_name);
+ goto onError;
+ }
+
+ /* Convert to Unicode */
+ if (len == 0)
+ _Py_RETURN_UNICODE_EMPTY();
+
+ v = PyUnicode_Decode(s, len, encoding, errors);
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyUnicode_Decode(const char *s,
+ Py_ssize_t size,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *buffer = NULL, *unicode;
+
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+
+ /* Shortcuts for common default encodings */
+ if (strcmp(encoding, "utf-8") == 0)
+ return PyUnicode_DecodeUTF8(s, size, errors);
+ else if (strcmp(encoding, "latin-1") == 0)
+ return PyUnicode_DecodeLatin1(s, size, errors);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+ else if (strcmp(encoding, "mbcs") == 0)
+ return PyUnicode_DecodeMBCS(s, size, errors);
+#endif
+ else if (strcmp(encoding, "ascii") == 0)
+ return PyUnicode_DecodeASCII(s, size, errors);
+
+ /* Decode via the codec registry */
+ buffer = PyBuffer_FromMemory((void *)s, size);
+ if (buffer == NULL)
+ goto onError;
+ unicode = PyCodec_Decode(buffer, encoding, errors);
+ if (unicode == NULL)
+ goto onError;
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_Format(PyExc_TypeError,
+ "decoder did not return an unicode object (type=%.400s)",
+ Py_TYPE(unicode)->tp_name);
+ Py_DECREF(unicode);
+ goto onError;
+ }
+ Py_DECREF(buffer);
+ return unicode;
+
+ onError:
+ Py_XDECREF(buffer);
+ return NULL;
+}
+
+PyObject *PyUnicode_AsDecodedObject(PyObject *unicode,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+
+ /* Decode via the codec registry */
+ v = PyCodec_Decode(unicode, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyUnicode_Encode(const Py_UNICODE *s,
+ Py_ssize_t size,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v, *unicode;
+
+ unicode = PyUnicode_FromUnicode(s, size);
+ if (unicode == NULL)
+ return NULL;
+ v = PyUnicode_AsEncodedString(unicode, encoding, errors);
+ Py_DECREF(unicode);
+ return v;
+}
+
+PyObject *PyUnicode_AsEncodedObject(PyObject *unicode,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+
+ /* Encode via the codec registry */
+ v = PyCodec_Encode(unicode, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *v;
+
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+
+ /* Shortcuts for common default encodings */
+ if (errors == NULL) {
+ if (strcmp(encoding, "utf-8") == 0)
+ return PyUnicode_AsUTF8String(unicode);
+ else if (strcmp(encoding, "latin-1") == 0)
+ return PyUnicode_AsLatin1String(unicode);
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+ else if (strcmp(encoding, "mbcs") == 0)
+ return PyUnicode_AsMBCSString(unicode);
+#endif
+ else if (strcmp(encoding, "ascii") == 0)
+ return PyUnicode_AsASCIIString(unicode);
+ }
+
+ /* Encode via the codec registry */
+ v = PyCodec_Encode(unicode, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ if (!PyString_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a string object (type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ goto onError;
+ }
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors)
+{
+ PyObject *v = ((PyUnicodeObject *)unicode)->defenc;
+
+ if (v)
+ return v;
+ v = PyUnicode_AsEncodedString(unicode, NULL, errors);
+ if (v && errors == NULL)
+ ((PyUnicodeObject *)unicode)->defenc = v;
+ return v;
+}
+
+Py_UNICODE *PyUnicode_AsUnicode(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+ return PyUnicode_AS_UNICODE(unicode);
+
+ onError:
+ return NULL;
+}
+
+Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ goto onError;
+ }
+ return PyUnicode_GET_SIZE(unicode);
+
+ onError:
+ return -1;
+}
+
+const char *PyUnicode_GetDefaultEncoding(void)
+{
+ return unicode_default_encoding;
+}
+
+int PyUnicode_SetDefaultEncoding(const char *encoding)
+{
+ PyObject *v;
+
+ /* Make sure the encoding is valid. As side effect, this also
+ loads the encoding into the codec registry cache. */
+ v = _PyCodec_Lookup(encoding);
+ if (v == NULL)
+ goto onError;
+ Py_DECREF(v);
+ strncpy(unicode_default_encoding,
+ encoding,
+ sizeof(unicode_default_encoding) - 1);
+ return 0;
+
+ onError:
+ return -1;
+}
+
+/* error handling callback helper:
+ build arguments, call the callback and check the arguments,
+ if no exception occurred, copy the replacement to the output
+ and adjust various state variables.
+ return 0 on success, -1 on error
+*/
+
+static
+int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler,
+ const char *encoding, const char *reason,
+ const char *input, Py_ssize_t insize, Py_ssize_t *startinpos,
+ Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
+ PyUnicodeObject **output, Py_ssize_t *outpos, Py_UNICODE **outptr)
+{
+ static char *argparse = "O!n;decoding error handler must return (unicode, int) tuple";
+
+ PyObject *restuple = NULL;
+ PyObject *repunicode = NULL;
+ Py_ssize_t outsize = PyUnicode_GET_SIZE(*output);
+ Py_ssize_t requiredsize;
+ Py_ssize_t newpos;
+ Py_UNICODE *repptr;
+ Py_ssize_t repsize;
+ int res = -1;
+
+ if (*errorHandler == NULL) {
+ *errorHandler = PyCodec_LookupError(errors);
+ if (*errorHandler == NULL)
+ goto onError;
+ }
+
+ if (*exceptionObject == NULL) {
+ *exceptionObject = PyUnicodeDecodeError_Create(
+ encoding, input, insize, *startinpos, *endinpos, reason);
+ if (*exceptionObject == NULL)
+ goto onError;
+ }
+ else {
+ if (PyUnicodeDecodeError_SetStart(*exceptionObject, *startinpos))
+ goto onError;
+ if (PyUnicodeDecodeError_SetEnd(*exceptionObject, *endinpos))
+ goto onError;
+ if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
+ goto onError;
+ }
+
+ restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL);
+ if (restuple == NULL)
+ goto onError;
+ if (!PyTuple_Check(restuple)) {
+ PyErr_SetString(PyExc_TypeError, &argparse[4]);
+ goto onError;
+ }
+ if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos))
+ goto onError;
+ if (newpos<0)
+ newpos = insize+newpos;
+ if (newpos<0 || newpos>insize) {
+ PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos);
+ goto onError;
+ }
+
+ /* need more space? (at least enough for what we
+ have+the replacement+the rest of the string (starting
+ at the new input position), so we won't have to check space
+ when there are no errors in the rest of the string) */
+ repptr = PyUnicode_AS_UNICODE(repunicode);
+ repsize = PyUnicode_GET_SIZE(repunicode);
+ requiredsize = *outpos;
+ if (requiredsize > PY_SSIZE_T_MAX - repsize)
+ goto overflow;
+ requiredsize += repsize;
+ if (requiredsize > PY_SSIZE_T_MAX - (insize - newpos))
+ goto overflow;
+ requiredsize += insize - newpos;
+ if (requiredsize > outsize) {
+ if (outsize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*outsize)
+ requiredsize = 2*outsize;
+ if (_PyUnicode_Resize(output, requiredsize) < 0)
+ goto onError;
+ *outptr = PyUnicode_AS_UNICODE(*output) + *outpos;
+ }
+ *endinpos = newpos;
+ *inptr = input + newpos;
+ Py_UNICODE_COPY(*outptr, repptr, repsize);
+ *outptr += repsize;
+ *outpos += repsize;
+ /* we made it! */
+ res = 0;
+
+ onError:
+ Py_XDECREF(restuple);
+ return res;
+
+ overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "decoded result is too long for a Python string");
+ goto onError;
+}
+
+/* --- UTF-7 Codec -------------------------------------------------------- */
+
+/* See RFC2152 for details. We encode conservatively and decode liberally. */
+
+/* Three simple macros defining base-64. */
+
+/* Is c a base-64 character? */
+
+#define IS_BASE64(c) \
+ (isalnum(c) || (c) == '+' || (c) == '/')
+
+/* given that c is a base-64 character, what is its base-64 value? */
+
+#define FROM_BASE64(c) \
+ (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' : \
+ ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 26 : \
+ ((c) >= '0' && (c) <= '9') ? (c) - '0' + 52 : \
+ (c) == '+' ? 62 : 63)
+
+/* What is the base-64 character of the bottom 6 bits of n? */
+
+#define TO_BASE64(n) \
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f])
+
+/* DECODE_DIRECT: this byte encountered in a UTF-7 string should be
+ * decoded as itself. We are permissive on decoding; the only ASCII
+ * byte not decoding to itself is the + which begins a base64
+ * string. */
+
+#define DECODE_DIRECT(c) \
+ ((c) <= 127 && (c) != '+')
+
+/* The UTF-7 encoder treats ASCII characters differently according to
+ * whether they are Set D, Set O, Whitespace, or special (i.e. none of
+ * the above). See RFC2152. This array identifies these different
+ * sets:
+ * 0 : "Set D"
+ * alphanumeric and '(),-./:?
+ * 1 : "Set O"
+ * !"#$%&*;<=>@[]^_`{|}
+ * 2 : "whitespace"
+ * ht nl cr sp
+ * 3 : special (must be base64 encoded)
+ * everything else (i.e. +\~ and non-printing codes 0-8 11-12 14-31 127)
+ */
+
+static
+char utf7_category[128] = {
+/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3,
+/* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+/* sp ! " # $ % & ' ( ) * + , - . / */
+ 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 0,
+/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+/* @ A B C D E F G H I J K L M N O */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1,
+/* ` a b c d e f g h i j k l m n o */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* p q r s t u v w x y z { | } ~ del */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3,
+};
+
+/* ENCODE_DIRECT: this character should be encoded as itself. The
+ * answer depends on whether we are encoding set O as itself, and also
+ * on whether we are encoding whitespace as itself. RFC2152 makes it
+ * clear that the answers to these questions vary between
+ * applications, so this code needs to be flexible. */
+
+#define ENCODE_DIRECT(c, directO, directWS) \
+ ((c) < 128 && (c) > 0 && \
+ ((utf7_category[(c)] == 0) || \
+ (directWS && (utf7_category[(c)] == 2)) || \
+ (directO && (utf7_category[(c)] == 1))))
+
+PyObject *PyUnicode_DecodeUTF7(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ return PyUnicode_DecodeUTF7Stateful(s, size, errors, NULL);
+}
+
+/* The decoder. The only state we preserve is our read position,
+ * i.e. how many characters we have consumed. So if we end in the
+ * middle of a shift sequence we have to back off the read position
+ * and the output to the beginning of the sequence, otherwise we lose
+ * all the shift state (seen bits, number of bits seen, high
+ * surrogate). */
+
+PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ Py_ssize_t *consumed)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ const char *e;
+ PyUnicodeObject *unicode;
+ Py_UNICODE *p;
+ const char *errmsg = "";
+ int inShift = 0;
+ Py_UNICODE *shiftOutStart;
+ unsigned int base64bits = 0;
+ unsigned long base64buffer = 0;
+ Py_UNICODE surrogate = 0;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+ if (size == 0) {
+ if (consumed)
+ *consumed = 0;
+ return (PyObject *)unicode;
+ }
+
+ p = unicode->str;
+ shiftOutStart = p;
+ e = s + size;
+
+ while (s < e) {
+ Py_UNICODE ch = (unsigned char) *s;
+
+ if (inShift) { /* in a base-64 section */
+ if (IS_BASE64(ch)) { /* consume a base-64 character */
+ base64buffer = (base64buffer << 6) | FROM_BASE64(ch);
+ base64bits += 6;
+ s++;
+ if (base64bits >= 16) {
+ /* we have enough bits for a UTF-16 value */
+ Py_UNICODE outCh = (Py_UNICODE)
+ (base64buffer >> (base64bits-16));
+ base64bits -= 16;
+ base64buffer &= (1 << base64bits) - 1; /* clear high bits */
+ assert(outCh <= 0xffff);
+ if (surrogate) {
+ /* expecting a second surrogate */
+ if (outCh >= 0xDC00 && outCh <= 0xDFFF) {
+#ifdef Py_UNICODE_WIDE
+ *p++ = (((surrogate & 0x3FF)<<10)
+ | (outCh & 0x3FF)) + 0x10000;
+#else
+ *p++ = surrogate;
+ *p++ = outCh;
+#endif
+ surrogate = 0;
+ continue;
+ }
+ else {
+ *p++ = surrogate;
+ surrogate = 0;
+ }
+ }
+ if (outCh >= 0xD800 && outCh <= 0xDBFF) {
+ /* first surrogate */
+ surrogate = outCh;
+ }
+ else {
+ *p++ = outCh;
+ }
+ }
+ }
+ else { /* now leaving a base-64 section */
+ inShift = 0;
+ s++;
+ if (surrogate) {
+ *p++ = surrogate;
+ surrogate = 0;
+ }
+ if (base64bits > 0) { /* left-over bits */
+ if (base64bits >= 6) {
+ /* We've seen at least one base-64 character */
+ errmsg = "partial character in shift sequence";
+ goto utf7Error;
+ }
+ else {
+ /* Some bits remain; they should be zero */
+ if (base64buffer != 0) {
+ errmsg = "non-zero padding bits in shift sequence";
+ goto utf7Error;
+ }
+ }
+ }
+ if (ch != '-') {
+ /* '-' is absorbed; other terminating
+ characters are preserved */
+ *p++ = ch;
+ }
+ }
+ }
+ else if ( ch == '+' ) {
+ startinpos = s-starts;
+ s++; /* consume '+' */
+ if (s < e && *s == '-') { /* '+-' encodes '+' */
+ s++;
+ *p++ = '+';
+ }
+ else { /* begin base64-encoded section */
+ inShift = 1;
+ shiftOutStart = p;
+ base64bits = 0;
+ base64buffer = 0;
+ }
+ }
+ else if (DECODE_DIRECT(ch)) { /* character decodes as itself */
+ *p++ = ch;
+ s++;
+ }
+ else {
+ startinpos = s-starts;
+ s++;
+ errmsg = "unexpected special character";
+ goto utf7Error;
+ }
+ continue;
+utf7Error:
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ endinpos = s-starts;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf7", errmsg,
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
+
+ /* end of string */
+
+ if (inShift && !consumed) { /* in shift sequence, no more to follow */
+ /* if we're in an inconsistent state, that's an error */
+ if (surrogate ||
+ (base64bits >= 6) ||
+ (base64bits > 0 && base64buffer != 0)) {
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ endinpos = size;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf7", "unterminated shift sequence",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
+ }
+
+ /* return state */
+ if (consumed) {
+ if (inShift) {
+ p = shiftOutStart; /* back off output */
+ *consumed = startinpos;
+ }
+ else {
+ *consumed = s-starts;
+ }
+ }
+
+ if (_PyUnicode_Resize(&unicode, p - PyUnicode_AS_UNICODE(unicode)) < 0)
+ goto onError;
+
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)unicode;
+
+ onError:
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ Py_DECREF(unicode);
+ return NULL;
+}
+
+
+PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
+ Py_ssize_t size,
+ int base64SetO,
+ int base64WhiteSpace,
+ const char *errors)
+{
+ PyObject *v;
+ /* It might be possible to tighten this worst case */
+ Py_ssize_t allocated = 8 * size;
+ int inShift = 0;
+ Py_ssize_t i = 0;
+ unsigned int base64bits = 0;
+ unsigned long base64buffer = 0;
+ char * out;
+ char * start;
+
+ if (allocated / 8 != size)
+ return PyErr_NoMemory();
+
+ if (size == 0)
+ return PyString_FromStringAndSize(NULL, 0);
+
+ v = PyString_FromStringAndSize(NULL, allocated);
+ if (v == NULL)
+ return NULL;
+
+ start = out = PyString_AS_STRING(v);
+ for (;i < size; ++i) {
+ Py_UNICODE ch = s[i];
+
+ if (inShift) {
+ if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+ /* shifting out */
+ if (base64bits) { /* output remaining bits */
+ *out++ = TO_BASE64(base64buffer << (6-base64bits));
+ base64buffer = 0;
+ base64bits = 0;
+ }
+ inShift = 0;
+ /* Characters not in the BASE64 set implicitly unshift the sequence
+ so no '-' is required, except if the character is itself a '-' */
+ if (IS_BASE64(ch) || ch == '-') {
+ *out++ = '-';
+ }
+ *out++ = (char) ch;
+ }
+ else {
+ goto encode_char;
+ }
+ }
+ else { /* not in a shift sequence */
+ if (ch == '+') {
+ *out++ = '+';
+ *out++ = '-';
+ }
+ else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+ *out++ = (char) ch;
+ }
+ else {
+ *out++ = '+';
+ inShift = 1;
+ goto encode_char;
+ }
+ }
+ continue;
+encode_char:
+#ifdef Py_UNICODE_WIDE
+ if (ch >= 0x10000) {
+ /* code first surrogate */
+ base64bits += 16;
+ base64buffer = (base64buffer << 16) | 0xd800 | ((ch-0x10000) >> 10);
+ while (base64bits >= 6) {
+ *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+ base64bits -= 6;
+ }
+ /* prepare second surrogate */
+ ch = 0xDC00 | ((ch-0x10000) & 0x3FF);
+ }
+#endif
+ base64bits += 16;
+ base64buffer = (base64buffer << 16) | ch;
+ while (base64bits >= 6) {
+ *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+ base64bits -= 6;
+ }
+ }
+ if (base64bits)
+ *out++= TO_BASE64(base64buffer << (6-base64bits) );
+ if (inShift)
+ *out++ = '-';
+
+ if (_PyString_Resize(&v, out - start))
+ return NULL;
+ return v;
+}
+
+#undef IS_BASE64
+#undef FROM_BASE64
+#undef TO_BASE64
+#undef DECODE_DIRECT
+#undef ENCODE_DIRECT
+
+/* --- UTF-8 Codec -------------------------------------------------------- */
+
+static
+char utf8_code_length[256] = {
+ /* Map UTF-8 encoded prefix byte to sequence length. Zero means
+ illegal prefix. See RFC 3629 for details */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70-7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0-BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* C0-C1 + C2-CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* D0-DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* E0-EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0-F4 + F5-FF */
+};
+
+PyObject *PyUnicode_DecodeUTF8(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
+}
+
+PyObject *PyUnicode_DecodeUTF8Stateful(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ Py_ssize_t *consumed)
+{
+ const char *starts = s;
+ int n;
+ int k;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ const char *e;
+ PyUnicodeObject *unicode;
+ Py_UNICODE *p;
+ const char *errmsg = "";
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ /* Note: size will always be longer than the resulting Unicode
+ character count */
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+ if (size == 0) {
+ if (consumed)
+ *consumed = 0;
+ return (PyObject *)unicode;
+ }
+
+ /* Unpack UTF-8 encoded data */
+ p = unicode->str;
+ e = s + size;
+
+ while (s < e) {
+ Py_UCS4 ch = (unsigned char)*s;
+
+ if (ch < 0x80) {
+ *p++ = (Py_UNICODE)ch;
+ s++;
+ continue;
+ }
+
+ n = utf8_code_length[ch];
+
+ if (s + n > e) {
+ if (consumed)
+ break;
+ else {
+ errmsg = "unexpected end of data";
+ startinpos = s-starts;
+ endinpos = startinpos+1;
+ for (k=1; (k < size-startinpos) && ((s[k]&0xC0) == 0x80); k++)
+ endinpos++;
+ goto utf8Error;
+ }
+ }
+
+ switch (n) {
+
+ case 0:
+ errmsg = "invalid start byte";
+ startinpos = s-starts;
+ endinpos = startinpos+1;
+ goto utf8Error;
+
+ case 1:
+ errmsg = "internal error";
+ startinpos = s-starts;
+ endinpos = startinpos+1;
+ goto utf8Error;
+
+ case 2:
+ if ((s[1] & 0xc0) != 0x80) {
+ errmsg = "invalid continuation byte";
+ startinpos = s-starts;
+ endinpos = startinpos + 1;
+ goto utf8Error;
+ }
+ ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f);
+ assert ((ch > 0x007F) && (ch <= 0x07FF));
+ *p++ = (Py_UNICODE)ch;
+ break;
+
+ case 3:
+ /* XXX: surrogates shouldn't be valid UTF-8!
+ see http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf
+ (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt
+ Uncomment the 2 lines below to make them invalid,
+ code points: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ ((unsigned char)s[0] == 0xE0 &&
+ (unsigned char)s[1] < 0xA0)/* ||
+ ((unsigned char)s[0] == 0xED &&
+ (unsigned char)s[1] > 0x9F)*/) {
+ errmsg = "invalid continuation byte";
+ startinpos = s-starts;
+ endinpos = startinpos + 1;
+
+ /* if s[1] first two bits are 1 and 0, then the invalid
+ continuation byte is s[2], so increment endinpos by 1,
+ if not, s[1] is invalid and endinpos doesn't need to
+ be incremented. */
+ if ((s[1] & 0xC0) == 0x80)
+ endinpos++;
+ goto utf8Error;
+ }
+ ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f);
+ assert ((ch > 0x07FF) && (ch <= 0xFFFF));
+ *p++ = (Py_UNICODE)ch;
+ break;
+
+ case 4:
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ (s[3] & 0xc0) != 0x80 ||
+ ((unsigned char)s[0] == 0xF0 &&
+ (unsigned char)s[1] < 0x90) ||
+ ((unsigned char)s[0] == 0xF4 &&
+ (unsigned char)s[1] > 0x8F)) {
+ errmsg = "invalid continuation byte";
+ startinpos = s-starts;
+ endinpos = startinpos + 1;
+ if ((s[1] & 0xC0) == 0x80) {
+ endinpos++;
+ if ((s[2] & 0xC0) == 0x80)
+ endinpos++;
+ }
+ goto utf8Error;
+ }
+ ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) +
+ ((s[2] & 0x3f) << 6) + (s[3] & 0x3f);
+ assert ((ch > 0xFFFF) && (ch <= 0x10ffff));
+
+#ifdef Py_UNICODE_WIDE
+ *p++ = (Py_UNICODE)ch;
+#else
+ /* compute and append the two surrogates: */
+
+ /* translate from 10000..10FFFF to 0..FFFF */
+ ch -= 0x10000;
+
+ /* high surrogate = top 10 bits added to D800 */
+ *p++ = (Py_UNICODE)(0xD800 + (ch >> 10));
+
+ /* low surrogate = bottom 10 bits added to DC00 */
+ *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF));
+#endif
+ break;
+ }
+ s += n;
+ continue;
+
+ utf8Error:
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf8", errmsg,
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
+ if (consumed)
+ *consumed = s-starts;
+
+ /* Adjust length */
+ if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+ goto onError;
+
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)unicode;
+
+ onError:
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ Py_DECREF(unicode);
+ return NULL;
+}
+
+/* Allocation strategy: if the string is short, convert into a stack buffer
+ and allocate exactly as much space needed at the end. Else allocate the
+ maximum possible needed (4 result bytes per Unicode character), and return
+ the excess memory at the end.
+*/
+PyObject *
+PyUnicode_EncodeUTF8(const Py_UNICODE *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+#define MAX_SHORT_UNICHARS 300 /* largest size we'll do on the stack */
+
+ Py_ssize_t i; /* index into s of next input byte */
+ PyObject *v; /* result string object */
+ char *p; /* next free byte in output buffer */
+ Py_ssize_t nallocated; /* number of result bytes allocated */
+ Py_ssize_t nneeded; /* number of result bytes needed */
+ char stackbuf[MAX_SHORT_UNICHARS * 4];
+
+ assert(s != NULL);
+ assert(size >= 0);
+
+ if (size <= MAX_SHORT_UNICHARS) {
+ /* Write into the stack buffer; nallocated can't overflow.
+ * At the end, we'll allocate exactly as much heap space as it
+ * turns out we need.
+ */
+ nallocated = Py_SAFE_DOWNCAST(sizeof(stackbuf), size_t, int);
+ v = NULL; /* will allocate after we're done */
+ p = stackbuf;
+ }
+ else {
+ /* Overallocate on the heap, and give the excess back at the end. */
+ nallocated = size * 4;
+ if (nallocated / 4 != size) /* overflow! */
+ return PyErr_NoMemory();
+ v = PyString_FromStringAndSize(NULL, nallocated);
+ if (v == NULL)
+ return NULL;
+ p = PyString_AS_STRING(v);
+ }
+
+ for (i = 0; i < size;) {
+ Py_UCS4 ch = s[i++];
+
+ if (ch < 0x80)
+ /* Encode ASCII */
+ *p++ = (char) ch;
+
+ else if (ch < 0x0800) {
+ /* Encode Latin-1 */
+ *p++ = (char)(0xc0 | (ch >> 6));
+ *p++ = (char)(0x80 | (ch & 0x3f));
+ }
+ else {
+ /* Encode UCS2 Unicode ordinals */
+ if (ch < 0x10000) {
+ /* Special case: check for high surrogate */
+ if (0xD800 <= ch && ch <= 0xDBFF && i != size) {
+ Py_UCS4 ch2 = s[i];
+ /* Check for low surrogate and combine the two to
+ form a UCS4 value */
+ if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+ ch = ((ch - 0xD800) << 10 | (ch2 - 0xDC00)) + 0x10000;
+ i++;
+ goto encodeUCS4;
+ }
+ /* Fall through: handles isolated high surrogates */
+ }
+ *p++ = (char)(0xe0 | (ch >> 12));
+ *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+ *p++ = (char)(0x80 | (ch & 0x3f));
+ continue;
+ }
+ encodeUCS4:
+ /* Encode UCS4 Unicode ordinals */
+ *p++ = (char)(0xf0 | (ch >> 18));
+ *p++ = (char)(0x80 | ((ch >> 12) & 0x3f));
+ *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
+ *p++ = (char)(0x80 | (ch & 0x3f));
+ }
+ }
+
+ if (v == NULL) {
+ /* This was stack allocated. */
+ nneeded = p - stackbuf;
+ assert(nneeded <= nallocated);
+ v = PyString_FromStringAndSize(stackbuf, nneeded);
+ }
+ else {
+ /* Cut back to size actually needed. */
+ nneeded = p - PyString_AS_STRING(v);
+ assert(nneeded <= nallocated);
+ if (_PyString_Resize(&v, nneeded))
+ return NULL;
+ }
+ return v;
+
+#undef MAX_SHORT_UNICHARS
+}
+
+PyObject *PyUnicode_AsUTF8String(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL);
+}
+
+/* --- UTF-32 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF32(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ int *byteorder)
+{
+ return PyUnicode_DecodeUTF32Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF32Stateful(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ int *byteorder,
+ Py_ssize_t *consumed)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ PyUnicodeObject *unicode;
+ Py_UNICODE *p;
+#ifndef Py_UNICODE_WIDE
+ int pairs = 0;
+ const unsigned char *qq;
+#else
+ const int pairs = 0;
+#endif
+ const unsigned char *q, *e;
+ int bo = 0; /* assume native ordering by default */
+ const char *errmsg = "";
+ /* Offsets from q for retrieving bytes in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ int iorder[] = {0, 1, 2, 3};
+#else
+ int iorder[] = {3, 2, 1, 0};
+#endif
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ q = (unsigned char *)s;
+ e = q + size;
+
+ if (byteorder)
+ bo = *byteorder;
+
+ /* Check for BOM marks (U+FEFF) in the input and adjust current
+ byte order setting accordingly. In native mode, the leading BOM
+ mark is skipped, in all other modes, it is copied to the output
+ stream as-is (giving a ZWNBSP character). */
+ if (bo == 0) {
+ if (size >= 4) {
+ const Py_UCS4 bom = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+ (q[iorder[1]] << 8) | q[iorder[0]];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ if (bom == 0x0000FEFF) {
+ q += 4;
+ bo = -1;
+ }
+ else if (bom == 0xFFFE0000) {
+ q += 4;
+ bo = 1;
+ }
+#else
+ if (bom == 0x0000FEFF) {
+ q += 4;
+ bo = 1;
+ }
+ else if (bom == 0xFFFE0000) {
+ q += 4;
+ bo = -1;
+ }
+#endif
+ }
+ }
+
+ if (bo == -1) {
+ /* force LE */
+ iorder[0] = 0;
+ iorder[1] = 1;
+ iorder[2] = 2;
+ iorder[3] = 3;
+ }
+ else if (bo == 1) {
+ /* force BE */
+ iorder[0] = 3;
+ iorder[1] = 2;
+ iorder[2] = 1;
+ iorder[3] = 0;
+ }
+
+ /* On narrow builds we split characters outside the BMP into two
+ code points => count how much extra space we need. */
+#ifndef Py_UNICODE_WIDE
+ for (qq = q; e - qq >= 4; qq += 4)
+ if (qq[iorder[2]] != 0 || qq[iorder[3]] != 0)
+ pairs++;
+#endif
+
+ /* This might be one to much, because of a BOM */
+ unicode = _PyUnicode_New((size+3)/4+pairs);
+ if (!unicode)
+ return NULL;
+ if (size == 0)
+ return (PyObject *)unicode;
+
+ /* Unpack UTF-32 encoded data */
+ p = unicode->str;
+
+ while (q < e) {
+ Py_UCS4 ch;
+ /* remaining bytes at the end? (size should be divisible by 4) */
+ if (e-q<4) {
+ if (consumed)
+ break;
+ errmsg = "truncated data";
+ startinpos = ((const char *)q)-starts;
+ endinpos = ((const char *)e)-starts;
+ goto utf32Error;
+ /* The remaining input chars are ignored if the callback
+ chooses to skip the input */
+ }
+ ch = (q[iorder[3]] << 24) | (q[iorder[2]] << 16) |
+ (q[iorder[1]] << 8) | q[iorder[0]];
+
+ if (ch >= 0x110000)
+ {
+ errmsg = "code point not in range(0x110000)";
+ startinpos = ((const char *)q)-starts;
+ endinpos = startinpos+4;
+ goto utf32Error;
+ }
+#ifndef Py_UNICODE_WIDE
+ if (ch >= 0x10000)
+ {
+ *p++ = 0xD800 | ((ch-0x10000) >> 10);
+ *p++ = 0xDC00 | ((ch-0x10000) & 0x3FF);
+ }
+ else
+#endif
+ *p++ = ch;
+ q += 4;
+ continue;
+ utf32Error:
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf32", errmsg,
+ starts, size, &startinpos, &endinpos, &exc, (const char **)&q,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
+
+ if (byteorder)
+ *byteorder = bo;
+
+ if (consumed)
+ *consumed = (const char *)q-starts;
+
+ /* Adjust length */
+ if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+ goto onError;
+
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)unicode;
+
+ onError:
+ Py_DECREF(unicode);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF32(const Py_UNICODE *s,
+ Py_ssize_t size,
+ const char *errors,
+ int byteorder)
+{
+ PyObject *v;
+ unsigned char *p;
+ Py_ssize_t nsize, bytesize;
+#ifndef Py_UNICODE_WIDE
+ Py_ssize_t i, pairs;
+#else
+ const int pairs = 0;
+#endif
+ /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ int iorder[] = {0, 1, 2, 3};
+#else
+ int iorder[] = {3, 2, 1, 0};
+#endif
+
+#define STORECHAR(CH) \
+ do { \
+ p[iorder[3]] = ((CH) >> 24) & 0xff; \
+ p[iorder[2]] = ((CH) >> 16) & 0xff; \
+ p[iorder[1]] = ((CH) >> 8) & 0xff; \
+ p[iorder[0]] = (CH) & 0xff; \
+ p += 4; \
+ } while(0)
+
+ /* In narrow builds we can output surrogate pairs as one code point,
+ so we need less space. */
+#ifndef Py_UNICODE_WIDE
+ for (i = pairs = 0; i < size-1; i++)
+ if (0xD800 <= s[i] && s[i] <= 0xDBFF &&
+ 0xDC00 <= s[i+1] && s[i+1] <= 0xDFFF)
+ pairs++;
+#endif
+ nsize = (size - pairs + (byteorder == 0));
+ bytesize = nsize * 4;
+ if (bytesize / 4 != nsize)
+ return PyErr_NoMemory();
+ v = PyString_FromStringAndSize(NULL, bytesize);
+ if (v == NULL)
+ return NULL;
+
+ p = (unsigned char *)PyString_AS_STRING(v);
+ if (byteorder == 0)
+ STORECHAR(0xFEFF);
+ if (size == 0)
+ return v;
+
+ if (byteorder == -1) {
+ /* force LE */
+ iorder[0] = 0;
+ iorder[1] = 1;
+ iorder[2] = 2;
+ iorder[3] = 3;
+ }
+ else if (byteorder == 1) {
+ /* force BE */
+ iorder[0] = 3;
+ iorder[1] = 2;
+ iorder[2] = 1;
+ iorder[3] = 0;
+ }
+
+ while (size-- > 0) {
+ Py_UCS4 ch = *s++;
+#ifndef Py_UNICODE_WIDE
+ if (0xD800 <= ch && ch <= 0xDBFF && size > 0) {
+ Py_UCS4 ch2 = *s;
+ if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+ ch = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+ s++;
+ size--;
+ }
+ }
+#endif
+ STORECHAR(ch);
+ }
+ return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF32String(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL,
+ 0);
+}
+
+/* --- UTF-16 Codec ------------------------------------------------------- */
+
+PyObject *
+PyUnicode_DecodeUTF16(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ int *byteorder)
+{
+ return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL);
+}
+
+PyObject *
+PyUnicode_DecodeUTF16Stateful(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ int *byteorder,
+ Py_ssize_t *consumed)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ PyUnicodeObject *unicode;
+ Py_UNICODE *p;
+ const unsigned char *q, *e;
+ int bo = 0; /* assume native ordering by default */
+ const char *errmsg = "";
+ /* Offsets from q for retrieving byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ int ihi = 1, ilo = 0;
+#else
+ int ihi = 0, ilo = 1;
+#endif
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ /* Note: size will always be longer than the resulting Unicode
+ character count */
+ unicode = _PyUnicode_New(size);
+ if (!unicode)
+ return NULL;
+ if (size == 0)
+ return (PyObject *)unicode;
+
+ /* Unpack UTF-16 encoded data */
+ p = unicode->str;
+ q = (unsigned char *)s;
+ e = q + size;
+
+ if (byteorder)
+ bo = *byteorder;
+
+ /* Check for BOM marks (U+FEFF) in the input and adjust current
+ byte order setting accordingly. In native mode, the leading BOM
+ mark is skipped, in all other modes, it is copied to the output
+ stream as-is (giving a ZWNBSP character). */
+ if (bo == 0) {
+ if (size >= 2) {
+ const Py_UNICODE bom = (q[ihi] << 8) | q[ilo];
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ if (bom == 0xFEFF) {
+ q += 2;
+ bo = -1;
+ }
+ else if (bom == 0xFFFE) {
+ q += 2;
+ bo = 1;
+ }
+#else
+ if (bom == 0xFEFF) {
+ q += 2;
+ bo = 1;
+ }
+ else if (bom == 0xFFFE) {
+ q += 2;
+ bo = -1;
+ }
+#endif
+ }
+ }
+
+ if (bo == -1) {
+ /* force LE */
+ ihi = 1;
+ ilo = 0;
+ }
+ else if (bo == 1) {
+ /* force BE */
+ ihi = 0;
+ ilo = 1;
+ }
+
+ while (q < e) {
+ Py_UNICODE ch;
+ /* remaining bytes at the end? (size should be even) */
+ if (e-q<2) {
+ if (consumed)
+ break;
+ errmsg = "truncated data";
+ startinpos = ((const char *)q)-starts;
+ endinpos = ((const char *)e)-starts;
+ goto utf16Error;
+ /* The remaining input chars are ignored if the callback
+ chooses to skip the input */
+ }
+ ch = (q[ihi] << 8) | q[ilo];
+
+ q += 2;
+
+ if (ch < 0xD800 || ch > 0xDFFF) {
+ *p++ = ch;
+ continue;
+ }
+
+ /* UTF-16 code pair: */
+ if (e - q < 2) {
+ q -= 2;
+ if (consumed)
+ break;
+ errmsg = "unexpected end of data";
+ startinpos = ((const char *)q)-starts;
+ endinpos = ((const char *)e)-starts;
+ goto utf16Error;
+ }
+ if (0xD800 <= ch && ch <= 0xDBFF) {
+ Py_UNICODE ch2 = (q[ihi] << 8) | q[ilo];
+ q += 2;
+ if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+#ifndef Py_UNICODE_WIDE
+ *p++ = ch;
+ *p++ = ch2;
+#else
+ *p++ = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+#endif
+ continue;
+ }
+ else {
+ errmsg = "illegal UTF-16 surrogate";
+ startinpos = (((const char *)q)-4)-starts;
+ endinpos = startinpos+2;
+ goto utf16Error;
+ }
+
+ }
+ errmsg = "illegal encoding";
+ startinpos = (((const char *)q)-2)-starts;
+ endinpos = startinpos+2;
+ /* Fall through to report the error */
+
+ utf16Error:
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf16", errmsg,
+ starts, size, &startinpos, &endinpos, &exc, (const char **)&q,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
+
+ if (byteorder)
+ *byteorder = bo;
+
+ if (consumed)
+ *consumed = (const char *)q-starts;
+
+ /* Adjust length */
+ if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)
+ goto onError;
+
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)unicode;
+
+ onError:
+ Py_DECREF(unicode);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+PyObject *
+PyUnicode_EncodeUTF16(const Py_UNICODE *s,
+ Py_ssize_t size,
+ const char *errors,
+ int byteorder)
+{
+ PyObject *v;
+ unsigned char *p;
+ Py_ssize_t nsize, bytesize;
+#ifdef Py_UNICODE_WIDE
+ Py_ssize_t i, pairs;
+#else
+ const int pairs = 0;
+#endif
+ /* Offsets from p for storing byte pairs in the right order. */
+#ifdef BYTEORDER_IS_LITTLE_ENDIAN
+ int ihi = 1, ilo = 0;
+#else
+ int ihi = 0, ilo = 1;
+#endif
+
+#define STORECHAR(CH) \
+ do { \
+ p[ihi] = ((CH) >> 8) & 0xff; \
+ p[ilo] = (CH) & 0xff; \
+ p += 2; \
+ } while(0)
+
+#ifdef Py_UNICODE_WIDE
+ for (i = pairs = 0; i < size; i++)
+ if (s[i] >= 0x10000)
+ pairs++;
+#endif
+ /* 2 * (size + pairs + (byteorder == 0)) */
+ if (size > PY_SSIZE_T_MAX ||
+ size > PY_SSIZE_T_MAX - pairs - (byteorder == 0))
+ return PyErr_NoMemory();
+ nsize = size + pairs + (byteorder == 0);
+ bytesize = nsize * 2;
+ if (bytesize / 2 != nsize)
+ return PyErr_NoMemory();
+ v = PyString_FromStringAndSize(NULL, bytesize);
+ if (v == NULL)
+ return NULL;
+
+ p = (unsigned char *)PyString_AS_STRING(v);
+ if (byteorder == 0)
+ STORECHAR(0xFEFF);
+ if (size == 0)
+ return v;
+
+ if (byteorder == -1) {
+ /* force LE */
+ ihi = 1;
+ ilo = 0;
+ }
+ else if (byteorder == 1) {
+ /* force BE */
+ ihi = 0;
+ ilo = 1;
+ }
+
+ while (size-- > 0) {
+ Py_UNICODE ch = *s++;
+ Py_UNICODE ch2 = 0;
+#ifdef Py_UNICODE_WIDE
+ if (ch >= 0x10000) {
+ ch2 = 0xDC00 | ((ch-0x10000) & 0x3FF);
+ ch = 0xD800 | ((ch-0x10000) >> 10);
+ }
+#endif
+ STORECHAR(ch);
+ if (ch2)
+ STORECHAR(ch2);
+ }
+ return v;
+#undef STORECHAR
+}
+
+PyObject *PyUnicode_AsUTF16String(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL,
+ 0);
+}
+
+/* --- Unicode Escape Codec ----------------------------------------------- */
+
+static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
+
+PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+ const char *end;
+ char* message;
+ Py_UCS4 chr = 0xffffffff; /* in case 'getcode' messes up */
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ /* Escaped strings will always be longer than the resulting
+ Unicode string, so we start with size here and then reduce the
+ length after conversion to the true value.
+ (but if the error callback returns a long replacement string
+ we'll have to allocate more space) */
+ v = _PyUnicode_New(size);
+ if (v == NULL)
+ goto onError;
+ if (size == 0)
+ return (PyObject *)v;
+
+ p = PyUnicode_AS_UNICODE(v);
+ end = s + size;
+
+ while (s < end) {
+ unsigned char c;
+ Py_UNICODE x;
+ int digits;
+
+ /* Non-escape characters are interpreted as Unicode ordinals */
+ if (*s != '\\') {
+ *p++ = (unsigned char) *s++;
+ continue;
+ }
+
+ startinpos = s-starts;
+ /* \ - Escapes */
+ s++;
+ c = *s++;
+ if (s > end)
+ c = '\0'; /* Invalid after \ */
+ switch (c) {
+
+ /* \x escapes */
+ case '\n': break;
+ case '\\': *p++ = '\\'; break;
+ case '\'': *p++ = '\''; break;
+ case '\"': *p++ = '\"'; break;
+ case 'b': *p++ = '\b'; break;
+ case 'f': *p++ = '\014'; break; /* FF */
+ case 't': *p++ = '\t'; break;
+ case 'n': *p++ = '\n'; break;
+ case 'r': *p++ = '\r'; break;
+ case 'v': *p++ = '\013'; break; /* VT */
+ case 'a': *p++ = '\007'; break; /* BEL, not classic C */
+
+ /* \OOO (octal) escapes */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ x = s[-1] - '0';
+ if (s < end && '0' <= *s && *s <= '7') {
+ x = (x<<3) + *s++ - '0';
+ if (s < end && '0' <= *s && *s <= '7')
+ x = (x<<3) + *s++ - '0';
+ }
+ *p++ = x;
+ break;
+
+ /* hex escapes */
+ /* \xXX */
+ case 'x':
+ digits = 2;
+ message = "truncated \\xXX escape";
+ goto hexescape;
+
+ /* \uXXXX */
+ case 'u':
+ digits = 4;
+ message = "truncated \\uXXXX escape";
+ goto hexescape;
+
+ /* \UXXXXXXXX */
+ case 'U':
+ digits = 8;
+ message = "truncated \\UXXXXXXXX escape";
+ hexescape:
+ chr = 0;
+ if (end - s < digits) {
+ /* count only hex digits */
+ for (; s < end; ++s) {
+ c = (unsigned char)*s;
+ if (!Py_ISXDIGIT(c))
+ goto error;
+ }
+ goto error;
+ }
+ for (; digits--; ++s) {
+ c = (unsigned char)*s;
+ if (!Py_ISXDIGIT(c))
+ goto error;
+ chr = (chr<<4) & ~0xF;
+ if (c >= '0' && c <= '9')
+ chr += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ chr += 10 + c - 'a';
+ else
+ chr += 10 + c - 'A';
+ }
+ if (chr == 0xffffffff && PyErr_Occurred())
+ /* _decoding_error will have already written into the
+ target buffer. */
+ break;
+ store:
+ /* when we get here, chr is a 32-bit unicode character */
+ if (chr <= 0xffff)
+ /* UCS-2 character */
+ *p++ = (Py_UNICODE) chr;
+ else if (chr <= 0x10ffff) {
+ /* UCS-4 character. Either store directly, or as
+ surrogate pair. */
+#ifdef Py_UNICODE_WIDE
+ *p++ = chr;
+#else
+ chr -= 0x10000L;
+ *p++ = 0xD800 + (Py_UNICODE) (chr >> 10);
+ *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF);
+#endif
+ } else {
+ message = "illegal Unicode character";
+ goto error;
+ }
+ break;
+
+ /* \N{name} */
+ case 'N':
+ message = "malformed \\N character escape";
+ if (ucnhash_CAPI == NULL) {
+ /* load the unicode data module */
+ ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(PyUnicodeData_CAPSULE_NAME, 1);
+ if (ucnhash_CAPI == NULL)
+ goto ucnhashError;
+ }
+ if (*s == '{') {
+ const char *start = s+1;
+ /* look for the closing brace */
+ while (*s != '}' && s < end)
+ s++;
+ if (s > start && s < end && *s == '}') {
+ /* found a name. look it up in the unicode database */
+ message = "unknown Unicode character name";
+ s++;
+ if (s - start - 1 <= INT_MAX &&
+ ucnhash_CAPI->getcode(NULL, start, (int)(s-start-1), &chr))
+ goto store;
+ }
+ }
+ goto error;
+
+ default:
+ if (s > end) {
+ message = "\\ at end of string";
+ s--;
+ goto error;
+ }
+ else {
+ *p++ = '\\';
+ *p++ = (unsigned char)s[-1];
+ }
+ break;
+ }
+ continue;
+
+ error:
+ endinpos = s-starts;
+ outpos = p-PyUnicode_AS_UNICODE(v);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "unicodeescape", message,
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p))
+ goto onError;
+ continue;
+ }
+ if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+ goto onError;
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)v;
+
+ ucnhashError:
+ PyErr_SetString(
+ PyExc_UnicodeError,
+ "\\N escapes not supported (can't load unicodedata module)"
+ );
+ Py_XDECREF(v);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+
+ onError:
+ Py_XDECREF(v);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+/* Return a Unicode-Escape string version of the Unicode object.
+
+ If quotes is true, the string is enclosed in u"" or u'' quotes as
+ appropriate.
+
+*/
+
+Py_LOCAL_INLINE(const Py_UNICODE *) findchar(const Py_UNICODE *s,
+ Py_ssize_t size,
+ Py_UNICODE ch)
+{
+ /* like wcschr, but doesn't stop at NULL characters */
+
+ while (size-- > 0) {
+ if (*s == ch)
+ return s;
+ s++;
+ }
+
+ return NULL;
+}
+
+static
+PyObject *unicodeescape_string(const Py_UNICODE *s,
+ Py_ssize_t size,
+ int quotes)
+{
+ PyObject *repr;
+ char *p;
+
+ static const char *hexdigit = "0123456789abcdef";
+#ifdef Py_UNICODE_WIDE
+ const Py_ssize_t expandsize = 10;
+#else
+ const Py_ssize_t expandsize = 6;
+#endif
+
+ /* XXX(nnorwitz): rather than over-allocating, it would be
+ better to choose a different scheme. Perhaps scan the
+ first N-chars of the string and allocate based on that size.
+ */
+ /* Initial allocation is based on the longest-possible unichr
+ escape.
+
+ In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
+ unichr, so in this case it's the longest unichr escape. In
+ narrow (UTF-16) builds this is five chars per source unichr
+ since there are two unichrs in the surrogate pair, so in narrow
+ (UTF-16) builds it's not the longest unichr escape.
+
+ In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
+ so in the narrow (UTF-16) build case it's the longest unichr
+ escape.
+ */
+
+ if (size > (PY_SSIZE_T_MAX - 2 - 1) / expandsize)
+ return PyErr_NoMemory();
+
+ repr = PyString_FromStringAndSize(NULL,
+ 2
+ + expandsize*size
+ + 1);
+ if (repr == NULL)
+ return NULL;
+
+ p = PyString_AS_STRING(repr);
+
+ if (quotes) {
+ *p++ = 'u';
+ *p++ = (findchar(s, size, '\'') &&
+ !findchar(s, size, '"')) ? '"' : '\'';
+ }
+ while (size-- > 0) {
+ Py_UNICODE ch = *s++;
+
+ /* Escape quotes and backslashes */
+ if ((quotes &&
+ ch == (Py_UNICODE) PyString_AS_STRING(repr)[1]) || ch == '\\') {
+ *p++ = '\\';
+ *p++ = (char) ch;
+ continue;
+ }
+
+#ifdef Py_UNICODE_WIDE
+ /* Map 21-bit characters to '\U00xxxxxx' */
+ else if (ch >= 0x10000) {
+ *p++ = '\\';
+ *p++ = 'U';
+ *p++ = hexdigit[(ch >> 28) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 24) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 20) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 16) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 12) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 8) & 0x0000000F];
+ *p++ = hexdigit[(ch >> 4) & 0x0000000F];
+ *p++ = hexdigit[ch & 0x0000000F];
+ continue;
+ }
+#else
+ /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+ else if (ch >= 0xD800 && ch < 0xDC00) {
+ Py_UNICODE ch2;
+ Py_UCS4 ucs;
+
+ ch2 = *s++;
+ size--;
+ if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+ ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+ *p++ = '\\';
+ *p++ = 'U';
+ *p++ = hexdigit[(ucs >> 28) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 24) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 20) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 16) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 12) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 8) & 0x0000000F];
+ *p++ = hexdigit[(ucs >> 4) & 0x0000000F];
+ *p++ = hexdigit[ucs & 0x0000000F];
+ continue;
+ }
+ /* Fall through: isolated surrogates are copied as-is */
+ s--;
+ size++;
+ }
+#endif
+
+ /* Map 16-bit characters to '\uxxxx' */
+ if (ch >= 256) {
+ *p++ = '\\';
+ *p++ = 'u';
+ *p++ = hexdigit[(ch >> 12) & 0x000F];
+ *p++ = hexdigit[(ch >> 8) & 0x000F];
+ *p++ = hexdigit[(ch >> 4) & 0x000F];
+ *p++ = hexdigit[ch & 0x000F];
+ }
+
+ /* Map special whitespace to '\t', \n', '\r' */
+ else if (ch == '\t') {
+ *p++ = '\\';
+ *p++ = 't';
+ }
+ else if (ch == '\n') {
+ *p++ = '\\';
+ *p++ = 'n';
+ }
+ else if (ch == '\r') {
+ *p++ = '\\';
+ *p++ = 'r';
+ }
+
+ /* Map non-printable US ASCII to '\xhh' */
+ else if (ch < ' ' || ch >= 0x7F) {
+ *p++ = '\\';
+ *p++ = 'x';
+ *p++ = hexdigit[(ch >> 4) & 0x000F];
+ *p++ = hexdigit[ch & 0x000F];
+ }
+
+ /* Copy everything else as-is */
+ else
+ *p++ = (char) ch;
+ }
+ if (quotes)
+ *p++ = PyString_AS_STRING(repr)[1];
+
+ *p = '\0';
+ if (_PyString_Resize(&repr, p - PyString_AS_STRING(repr)))
+ return NULL;
+ return repr;
+}
+
+PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s,
+ Py_ssize_t size)
+{
+ return unicodeescape_string(s, size, 0);
+}
+
+PyObject *PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Raw Unicode Escape Codec ------------------------------------------- */
+
+PyObject *PyUnicode_DecodeRawUnicodeEscape(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+ const char *end;
+ const char *bs;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ /* Escaped strings will always be longer than the resulting
+ Unicode string, so we start with size here and then reduce the
+ length after conversion to the true value. (But decoding error
+ handler might have to resize the string) */
+ v = _PyUnicode_New(size);
+ if (v == NULL)
+ goto onError;
+ if (size == 0)
+ return (PyObject *)v;
+ p = PyUnicode_AS_UNICODE(v);
+ end = s + size;
+ while (s < end) {
+ unsigned char c;
+ Py_UCS4 x;
+ int i;
+ int count;
+
+ /* Non-escape characters are interpreted as Unicode ordinals */
+ if (*s != '\\') {
+ *p++ = (unsigned char)*s++;
+ continue;
+ }
+ startinpos = s-starts;
+
+ /* \u-escapes are only interpreted iff the number of leading
+ backslashes if odd */
+ bs = s;
+ for (;s < end;) {
+ if (*s != '\\')
+ break;
+ *p++ = (unsigned char)*s++;
+ }
+ if (((s - bs) & 1) == 0 ||
+ s >= end ||
+ (*s != 'u' && *s != 'U')) {
+ continue;
+ }
+ p--;
+ count = *s=='u' ? 4 : 8;
+ s++;
+
+ /* \uXXXX with 4 hex digits, \Uxxxxxxxx with 8 */
+ outpos = p-PyUnicode_AS_UNICODE(v);
+ for (x = 0, i = 0; i < count; ++i, ++s) {
+ c = (unsigned char)*s;
+ if (!isxdigit(c)) {
+ endinpos = s-starts;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "rawunicodeescape", "truncated \\uXXXX",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p))
+ goto onError;
+ goto nextByte;
+ }
+ x = (x<<4) & ~0xF;
+ if (c >= '0' && c <= '9')
+ x += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ x += 10 + c - 'a';
+ else
+ x += 10 + c - 'A';
+ }
+ if (x <= 0xffff)
+ /* UCS-2 character */
+ *p++ = (Py_UNICODE) x;
+ else if (x <= 0x10ffff) {
+ /* UCS-4 character. Either store directly, or as
+ surrogate pair. */
+#ifdef Py_UNICODE_WIDE
+ *p++ = (Py_UNICODE) x;
+#else
+ x -= 0x10000L;
+ *p++ = 0xD800 + (Py_UNICODE) (x >> 10);
+ *p++ = 0xDC00 + (Py_UNICODE) (x & 0x03FF);
+#endif
+ } else {
+ endinpos = s-starts;
+ outpos = p-PyUnicode_AS_UNICODE(v);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "rawunicodeescape", "\\Uxxxxxxxx out of range",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p))
+ goto onError;
+ }
+ nextByte:
+ ;
+ }
+ if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+ goto onError;
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)v;
+
+ onError:
+ Py_XDECREF(v);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
+ Py_ssize_t size)
+{
+ PyObject *repr;
+ char *p;
+ char *q;
+
+ static const char *hexdigit = "0123456789abcdef";
+#ifdef Py_UNICODE_WIDE
+ const Py_ssize_t expandsize = 10;
+#else
+ const Py_ssize_t expandsize = 6;
+#endif
+
+ if (size > PY_SSIZE_T_MAX / expandsize)
+ return PyErr_NoMemory();
+
+ repr = PyString_FromStringAndSize(NULL, expandsize * size);
+ if (repr == NULL)
+ return NULL;
+ if (size == 0)
+ return repr;
+
+ p = q = PyString_AS_STRING(repr);
+ while (size-- > 0) {
+ Py_UNICODE ch = *s++;
+#ifdef Py_UNICODE_WIDE
+ /* Map 32-bit characters to '\Uxxxxxxxx' */
+ if (ch >= 0x10000) {
+ *p++ = '\\';
+ *p++ = 'U';
+ *p++ = hexdigit[(ch >> 28) & 0xf];
+ *p++ = hexdigit[(ch >> 24) & 0xf];
+ *p++ = hexdigit[(ch >> 20) & 0xf];
+ *p++ = hexdigit[(ch >> 16) & 0xf];
+ *p++ = hexdigit[(ch >> 12) & 0xf];
+ *p++ = hexdigit[(ch >> 8) & 0xf];
+ *p++ = hexdigit[(ch >> 4) & 0xf];
+ *p++ = hexdigit[ch & 15];
+ }
+ else
+#else
+ /* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+ if (ch >= 0xD800 && ch < 0xDC00) {
+ Py_UNICODE ch2;
+ Py_UCS4 ucs;
+
+ ch2 = *s++;
+ size--;
+ if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+ ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+ *p++ = '\\';
+ *p++ = 'U';
+ *p++ = hexdigit[(ucs >> 28) & 0xf];
+ *p++ = hexdigit[(ucs >> 24) & 0xf];
+ *p++ = hexdigit[(ucs >> 20) & 0xf];
+ *p++ = hexdigit[(ucs >> 16) & 0xf];
+ *p++ = hexdigit[(ucs >> 12) & 0xf];
+ *p++ = hexdigit[(ucs >> 8) & 0xf];
+ *p++ = hexdigit[(ucs >> 4) & 0xf];
+ *p++ = hexdigit[ucs & 0xf];
+ continue;
+ }
+ /* Fall through: isolated surrogates are copied as-is */
+ s--;
+ size++;
+ }
+#endif
+ /* Map 16-bit characters to '\uxxxx' */
+ if (ch >= 256) {
+ *p++ = '\\';
+ *p++ = 'u';
+ *p++ = hexdigit[(ch >> 12) & 0xf];
+ *p++ = hexdigit[(ch >> 8) & 0xf];
+ *p++ = hexdigit[(ch >> 4) & 0xf];
+ *p++ = hexdigit[ch & 15];
+ }
+ /* Copy everything else as-is */
+ else
+ *p++ = (char) ch;
+ }
+ *p = '\0';
+ if (_PyString_Resize(&repr, p - q))
+ return NULL;
+ return repr;
+}
+
+PyObject *PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeRawUnicodeEscape(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode));
+}
+
+/* --- Unicode Internal Codec ------------------------------------------- */
+
+PyObject *_PyUnicode_DecodeUnicodeInternal(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+ const char *end;
+ const char *reason;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+#ifdef Py_UNICODE_WIDE
+ Py_UNICODE unimax = PyUnicode_GetMax();
+#endif
+
+ /* XXX overflow detection missing */
+ v = _PyUnicode_New((size+Py_UNICODE_SIZE-1)/ Py_UNICODE_SIZE);
+ if (v == NULL)
+ goto onError;
+ if (PyUnicode_GetSize((PyObject *)v) == 0)
+ return (PyObject *)v;
+ p = PyUnicode_AS_UNICODE(v);
+ end = s + size;
+
+ while (s < end) {
+ if (end-s < Py_UNICODE_SIZE) {
+ endinpos = end-starts;
+ reason = "truncated input";
+ goto error;
+ }
+ memcpy(p, s, sizeof(Py_UNICODE));
+#ifdef Py_UNICODE_WIDE
+ /* We have to sanity check the raw data, otherwise doom looms for
+ some malformed UCS-4 data. */
+ if (*p > unimax || *p < 0) {
+ endinpos = s - starts + Py_UNICODE_SIZE;
+ reason = "illegal code point (> 0x10FFFF)";
+ goto error;
+ }
+#endif
+ p++;
+ s += Py_UNICODE_SIZE;
+ continue;
+
+ error:
+ startinpos = s - starts;
+ outpos = p - PyUnicode_AS_UNICODE(v);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "unicode_internal", reason,
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p)) {
+ goto onError;
+ }
+ }
+
+ if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+ goto onError;
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)v;
+
+ onError:
+ Py_XDECREF(v);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+/* --- Latin-1 Codec ------------------------------------------------------ */
+
+PyObject *PyUnicode_DecodeLatin1(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+
+ /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */
+ if (size == 1) {
+ Py_UNICODE r = *(unsigned char*)s;
+ return PyUnicode_FromUnicode(&r, 1);
+ }
+
+ v = _PyUnicode_New(size);
+ if (v == NULL)
+ goto onError;
+ if (size == 0)
+ return (PyObject *)v;
+ p = PyUnicode_AS_UNICODE(v);
+ while (size-- > 0)
+ *p++ = (unsigned char)*s++;
+ return (PyObject *)v;
+
+ onError:
+ Py_XDECREF(v);
+ return NULL;
+}
+
+/* create or adjust a UnicodeEncodeError */
+static void make_encode_exception(PyObject **exceptionObject,
+ const char *encoding,
+ const Py_UNICODE *unicode, Py_ssize_t size,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ const char *reason)
+{
+ if (*exceptionObject == NULL) {
+ *exceptionObject = PyUnicodeEncodeError_Create(
+ encoding, unicode, size, startpos, endpos, reason);
+ }
+ else {
+ if (PyUnicodeEncodeError_SetStart(*exceptionObject, startpos))
+ goto onError;
+ if (PyUnicodeEncodeError_SetEnd(*exceptionObject, endpos))
+ goto onError;
+ if (PyUnicodeEncodeError_SetReason(*exceptionObject, reason))
+ goto onError;
+ return;
+ onError:
+ Py_CLEAR(*exceptionObject);
+ }
+}
+
+/* raises a UnicodeEncodeError */
+static void raise_encode_exception(PyObject **exceptionObject,
+ const char *encoding,
+ const Py_UNICODE *unicode, Py_ssize_t size,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ const char *reason)
+{
+ make_encode_exception(exceptionObject,
+ encoding, unicode, size, startpos, endpos, reason);
+ if (*exceptionObject != NULL)
+ PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+ build arguments, call the callback and check the arguments,
+ put the result into newpos and return the replacement string, which
+ has to be freed by the caller */
+static PyObject *unicode_encode_call_errorhandler(const char *errors,
+ PyObject **errorHandler,
+ const char *encoding, const char *reason,
+ const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ Py_ssize_t *newpos)
+{
+ static char *argparse = "O!n;encoding error handler must return (unicode, int) tuple";
+
+ PyObject *restuple;
+ PyObject *resunicode;
+
+ if (*errorHandler == NULL) {
+ *errorHandler = PyCodec_LookupError(errors);
+ if (*errorHandler == NULL)
+ return NULL;
+ }
+
+ make_encode_exception(exceptionObject,
+ encoding, unicode, size, startpos, endpos, reason);
+ if (*exceptionObject == NULL)
+ return NULL;
+
+ restuple = PyObject_CallFunctionObjArgs(
+ *errorHandler, *exceptionObject, NULL);
+ if (restuple == NULL)
+ return NULL;
+ if (!PyTuple_Check(restuple)) {
+ PyErr_SetString(PyExc_TypeError, &argparse[4]);
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+ &resunicode, newpos)) {
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ if (*newpos<0)
+ *newpos = size+*newpos;
+ if (*newpos<0 || *newpos>size) {
+ PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ Py_INCREF(resunicode);
+ Py_DECREF(restuple);
+ return resunicode;
+}
+
+static PyObject *unicode_encode_ucs1(const Py_UNICODE *p,
+ Py_ssize_t size,
+ const char *errors,
+ int limit)
+{
+ /* output object */
+ PyObject *res;
+ /* pointers to the beginning and end+1 of input */
+ const Py_UNICODE *startp = p;
+ const Py_UNICODE *endp = p + size;
+ /* pointer to the beginning of the unencodable characters */
+ /* const Py_UNICODE *badp = NULL; */
+ /* pointer into the output */
+ char *str;
+ /* current output position */
+ Py_ssize_t respos = 0;
+ Py_ssize_t ressize;
+ const char *encoding = (limit == 256) ? "latin-1" : "ascii";
+ const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)";
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+ /* the following variable is used for caching string comparisons
+ * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+ int known_errorHandler = -1;
+
+ /* allocate enough for a simple encoding without
+ replacements, if we need more, we'll resize */
+ res = PyString_FromStringAndSize(NULL, size);
+ if (res == NULL)
+ goto onError;
+ if (size == 0)
+ return res;
+ str = PyString_AS_STRING(res);
+ ressize = size;
+
+ while (p<endp) {
+ Py_UNICODE c = *p;
+
+ /* can we encode this? */
+ if (c<limit) {
+ /* no overflow check, because we know that the space is enough */
+ *str++ = (char)c;
+ ++p;
+ }
+ else {
+ Py_ssize_t unicodepos = p-startp;
+ Py_ssize_t requiredsize;
+ PyObject *repunicode;
+ Py_ssize_t repsize;
+ Py_ssize_t newpos;
+ Py_ssize_t respos;
+ Py_UNICODE *uni2;
+ /* startpos for collecting unencodable chars */
+ const Py_UNICODE *collstart = p;
+ const Py_UNICODE *collend = p;
+ /* find all unecodable characters */
+ while ((collend < endp) && ((*collend) >= limit))
+ ++collend;
+ /* cache callback name lookup (if not done yet, i.e. it's the first error) */
+ if (known_errorHandler==-1) {
+ if ((errors==NULL) || (!strcmp(errors, "strict")))
+ known_errorHandler = 1;
+ else if (!strcmp(errors, "replace"))
+ known_errorHandler = 2;
+ else if (!strcmp(errors, "ignore"))
+ known_errorHandler = 3;
+ else if (!strcmp(errors, "xmlcharrefreplace"))
+ known_errorHandler = 4;
+ else
+ known_errorHandler = 0;
+ }
+ switch (known_errorHandler) {
+ case 1: /* strict */
+ raise_encode_exception(&exc, encoding, startp, size, collstart-startp, collend-startp, reason);
+ goto onError;
+ case 2: /* replace */
+ while (collstart++ < collend)
+ *str++ = '?'; /* fall through */
+ case 3: /* ignore */
+ p = collend;
+ break;
+ case 4: /* xmlcharrefreplace */
+ respos = str - PyString_AS_STRING(res);
+ /* determine replacement size (temporarily (mis)uses p) */
+ requiredsize = respos;
+ for (p = collstart; p < collend;) {
+ Py_UCS4 ch = _Py_UNICODE_NEXT(p, collend);
+ Py_ssize_t incr;
+ if (ch < 10)
+ incr = 2+1+1;
+ else if (ch < 100)
+ incr = 2+2+1;
+ else if (ch < 1000)
+ incr = 2+3+1;
+ else if (ch < 10000)
+ incr = 2+4+1;
+ else if (ch < 100000)
+ incr = 2+5+1;
+ else if (ch < 1000000)
+ incr = 2+6+1;
+ else
+ incr = 2+7+1;
+ if (requiredsize > PY_SSIZE_T_MAX - incr)
+ goto overflow;
+ requiredsize += incr;
+ }
+ if (requiredsize > PY_SSIZE_T_MAX - (endp - collend))
+ goto overflow;
+ requiredsize += endp - collend;
+ if (requiredsize > ressize) {
+ if (ressize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*ressize)
+ requiredsize = 2*ressize;
+ if (_PyString_Resize(&res, requiredsize))
+ goto onError;
+ str = PyString_AS_STRING(res) + respos;
+ ressize = requiredsize;
+ }
+ /* generate replacement (temporarily (mis)uses p) */
+ for (p = collstart; p < collend;) {
+ Py_UCS4 ch = _Py_UNICODE_NEXT(p, collend);
+ str += sprintf(str, "&#%d;", (int)ch);
+ }
+ p = collend;
+ break;
+ default:
+ repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+ encoding, reason, startp, size, &exc,
+ collstart-startp, collend-startp, &newpos);
+ if (repunicode == NULL)
+ goto onError;
+ /* need more space? (at least enough for what we have+the
+ replacement+the rest of the string, so we won't have to
+ check space for encodable characters) */
+ respos = str - PyString_AS_STRING(res);
+ repsize = PyUnicode_GET_SIZE(repunicode);
+ if (respos > PY_SSIZE_T_MAX - repsize)
+ goto overflow;
+ requiredsize = respos + repsize;
+ if (requiredsize > PY_SSIZE_T_MAX - (endp - collend))
+ goto overflow;
+ requiredsize += endp - collend;
+ if (requiredsize > ressize) {
+ if (ressize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*ressize)
+ requiredsize = 2*ressize;
+ if (_PyString_Resize(&res, requiredsize)) {
+ Py_DECREF(repunicode);
+ goto onError;
+ }
+ str = PyString_AS_STRING(res) + respos;
+ ressize = requiredsize;
+ }
+ /* check if there is anything unencodable in the replacement
+ and copy it to the output */
+ for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2, ++str) {
+ c = *uni2;
+ if (c >= limit) {
+ raise_encode_exception(&exc, encoding, startp, size,
+ unicodepos, unicodepos+1, reason);
+ Py_DECREF(repunicode);
+ goto onError;
+ }
+ *str = (char)c;
+ }
+ p = startp + newpos;
+ Py_DECREF(repunicode);
+ }
+ }
+ }
+ /* Resize if we allocated to much */
+ respos = str - PyString_AS_STRING(res);
+ if (respos < ressize)
+ /* If this falls res will be NULL */
+ _PyString_Resize(&res, respos);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return res;
+
+ overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "encoded result is too long for a Python string");
+
+ onError:
+ Py_XDECREF(res);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p,
+ Py_ssize_t size,
+ const char *errors)
+{
+ return unicode_encode_ucs1(p, size, errors, 256);
+}
+
+PyObject *PyUnicode_AsLatin1String(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL);
+}
+
+/* --- 7-bit ASCII Codec -------------------------------------------------- */
+
+PyObject *PyUnicode_DecodeASCII(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ const char *starts = s;
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ const char *e;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+
+ /* ASCII is equivalent to the first 128 ordinals in Unicode. */
+ if (size == 1 && *(unsigned char*)s < 128) {
+ Py_UNICODE r = *(unsigned char*)s;
+ return PyUnicode_FromUnicode(&r, 1);
+ }
+
+ v = _PyUnicode_New(size);
+ if (v == NULL)
+ goto onError;
+ if (size == 0)
+ return (PyObject *)v;
+ p = PyUnicode_AS_UNICODE(v);
+ e = s + size;
+ while (s < e) {
+ register unsigned char c = (unsigned char)*s;
+ if (c < 128) {
+ *p++ = c;
+ ++s;
+ }
+ else {
+ startinpos = s-starts;
+ endinpos = startinpos + 1;
+ outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v);
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "ascii", "ordinal not in range(128)",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p))
+ goto onError;
+ }
+ }
+ if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v))
+ if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+ goto onError;
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)v;
+
+ onError:
+ Py_XDECREF(v);
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return NULL;
+}
+
+PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p,
+ Py_ssize_t size,
+ const char *errors)
+{
+ return unicode_encode_ucs1(p, size, errors, 128);
+}
+
+PyObject *PyUnicode_AsASCIIString(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL);
+}
+
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+
+/* --- MBCS codecs for Windows -------------------------------------------- */
+
+#if SIZEOF_INT < SIZEOF_SIZE_T
+#define NEED_RETRY
+#endif
+
+/* XXX This code is limited to "true" double-byte encodings, as
+ a) it assumes an incomplete character consists of a single byte, and
+ b) IsDBCSLeadByte (probably) does not work for non-DBCS multi-byte
+ encodings, see IsDBCSLeadByteEx documentation. */
+
+static int is_dbcs_lead_byte(const char *s, int offset)
+{
+ const char *curr = s + offset;
+
+ if (IsDBCSLeadByte(*curr)) {
+ const char *prev = CharPrev(s, curr);
+ return (prev == curr) || !IsDBCSLeadByte(*prev) || (curr - prev == 2);
+ }
+ return 0;
+}
+
+/*
+ * Decode MBCS string into unicode object. If 'final' is set, converts
+ * trailing lead-byte too. Returns consumed size if succeed, -1 otherwise.
+ */
+static int decode_mbcs(PyUnicodeObject **v,
+ const char *s, /* MBCS string */
+ int size, /* sizeof MBCS string */
+ int final)
+{
+ Py_UNICODE *p;
+ Py_ssize_t n = 0;
+ int usize = 0;
+
+ assert(size >= 0);
+
+ /* Skip trailing lead-byte unless 'final' is set */
+ if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1))
+ --size;
+
+ /* First get the size of the result */
+ if (size > 0) {
+ usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0);
+ if (usize == 0) {
+ PyErr_SetFromWindowsErrWithFilename(0, NULL);
+ return -1;
+ }
+ }
+
+ if (*v == NULL) {
+ /* Create unicode object */
+ *v = _PyUnicode_New(usize);
+ if (*v == NULL)
+ return -1;
+ }
+ else {
+ /* Extend unicode object */
+ n = PyUnicode_GET_SIZE(*v);
+ if (_PyUnicode_Resize(v, n + usize) < 0)
+ return -1;
+ }
+
+ /* Do the conversion */
+ if (size > 0) {
+ p = PyUnicode_AS_UNICODE(*v) + n;
+ if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) {
+ PyErr_SetFromWindowsErrWithFilename(0, NULL);
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+PyObject *PyUnicode_DecodeMBCSStateful(const char *s,
+ Py_ssize_t size,
+ const char *errors,
+ Py_ssize_t *consumed)
+{
+ PyUnicodeObject *v = NULL;
+ int done;
+
+ if (consumed)
+ *consumed = 0;
+
+#ifdef NEED_RETRY
+ retry:
+ if (size > INT_MAX)
+ done = decode_mbcs(&v, s, INT_MAX, 0);
+ else
+#endif
+ done = decode_mbcs(&v, s, (int)size, !consumed);
+
+ if (done < 0) {
+ Py_XDECREF(v);
+ return NULL;
+ }
+
+ if (consumed)
+ *consumed += done;
+
+#ifdef NEED_RETRY
+ if (size > INT_MAX) {
+ s += done;
+ size -= done;
+ goto retry;
+ }
+#endif
+
+ return (PyObject *)v;
+}
+
+PyObject *PyUnicode_DecodeMBCS(const char *s,
+ Py_ssize_t size,
+ const char *errors)
+{
+ return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL);
+}
+
+/*
+ * Convert unicode into string object (MBCS).
+ * Returns 0 if succeed, -1 otherwise.
+ */
+static int encode_mbcs(PyObject **repr,
+ const Py_UNICODE *p, /* unicode */
+ int size) /* size of unicode */
+{
+ int mbcssize = 0;
+ Py_ssize_t n = 0;
+
+ assert(size >= 0);
+
+ /* First get the size of the result */
+ if (size > 0) {
+ mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL);
+ if (mbcssize == 0) {
+ PyErr_SetFromWindowsErrWithFilename(0, NULL);
+ return -1;
+ }
+ }
+
+ if (*repr == NULL) {
+ /* Create string object */
+ *repr = PyString_FromStringAndSize(NULL, mbcssize);
+ if (*repr == NULL)
+ return -1;
+ }
+ else {
+ /* Extend string object */
+ n = PyString_Size(*repr);
+ if (_PyString_Resize(repr, n + mbcssize) < 0)
+ return -1;
+ }
+
+ /* Do the conversion */
+ if (size > 0) {
+ char *s = PyString_AS_STRING(*repr) + n;
+ if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) {
+ PyErr_SetFromWindowsErrWithFilename(0, NULL);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,
+ Py_ssize_t size,
+ const char *errors)
+{
+ PyObject *repr = NULL;
+ int ret;
+
+#ifdef NEED_RETRY
+ retry:
+ if (size > INT_MAX)
+ ret = encode_mbcs(&repr, p, INT_MAX);
+ else
+#endif
+ ret = encode_mbcs(&repr, p, (int)size);
+
+ if (ret < 0) {
+ Py_XDECREF(repr);
+ return NULL;
+ }
+
+#ifdef NEED_RETRY
+ if (size > INT_MAX) {
+ p += INT_MAX;
+ size -= INT_MAX;
+ goto retry;
+ }
+#endif
+
+ return repr;
+}
+
+PyObject *PyUnicode_AsMBCSString(PyObject *unicode)
+{
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL);
+}
+
+#undef NEED_RETRY
+
+#endif /* MS_WINDOWS */
+
+/* --- Character Mapping Codec -------------------------------------------- */
+
+PyObject *PyUnicode_DecodeCharmap(const char *s,
+ Py_ssize_t size,
+ PyObject *mapping,
+ const char *errors)
+{
+ const char *starts = s;
+ Py_ssize_t startinpos;
+ Py_ssize_t endinpos;
+ Py_ssize_t outpos;
+ const char *e;
+ PyUnicodeObject *v;
+ Py_UNICODE *p;
+ Py_ssize_t extrachars = 0;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+ Py_UNICODE *mapstring = NULL;
+ Py_ssize_t maplen = 0;
+
+ /* Default to Latin-1 */
+ if (mapping == NULL)
+ return PyUnicode_DecodeLatin1(s, size, errors);
+
+ v = _PyUnicode_New(size);
+ if (v == NULL)
+ goto onError;
+ if (size == 0)
+ return (PyObject *)v;
+ p = PyUnicode_AS_UNICODE(v);
+ e = s + size;
+ if (PyUnicode_CheckExact(mapping)) {
+ mapstring = PyUnicode_AS_UNICODE(mapping);
+ maplen = PyUnicode_GET_SIZE(mapping);
+ while (s < e) {
+ unsigned char ch = *s;
+ Py_UNICODE x = 0xfffe; /* illegal value */
+
+ if (ch < maplen)
+ x = mapstring[ch];
+
+ if (x == 0xfffe) {
+ /* undefined mapping */
+ outpos = p-PyUnicode_AS_UNICODE(v);
+ startinpos = s-starts;
+ endinpos = startinpos+1;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "charmap", "character maps to <undefined>",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p)) {
+ goto onError;
+ }
+ continue;
+ }
+ *p++ = x;
+ ++s;
+ }
+ }
+ else {
+ while (s < e) {
+ unsigned char ch = *s;
+ PyObject *w, *x;
+
+ /* Get mapping (char ordinal -> integer, Unicode char or None) */
+ w = PyInt_FromLong((long)ch);
+ if (w == NULL)
+ goto onError;
+ x = PyObject_GetItem(mapping, w);
+ Py_DECREF(w);
+ if (x == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+ /* No mapping found means: mapping is undefined. */
+ PyErr_Clear();
+ goto Undefined;
+ } else
+ goto onError;
+ }
+
+ /* Apply mapping */
+ if (x == Py_None)
+ goto Undefined;
+ if (PyInt_Check(x)) {
+ long value = PyInt_AS_LONG(x);
+ if (value == 0xFFFE)
+ goto Undefined;
+ if (value < 0 || value > 0x10FFFF) {
+ PyErr_SetString(PyExc_TypeError,
+ "character mapping must be in range(0x110000)");
+ Py_DECREF(x);
+ goto onError;
+ }
+
+#ifndef Py_UNICODE_WIDE
+ if (value > 0xFFFF) {
+ /* see the code for 1-n mapping below */
+ if (extrachars < 2) {
+ /* resize first */
+ Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);
+ Py_ssize_t needed = 10 - extrachars;
+ extrachars += needed;
+ /* XXX overflow detection missing */
+ if (_PyUnicode_Resize(&v,
+ PyUnicode_GET_SIZE(v) + needed) < 0) {
+ Py_DECREF(x);
+ goto onError;
+ }
+ p = PyUnicode_AS_UNICODE(v) + oldpos;
+ }
+ value -= 0x10000;
+ *p++ = 0xD800 | (value >> 10);
+ *p++ = 0xDC00 | (value & 0x3FF);
+ extrachars -= 2;
+ }
+ else
+#endif
+ *p++ = (Py_UNICODE)value;
+ }
+ else if (PyUnicode_Check(x)) {
+ Py_ssize_t targetsize = PyUnicode_GET_SIZE(x);
+
+ if (targetsize == 1) {
+ /* 1-1 mapping */
+ Py_UNICODE value = *PyUnicode_AS_UNICODE(x);
+ if (value == 0xFFFE)
+ goto Undefined;
+ *p++ = value;
+ }
+ else if (targetsize > 1) {
+ /* 1-n mapping */
+ if (targetsize > extrachars) {
+ /* resize first */
+ Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);
+ Py_ssize_t needed = (targetsize - extrachars) + \
+ (targetsize << 2);
+ extrachars += needed;
+ /* XXX overflow detection missing */
+ if (_PyUnicode_Resize(&v,
+ PyUnicode_GET_SIZE(v) + needed) < 0) {
+ Py_DECREF(x);
+ goto onError;
+ }
+ p = PyUnicode_AS_UNICODE(v) + oldpos;
+ }
+ Py_UNICODE_COPY(p,
+ PyUnicode_AS_UNICODE(x),
+ targetsize);
+ p += targetsize;
+ extrachars -= targetsize;
+ }
+ /* 1-0 mapping: skip the character */
+ }
+ else {
+ /* wrong return value */
+ PyErr_SetString(PyExc_TypeError,
+ "character mapping must return integer, None or unicode");
+ Py_DECREF(x);
+ goto onError;
+ }
+ Py_DECREF(x);
+ ++s;
+ continue;
+Undefined:
+ /* undefined mapping */
+ Py_XDECREF(x);
+ outpos = p-PyUnicode_AS_UNICODE(v);
+ startinpos = s-starts;
+ endinpos = startinpos+1;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "charmap", "character maps to <undefined>",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &v, &outpos, &p)) {
+ goto onError;
+ }
+ }
+ }
+ if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v))
+ if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)
+ goto onError;
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ return (PyObject *)v;
+
+ onError:
+ Py_XDECREF(errorHandler);
+ Py_XDECREF(exc);
+ Py_XDECREF(v);
+ return NULL;
+}
+
+/* Charmap encoding: the lookup table */
+
+struct encoding_map{
+ PyObject_HEAD
+ unsigned char level1[32];
+ int count2, count3;
+ unsigned char level23[1];
+};
+
+static PyObject*
+encoding_map_size(PyObject *obj, PyObject* args)
+{
+ struct encoding_map *map = (struct encoding_map*)obj;
+ return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 +
+ 128*map->count3);
+}
+
+static PyMethodDef encoding_map_methods[] = {
+ {"size", encoding_map_size, METH_NOARGS,
+ PyDoc_STR("Return the size (in bytes) of this object") },
+ { 0 }
+};
+
+static void
+encoding_map_dealloc(PyObject* o)
+{
+ PyObject_FREE(o);
+}
+
+static PyTypeObject EncodingMapType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "EncodingMap", /*tp_name*/
+ sizeof(struct encoding_map), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ encoding_map_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ encoding_map_methods, /*tp_methods*/
+ 0, /*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*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+};
+
+PyObject*
+PyUnicode_BuildEncodingMap(PyObject* string)
+{
+ Py_UNICODE *decode;
+ PyObject *result;
+ struct encoding_map *mresult;
+ int i;
+ int need_dict = 0;
+ unsigned char level1[32];
+ unsigned char level2[512];
+ unsigned char *mlevel1, *mlevel2, *mlevel3;
+ int count2 = 0, count3 = 0;
+
+ if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ decode = PyUnicode_AS_UNICODE(string);
+ memset(level1, 0xFF, sizeof level1);
+ memset(level2, 0xFF, sizeof level2);
+
+ /* If there isn't a one-to-one mapping of NULL to \0,
+ or if there are non-BMP characters, we need to use
+ a mapping dictionary. */
+ if (decode[0] != 0)
+ need_dict = 1;
+ for (i = 1; i < 256; i++) {
+ int l1, l2;
+ if (decode[i] == 0
+#ifdef Py_UNICODE_WIDE
+ || decode[i] > 0xFFFF
+#endif
+ ) {
+ need_dict = 1;
+ break;
+ }
+ if (decode[i] == 0xFFFE)
+ /* unmapped character */
+ continue;
+ l1 = decode[i] >> 11;
+ l2 = decode[i] >> 7;
+ if (level1[l1] == 0xFF)
+ level1[l1] = count2++;
+ if (level2[l2] == 0xFF)
+ level2[l2] = count3++;
+ }
+
+ if (count2 >= 0xFF || count3 >= 0xFF)
+ need_dict = 1;
+
+ if (need_dict) {
+ PyObject *result = PyDict_New();
+ PyObject *key, *value;
+ if (!result)
+ return NULL;
+ for (i = 0; i < 256; i++) {
+ value = NULL;
+ key = PyInt_FromLong(decode[i]);
+ value = PyInt_FromLong(i);
+ if (!key || !value)
+ goto failed1;
+ if (PyDict_SetItem(result, key, value) == -1)
+ goto failed1;
+ Py_DECREF(key);
+ Py_DECREF(value);
+ }
+ return result;
+ failed1:
+ Py_XDECREF(key);
+ Py_XDECREF(value);
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ /* Create a three-level trie */
+ result = PyObject_MALLOC(sizeof(struct encoding_map) +
+ 16*count2 + 128*count3 - 1);
+ if (!result)
+ return PyErr_NoMemory();
+ PyObject_Init(result, &EncodingMapType);
+ mresult = (struct encoding_map*)result;
+ mresult->count2 = count2;
+ mresult->count3 = count3;
+ mlevel1 = mresult->level1;
+ mlevel2 = mresult->level23;
+ mlevel3 = mresult->level23 + 16*count2;
+ memcpy(mlevel1, level1, 32);
+ memset(mlevel2, 0xFF, 16*count2);
+ memset(mlevel3, 0, 128*count3);
+ count3 = 0;
+ for (i = 1; i < 256; i++) {
+ int o1, o2, o3, i2, i3;
+ if (decode[i] == 0xFFFE)
+ /* unmapped character */
+ continue;
+ o1 = decode[i]>>11;
+ o2 = (decode[i]>>7) & 0xF;
+ i2 = 16*mlevel1[o1] + o2;
+ if (mlevel2[i2] == 0xFF)
+ mlevel2[i2] = count3++;
+ o3 = decode[i] & 0x7F;
+ i3 = 128*mlevel2[i2] + o3;
+ mlevel3[i3] = i;
+ }
+ return result;
+}
+
+static int
+encoding_map_lookup(Py_UNICODE c, PyObject *mapping)
+{
+ struct encoding_map *map = (struct encoding_map*)mapping;
+ int l1 = c>>11;
+ int l2 = (c>>7) & 0xF;
+ int l3 = c & 0x7F;
+ int i;
+
+#ifdef Py_UNICODE_WIDE
+ if (c > 0xFFFF) {
+ return -1;
+ }
+#endif
+ if (c == 0)
+ return 0;
+ /* level 1*/
+ i = map->level1[l1];
+ if (i == 0xFF) {
+ return -1;
+ }
+ /* level 2*/
+ i = map->level23[16*i+l2];
+ if (i == 0xFF) {
+ return -1;
+ }
+ /* level 3 */
+ i = map->level23[16*map->count2 + 128*i + l3];
+ if (i == 0) {
+ return -1;
+ }
+ return i;
+}
+
+/* Lookup the character ch in the mapping. If the character
+ can't be found, Py_None is returned (or NULL, if another
+ error occurred). */
+static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping)
+{
+ PyObject *w = PyInt_FromLong((long)c);
+ PyObject *x;
+
+ if (w == NULL)
+ return NULL;
+ x = PyObject_GetItem(mapping, w);
+ Py_DECREF(w);
+ if (x == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+ /* No mapping found means: mapping is undefined. */
+ PyErr_Clear();
+ x = Py_None;
+ Py_INCREF(x);
+ return x;
+ } else
+ return NULL;
+ }
+ else if (x == Py_None)
+ return x;
+ else if (PyInt_Check(x)) {
+ long value = PyInt_AS_LONG(x);
+ if (value < 0 || value > 255) {
+ PyErr_SetString(PyExc_TypeError,
+ "character mapping must be in range(256)");
+ Py_DECREF(x);
+ return NULL;
+ }
+ return x;
+ }
+ else if (PyString_Check(x))
+ return x;
+ else {
+ /* wrong return value */
+ PyErr_SetString(PyExc_TypeError,
+ "character mapping must return integer, None or str");
+ Py_DECREF(x);
+ return NULL;
+ }
+}
+
+static int
+charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
+{
+ Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+ /* exponentially overallocate to minimize reallocations */
+ if (requiredsize < 2*outsize)
+ requiredsize = 2*outsize;
+ if (_PyString_Resize(outobj, requiredsize)) {
+ return 0;
+ }
+ return 1;
+}
+
+typedef enum charmapencode_result {
+ enc_SUCCESS, enc_FAILED, enc_EXCEPTION
+}charmapencode_result;
+/* lookup the character, put the result in the output string and adjust
+ various state variables. Reallocate the output string if not enough
+ space is available. Return a new reference to the object that
+ was put in the output buffer, or Py_None, if the mapping was undefined
+ (in which case no character was written) or NULL, if a
+ reallocation error occurred. The caller must decref the result */
+static
+charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
+ PyObject **outobj, Py_ssize_t *outpos)
+{
+ PyObject *rep;
+ char *outstart;
+ Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
+
+ if (Py_TYPE(mapping) == &EncodingMapType) {
+ int res = encoding_map_lookup(c, mapping);
+ Py_ssize_t requiredsize = *outpos+1;
+ if (res == -1)
+ return enc_FAILED;
+ if (outsize<requiredsize)
+ if (!charmapencode_resize(outobj, outpos, requiredsize))
+ return enc_EXCEPTION;
+ outstart = PyString_AS_STRING(*outobj);
+ outstart[(*outpos)++] = (char)res;
+ return enc_SUCCESS;
+ }
+
+ rep = charmapencode_lookup(c, mapping);
+ if (rep==NULL)
+ return enc_EXCEPTION;
+ else if (rep==Py_None) {
+ Py_DECREF(rep);
+ return enc_FAILED;
+ } else {
+ if (PyInt_Check(rep)) {
+ Py_ssize_t requiredsize = *outpos+1;
+ if (outsize<requiredsize)
+ if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+ Py_DECREF(rep);
+ return enc_EXCEPTION;
+ }
+ outstart = PyString_AS_STRING(*outobj);
+ outstart[(*outpos)++] = (char)PyInt_AS_LONG(rep);
+ }
+ else {
+ const char *repchars = PyString_AS_STRING(rep);
+ Py_ssize_t repsize = PyString_GET_SIZE(rep);
+ Py_ssize_t requiredsize = *outpos+repsize;
+ if (outsize<requiredsize)
+ if (!charmapencode_resize(outobj, outpos, requiredsize)) {
+ Py_DECREF(rep);
+ return enc_EXCEPTION;
+ }
+ outstart = PyString_AS_STRING(*outobj);
+ memcpy(outstart + *outpos, repchars, repsize);
+ *outpos += repsize;
+ }
+ }
+ Py_DECREF(rep);
+ return enc_SUCCESS;
+}
+
+/* handle an error in PyUnicode_EncodeCharmap
+ Return 0 on success, -1 on error */
+static
+int charmap_encoding_error(
+ const Py_UNICODE *p, Py_ssize_t size, Py_ssize_t *inpos, PyObject *mapping,
+ PyObject **exceptionObject,
+ int *known_errorHandler, PyObject **errorHandler, const char *errors,
+ PyObject **res, Py_ssize_t *respos)
+{
+ PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+ Py_ssize_t repsize;
+ Py_ssize_t newpos;
+ Py_UNICODE *uni2;
+ /* startpos for collecting unencodable chars */
+ Py_ssize_t collstartpos = *inpos;
+ Py_ssize_t collendpos = *inpos+1;
+ Py_ssize_t collpos;
+ char *encoding = "charmap";
+ char *reason = "character maps to <undefined>";
+ charmapencode_result x;
+
+ /* find all unencodable characters */
+ while (collendpos < size) {
+ PyObject *rep;
+ if (Py_TYPE(mapping) == &EncodingMapType) {
+ int res = encoding_map_lookup(p[collendpos], mapping);
+ if (res != -1)
+ break;
+ ++collendpos;
+ continue;
+ }
+
+ rep = charmapencode_lookup(p[collendpos], mapping);
+ if (rep==NULL)
+ return -1;
+ else if (rep!=Py_None) {
+ Py_DECREF(rep);
+ break;
+ }
+ Py_DECREF(rep);
+ ++collendpos;
+ }
+ /* cache callback name lookup
+ * (if not done yet, i.e. it's the first error) */
+ if (*known_errorHandler==-1) {
+ if ((errors==NULL) || (!strcmp(errors, "strict")))
+ *known_errorHandler = 1;
+ else if (!strcmp(errors, "replace"))
+ *known_errorHandler = 2;
+ else if (!strcmp(errors, "ignore"))
+ *known_errorHandler = 3;
+ else if (!strcmp(errors, "xmlcharrefreplace"))
+ *known_errorHandler = 4;
+ else
+ *known_errorHandler = 0;
+ }
+ switch (*known_errorHandler) {
+ case 1: /* strict */
+ raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+ return -1;
+ case 2: /* replace */
+ for (collpos = collstartpos; collpos<collendpos; ++collpos) {
+ x = charmapencode_output('?', mapping, res, respos);
+ if (x==enc_EXCEPTION) {
+ return -1;
+ }
+ else if (x==enc_FAILED) {
+ raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+ return -1;
+ }
+ }
+ /* fall through */
+ case 3: /* ignore */
+ *inpos = collendpos;
+ break;
+ case 4: /* xmlcharrefreplace */
+ /* generate replacement */
+ for (collpos = collstartpos; collpos < collendpos;) {
+ char buffer[2+29+1+1];
+ char *cp;
+ Py_UCS4 ch = p[collpos++];
+#ifndef Py_UNICODE_WIDE
+ if ((0xD800 <= ch && ch <= 0xDBFF) &&
+ (collpos < collendpos) &&
+ (0xDC00 <= p[collpos] && p[collpos] <= 0xDFFF)) {
+ ch = ((((ch & 0x03FF) << 10) |
+ ((Py_UCS4)p[collpos++] & 0x03FF)) + 0x10000);
+ }
+#endif
+ sprintf(buffer, "&#%d;", (int)ch);
+ for (cp = buffer; *cp; ++cp) {
+ x = charmapencode_output(*cp, mapping, res, respos);
+ if (x==enc_EXCEPTION)
+ return -1;
+ else if (x==enc_FAILED) {
+ raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+ return -1;
+ }
+ }
+ }
+ *inpos = collendpos;
+ break;
+ default:
+ repunicode = unicode_encode_call_errorhandler(errors, errorHandler,
+ encoding, reason, p, size, exceptionObject,
+ collstartpos, collendpos, &newpos);
+ if (repunicode == NULL)
+ return -1;
+ /* generate replacement */
+ repsize = PyUnicode_GET_SIZE(repunicode);
+ for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+ x = charmapencode_output(*uni2, mapping, res, respos);
+ if (x==enc_EXCEPTION) {
+ return -1;
+ }
+ else if (x==enc_FAILED) {
+ Py_DECREF(repunicode);
+ raise_encode_exception(exceptionObject, encoding, p, size, collstartpos, collendpos, reason);
+ return -1;
+ }
+ }
+ *inpos = newpos;
+ Py_DECREF(repunicode);
+ }
+ return 0;
+}
+
+PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
+ Py_ssize_t size,
+ PyObject *mapping,
+ const char *errors)
+{
+ /* output object */
+ PyObject *res = NULL;
+ /* current input position */
+ Py_ssize_t inpos = 0;
+ /* current output position */
+ Py_ssize_t respos = 0;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+ /* the following variable is used for caching string comparisons
+ * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+ * 3=ignore, 4=xmlcharrefreplace */
+ int known_errorHandler = -1;
+
+ /* Default to Latin-1 */
+ if (mapping == NULL)
+ return PyUnicode_EncodeLatin1(p, size, errors);
+
+ /* allocate enough for a simple encoding without
+ replacements, if we need more, we'll resize */
+ res = PyString_FromStringAndSize(NULL, size);
+ if (res == NULL)
+ goto onError;
+ if (size == 0)
+ return res;
+
+ while (inpos<size) {
+ /* try to encode it */
+ charmapencode_result x = charmapencode_output(p[inpos], mapping, &res, &respos);
+ if (x==enc_EXCEPTION) /* error */
+ goto onError;
+ if (x==enc_FAILED) { /* unencodable character */
+ if (charmap_encoding_error(p, size, &inpos, mapping,
+ &exc,
+ &known_errorHandler, &errorHandler, errors,
+ &res, &respos)) {
+ goto onError;
+ }
+ }
+ else
+ /* done with this character => adjust input position */
+ ++inpos;
+ }
+
+ /* Resize if we allocated to much */
+ if (respos<PyString_GET_SIZE(res)) {
+ if (_PyString_Resize(&res, respos))
+ goto onError;
+ }
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return res;
+
+ onError:
+ Py_XDECREF(res);
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return NULL;
+}
+
+PyObject *PyUnicode_AsCharmapString(PyObject *unicode,
+ PyObject *mapping)
+{
+ if (!PyUnicode_Check(unicode) || mapping == NULL) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ return PyUnicode_EncodeCharmap(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ mapping,
+ NULL);
+}
+
+/* create or adjust a UnicodeTranslateError */
+static void make_translate_exception(PyObject **exceptionObject,
+ const Py_UNICODE *unicode, Py_ssize_t size,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ const char *reason)
+{
+ if (*exceptionObject == NULL) {
+ *exceptionObject = PyUnicodeTranslateError_Create(
+ unicode, size, startpos, endpos, reason);
+ }
+ else {
+ if (PyUnicodeTranslateError_SetStart(*exceptionObject, startpos))
+ goto onError;
+ if (PyUnicodeTranslateError_SetEnd(*exceptionObject, endpos))
+ goto onError;
+ if (PyUnicodeTranslateError_SetReason(*exceptionObject, reason))
+ goto onError;
+ return;
+ onError:
+ Py_CLEAR(*exceptionObject);
+ }
+}
+
+/* raises a UnicodeTranslateError */
+static void raise_translate_exception(PyObject **exceptionObject,
+ const Py_UNICODE *unicode, Py_ssize_t size,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ const char *reason)
+{
+ make_translate_exception(exceptionObject,
+ unicode, size, startpos, endpos, reason);
+ if (*exceptionObject != NULL)
+ PyCodec_StrictErrors(*exceptionObject);
+}
+
+/* error handling callback helper:
+ build arguments, call the callback and check the arguments,
+ put the result into newpos and return the replacement string, which
+ has to be freed by the caller */
+static PyObject *unicode_translate_call_errorhandler(const char *errors,
+ PyObject **errorHandler,
+ const char *reason,
+ const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ Py_ssize_t *newpos)
+{
+ static char *argparse = "O!n;translating error handler must return (unicode, int) tuple";
+
+ Py_ssize_t i_newpos;
+ PyObject *restuple;
+ PyObject *resunicode;
+
+ if (*errorHandler == NULL) {
+ *errorHandler = PyCodec_LookupError(errors);
+ if (*errorHandler == NULL)
+ return NULL;
+ }
+
+ make_translate_exception(exceptionObject,
+ unicode, size, startpos, endpos, reason);
+ if (*exceptionObject == NULL)
+ return NULL;
+
+ restuple = PyObject_CallFunctionObjArgs(
+ *errorHandler, *exceptionObject, NULL);
+ if (restuple == NULL)
+ return NULL;
+ if (!PyTuple_Check(restuple)) {
+ PyErr_SetString(PyExc_TypeError, &argparse[4]);
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type,
+ &resunicode, &i_newpos)) {
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ if (i_newpos<0)
+ *newpos = size+i_newpos;
+ else
+ *newpos = i_newpos;
+ if (*newpos<0 || *newpos>size) {
+ PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
+ Py_DECREF(restuple);
+ return NULL;
+ }
+ Py_INCREF(resunicode);
+ Py_DECREF(restuple);
+ return resunicode;
+}
+
+/* Lookup the character ch in the mapping and put the result in result,
+ which must be decrefed by the caller.
+ Return 0 on success, -1 on error */
+static
+int charmaptranslate_lookup(Py_UNICODE c, PyObject *mapping, PyObject **result)
+{
+ PyObject *w = PyInt_FromLong((long)c);
+ PyObject *x;
+
+ if (w == NULL)
+ return -1;
+ x = PyObject_GetItem(mapping, w);
+ Py_DECREF(w);
+ if (x == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_LookupError)) {
+ /* No mapping found means: use 1:1 mapping. */
+ PyErr_Clear();
+ *result = NULL;
+ return 0;
+ } else
+ return -1;
+ }
+ else if (x == Py_None) {
+ *result = x;
+ return 0;
+ }
+ else if (PyInt_Check(x)) {
+ long value = PyInt_AS_LONG(x);
+ long max = PyUnicode_GetMax();
+ if (value < 0 || value > max) {
+ PyErr_Format(PyExc_TypeError,
+ "character mapping must be in range(0x%lx)", max+1);
+ Py_DECREF(x);
+ return -1;
+ }
+ *result = x;
+ return 0;
+ }
+ else if (PyUnicode_Check(x)) {
+ *result = x;
+ return 0;
+ }
+ else {
+ /* wrong return value */
+ PyErr_SetString(PyExc_TypeError,
+ "character mapping must return integer, None or unicode");
+ Py_DECREF(x);
+ return -1;
+ }
+}
+/* ensure that *outobj is at least requiredsize characters long,
+ if not reallocate and adjust various state variables.
+ Return 0 on success, -1 on error */
+static
+int charmaptranslate_makespace(PyObject **outobj, Py_UNICODE **outp,
+ Py_ssize_t requiredsize)
+{
+ Py_ssize_t oldsize = PyUnicode_GET_SIZE(*outobj);
+ if (requiredsize > oldsize) {
+ /* remember old output position */
+ Py_ssize_t outpos = *outp-PyUnicode_AS_UNICODE(*outobj);
+ /* exponentially overallocate to minimize reallocations */
+ if (requiredsize < 2 * oldsize)
+ requiredsize = 2 * oldsize;
+ if (PyUnicode_Resize(outobj, requiredsize) < 0)
+ return -1;
+ *outp = PyUnicode_AS_UNICODE(*outobj) + outpos;
+ }
+ return 0;
+}
+/* lookup the character, put the result in the output string and adjust
+ various state variables. Return a new reference to the object that
+ was put in the output buffer in *result, or Py_None, if the mapping was
+ undefined (in which case no character was written).
+ The called must decref result.
+ Return 0 on success, -1 on error. */
+static
+int charmaptranslate_output(const Py_UNICODE *startinp, const Py_UNICODE *curinp,
+ Py_ssize_t insize, PyObject *mapping, PyObject **outobj, Py_UNICODE **outp,
+ PyObject **res)
+{
+ if (charmaptranslate_lookup(*curinp, mapping, res))
+ return -1;
+ if (*res==NULL) {
+ /* not found => default to 1:1 mapping */
+ *(*outp)++ = *curinp;
+ }
+ else if (*res==Py_None)
+ ;
+ else if (PyInt_Check(*res)) {
+ /* no overflow check, because we know that the space is enough */
+ *(*outp)++ = (Py_UNICODE)PyInt_AS_LONG(*res);
+ }
+ else if (PyUnicode_Check(*res)) {
+ Py_ssize_t repsize = PyUnicode_GET_SIZE(*res);
+ if (repsize==1) {
+ /* no overflow check, because we know that the space is enough */
+ *(*outp)++ = *PyUnicode_AS_UNICODE(*res);
+ }
+ else if (repsize!=0) {
+ /* more than one character */
+ Py_ssize_t requiredsize = (*outp-PyUnicode_AS_UNICODE(*outobj)) +
+ (insize - (curinp-startinp)) +
+ repsize - 1;
+ if (charmaptranslate_makespace(outobj, outp, requiredsize))
+ return -1;
+ memcpy(*outp, PyUnicode_AS_UNICODE(*res), sizeof(Py_UNICODE)*repsize);
+ *outp += repsize;
+ }
+ }
+ else
+ return -1;
+ return 0;
+}
+
+PyObject *PyUnicode_TranslateCharmap(const Py_UNICODE *p,
+ Py_ssize_t size,
+ PyObject *mapping,
+ const char *errors)
+{
+ /* output object */
+ PyObject *res = NULL;
+ /* pointers to the beginning and end+1 of input */
+ const Py_UNICODE *startp = p;
+ const Py_UNICODE *endp = p + size;
+ /* pointer into the output */
+ Py_UNICODE *str;
+ /* current output position */
+ Py_ssize_t respos = 0;
+ char *reason = "character maps to <undefined>";
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+ /* the following variable is used for caching string comparisons
+ * -1=not initialized, 0=unknown, 1=strict, 2=replace,
+ * 3=ignore, 4=xmlcharrefreplace */
+ int known_errorHandler = -1;
+
+ if (mapping == NULL) {
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ /* allocate enough for a simple 1:1 translation without
+ replacements, if we need more, we'll resize */
+ res = PyUnicode_FromUnicode(NULL, size);
+ if (res == NULL)
+ goto onError;
+ if (size == 0)
+ return res;
+ str = PyUnicode_AS_UNICODE(res);
+
+ while (p<endp) {
+ /* try to encode it */
+ PyObject *x = NULL;
+ if (charmaptranslate_output(startp, p, size, mapping, &res, &str, &x)) {
+ Py_XDECREF(x);
+ goto onError;
+ }
+ Py_XDECREF(x);
+ if (x!=Py_None) /* it worked => adjust input pointer */
+ ++p;
+ else { /* untranslatable character */
+ PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
+ Py_ssize_t repsize;
+ Py_ssize_t newpos;
+ Py_UNICODE *uni2;
+ /* startpos for collecting untranslatable chars */
+ const Py_UNICODE *collstart = p;
+ const Py_UNICODE *collend = p+1;
+ const Py_UNICODE *coll;
+
+ /* find all untranslatable characters */
+ while (collend < endp) {
+ if (charmaptranslate_lookup(*collend, mapping, &x))
+ goto onError;
+ Py_XDECREF(x);
+ if (x!=Py_None)
+ break;
+ ++collend;
+ }
+ /* cache callback name lookup
+ * (if not done yet, i.e. it's the first error) */
+ if (known_errorHandler==-1) {
+ if ((errors==NULL) || (!strcmp(errors, "strict")))
+ known_errorHandler = 1;
+ else if (!strcmp(errors, "replace"))
+ known_errorHandler = 2;
+ else if (!strcmp(errors, "ignore"))
+ known_errorHandler = 3;
+ else if (!strcmp(errors, "xmlcharrefreplace"))
+ known_errorHandler = 4;
+ else
+ known_errorHandler = 0;
+ }
+ switch (known_errorHandler) {
+ case 1: /* strict */
+ raise_translate_exception(&exc, startp, size, collstart-startp, collend-startp, reason);
+ goto onError;
+ case 2: /* replace */
+ /* No need to check for space, this is a 1:1 replacement */
+ for (coll = collstart; coll<collend; ++coll)
+ *str++ = '?';
+ /* fall through */
+ case 3: /* ignore */
+ p = collend;
+ break;
+ case 4: /* xmlcharrefreplace */
+ /* generate replacement (temporarily (mis)uses p) */
+ for (p = collstart; p < collend;) {
+ char buffer[2+29+1+1];
+ char *cp;
+ Py_UCS4 ch = _Py_UNICODE_NEXT(p, collend);
+ sprintf(buffer, "&#%d;", (int)ch);
+ if (charmaptranslate_makespace(&res, &str,
+ (str-PyUnicode_AS_UNICODE(res))+strlen(buffer)+(endp-collend)))
+ goto onError;
+ for (cp = buffer; *cp; ++cp)
+ *str++ = *cp;
+ }
+ p = collend;
+ break;
+ default:
+ repunicode = unicode_translate_call_errorhandler(errors, &errorHandler,
+ reason, startp, size, &exc,
+ collstart-startp, collend-startp, &newpos);
+ if (repunicode == NULL)
+ goto onError;
+ /* generate replacement */
+ repsize = PyUnicode_GET_SIZE(repunicode);
+ if (charmaptranslate_makespace(&res, &str,
+ (str-PyUnicode_AS_UNICODE(res))+repsize+(endp-collend))) {
+ Py_DECREF(repunicode);
+ goto onError;
+ }
+ for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2)
+ *str++ = *uni2;
+ p = startp + newpos;
+ Py_DECREF(repunicode);
+ }
+ }
+ }
+ /* Resize if we allocated to much */
+ respos = str-PyUnicode_AS_UNICODE(res);
+ if (respos<PyUnicode_GET_SIZE(res)) {
+ if (PyUnicode_Resize(&res, respos) < 0)
+ goto onError;
+ }
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return res;
+
+ onError:
+ Py_XDECREF(res);
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return NULL;
+}
+
+PyObject *PyUnicode_Translate(PyObject *str,
+ PyObject *mapping,
+ const char *errors)
+{
+ PyObject *result;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ goto onError;
+ result = PyUnicode_TranslateCharmap(PyUnicode_AS_UNICODE(str),
+ PyUnicode_GET_SIZE(str),
+ mapping,
+ errors);
+ Py_DECREF(str);
+ return result;
+
+ onError:
+ Py_XDECREF(str);
+ return NULL;
+}
+
+/* --- Decimal Encoder ---------------------------------------------------- */
+
+int PyUnicode_EncodeDecimal(Py_UNICODE *s,
+ Py_ssize_t length,
+ char *output,
+ const char *errors)
+{
+ Py_UNICODE *p, *end;
+ PyObject *errorHandler = NULL;
+ PyObject *exc = NULL;
+ const char *encoding = "decimal";
+ const char *reason = "invalid decimal Unicode string";
+ /* the following variable is used for caching string comparisons
+ * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */
+ int known_errorHandler = -1;
+
+ if (output == NULL) {
+ PyErr_BadArgument();
+ return -1;
+ }
+
+ p = s;
+ end = s + length;
+ while (p < end) {
+ register Py_UNICODE ch = *p;
+ int decimal;
+ PyObject *repunicode;
+ Py_ssize_t repsize;
+ Py_ssize_t newpos;
+ Py_UNICODE *uni2;
+ Py_UNICODE *collstart;
+ Py_UNICODE *collend;
+
+ if (Py_UNICODE_ISSPACE(ch)) {
+ *output++ = ' ';
+ ++p;
+ continue;
+ }
+ decimal = Py_UNICODE_TODECIMAL(ch);
+ if (decimal >= 0) {
+ *output++ = '0' + decimal;
+ ++p;
+ continue;
+ }
+ if (0 < ch && ch < 256) {
+ *output++ = (char)ch;
+ ++p;
+ continue;
+ }
+ /* All other characters are considered unencodable */
+ collstart = p;
+ for (collend = p+1; collend < end; collend++) {
+ if ((0 < *collend && *collend < 256) ||
+ Py_UNICODE_ISSPACE(*collend) ||
+ 0 <= Py_UNICODE_TODECIMAL(*collend))
+ break;
+ }
+ /* cache callback name lookup
+ * (if not done yet, i.e. it's the first error) */
+ if (known_errorHandler==-1) {
+ if ((errors==NULL) || (!strcmp(errors, "strict")))
+ known_errorHandler = 1;
+ else if (!strcmp(errors, "replace"))
+ known_errorHandler = 2;
+ else if (!strcmp(errors, "ignore"))
+ known_errorHandler = 3;
+ else if (!strcmp(errors, "xmlcharrefreplace"))
+ known_errorHandler = 4;
+ else
+ known_errorHandler = 0;
+ }
+ switch (known_errorHandler) {
+ case 1: /* strict */
+ raise_encode_exception(&exc, encoding, s, length, collstart-s, collend-s, reason);
+ goto onError;
+ case 2: /* replace */
+ for (p = collstart; p < collend; ++p)
+ *output++ = '?';
+ /* fall through */
+ case 3: /* ignore */
+ p = collend;
+ break;
+ case 4: /* xmlcharrefreplace */
+ /* generate replacement (temporarily (mis)uses p) */
+ for (p = collstart; p < collend;) {
+ Py_UCS4 ch = _Py_UNICODE_NEXT(p, collend);
+ output += sprintf(output, "&#%d;", ch);
+ }
+ p = collend;
+ break;
+ default:
+ repunicode = unicode_encode_call_errorhandler(errors, &errorHandler,
+ encoding, reason, s, length, &exc,
+ collstart-s, collend-s, &newpos);
+ if (repunicode == NULL)
+ goto onError;
+ /* generate replacement */
+ repsize = PyUnicode_GET_SIZE(repunicode);
+ for (uni2 = PyUnicode_AS_UNICODE(repunicode); repsize-->0; ++uni2) {
+ Py_UNICODE ch = *uni2;
+ if (Py_UNICODE_ISSPACE(ch))
+ *output++ = ' ';
+ else {
+ decimal = Py_UNICODE_TODECIMAL(ch);
+ if (decimal >= 0)
+ *output++ = '0' + decimal;
+ else if (0 < ch && ch < 256)
+ *output++ = (char)ch;
+ else {
+ Py_DECREF(repunicode);
+ raise_encode_exception(&exc, encoding,
+ s, length, collstart-s, collend-s, reason);
+ goto onError;
+ }
+ }
+ }
+ p = s + newpos;
+ Py_DECREF(repunicode);
+ }
+ }
+ /* 0-terminate the output string */
+ *output++ = '\0';
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return 0;
+
+ onError:
+ Py_XDECREF(exc);
+ Py_XDECREF(errorHandler);
+ return -1;
+}
+
+/* --- Helpers ------------------------------------------------------------ */
+
+#include "stringlib/unicodedefs.h"
+#include "stringlib/fastsearch.h"
+
+#include "stringlib/count.h"
+#include "stringlib/find.h"
+#include "stringlib/partition.h"
+#include "stringlib/split.h"
+
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
+
+Py_ssize_t PyUnicode_Count(PyObject *str,
+ PyObject *substr,
+ Py_ssize_t start,
+ Py_ssize_t end)
+{
+ Py_ssize_t result;
+ PyUnicodeObject* str_obj;
+ PyUnicodeObject* sub_obj;
+
+ str_obj = (PyUnicodeObject*) PyUnicode_FromObject(str);
+ if (!str_obj)
+ return -1;
+ sub_obj = (PyUnicodeObject*) PyUnicode_FromObject(substr);
+ if (!sub_obj) {
+ Py_DECREF(str_obj);
+ return -1;
+ }
+
+ ADJUST_INDICES(start, end, str_obj->length);
+ result = stringlib_count(
+ str_obj->str + start, end - start, sub_obj->str, sub_obj->length,
+ PY_SSIZE_T_MAX
+ );
+
+ Py_DECREF(sub_obj);
+ Py_DECREF(str_obj);
+
+ return result;
+}
+
+Py_ssize_t PyUnicode_Find(PyObject *str,
+ PyObject *sub,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ int direction)
+{
+ Py_ssize_t result;
+
+ str = PyUnicode_FromObject(str);
+ if (!str)
+ return -2;
+ sub = PyUnicode_FromObject(sub);
+ if (!sub) {
+ Py_DECREF(str);
+ return -2;
+ }
+
+ if (direction > 0)
+ result = stringlib_find_slice(
+ PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+ PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+ start, end
+ );
+ else
+ result = stringlib_rfind_slice(
+ PyUnicode_AS_UNICODE(str), PyUnicode_GET_SIZE(str),
+ PyUnicode_AS_UNICODE(sub), PyUnicode_GET_SIZE(sub),
+ start, end
+ );
+
+ Py_DECREF(str);
+ Py_DECREF(sub);
+
+ return result;
+}
+
+static
+int tailmatch(PyUnicodeObject *self,
+ PyUnicodeObject *substring,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ int direction)
+{
+ if (substring->length == 0)
+ return 1;
+
+ ADJUST_INDICES(start, end, self->length);
+ end -= substring->length;
+ if (end < start)
+ return 0;
+
+ if (direction > 0) {
+ if (Py_UNICODE_MATCH(self, end, substring))
+ return 1;
+ } else {
+ if (Py_UNICODE_MATCH(self, start, substring))
+ return 1;
+ }
+
+ return 0;
+}
+
+Py_ssize_t PyUnicode_Tailmatch(PyObject *str,
+ PyObject *substr,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ int direction)
+{
+ Py_ssize_t result;
+
+ str = PyUnicode_FromObject(str);
+ if (str == NULL)
+ return -1;
+ substr = PyUnicode_FromObject(substr);
+ if (substr == NULL) {
+ Py_DECREF(str);
+ return -1;
+ }
+
+ result = tailmatch((PyUnicodeObject *)str,
+ (PyUnicodeObject *)substr,
+ start, end, direction);
+ Py_DECREF(str);
+ Py_DECREF(substr);
+ return result;
+}
+
+/* Apply fixfct filter to the Unicode object self and return a
+ reference to the modified object */
+
+static
+PyObject *fixup(PyUnicodeObject *self,
+ int (*fixfct)(PyUnicodeObject *s))
+{
+
+ PyUnicodeObject *u;
+
+ u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+ if (u == NULL)
+ return NULL;
+
+ Py_UNICODE_COPY(u->str, self->str, self->length);
+
+ if (!fixfct(u) && PyUnicode_CheckExact(self)) {
+ /* fixfct should return TRUE if it modified the buffer. If
+ FALSE, return a reference to the original buffer instead
+ (to save space, not time) */
+ Py_INCREF(self);
+ Py_DECREF(u);
+ return (PyObject*) self;
+ }
+ return (PyObject*) u;
+}
+
+static
+int fixupper(PyUnicodeObject *self)
+{
+ Py_ssize_t len = self->length;
+ Py_UNICODE *s = self->str;
+ int status = 0;
+
+ while (len-- > 0) {
+ register Py_UNICODE ch;
+
+ ch = Py_UNICODE_TOUPPER(*s);
+ if (ch != *s) {
+ status = 1;
+ *s = ch;
+ }
+ s++;
+ }
+
+ return status;
+}
+
+static
+int fixlower(PyUnicodeObject *self)
+{
+ Py_ssize_t len = self->length;
+ Py_UNICODE *s = self->str;
+ int status = 0;
+
+ while (len-- > 0) {
+ register Py_UNICODE ch;
+
+ ch = Py_UNICODE_TOLOWER(*s);
+ if (ch != *s) {
+ status = 1;
+ *s = ch;
+ }
+ s++;
+ }
+
+ return status;
+}
+
+static
+int fixswapcase(PyUnicodeObject *self)
+{
+ Py_ssize_t len = self->length;
+ Py_UNICODE *s = self->str;
+ int status = 0;
+
+ while (len-- > 0) {
+ if (Py_UNICODE_ISUPPER(*s)) {
+ *s = Py_UNICODE_TOLOWER(*s);
+ status = 1;
+ } else if (Py_UNICODE_ISLOWER(*s)) {
+ *s = Py_UNICODE_TOUPPER(*s);
+ status = 1;
+ }
+ s++;
+ }
+
+ return status;
+}
+
+static
+int fixcapitalize(PyUnicodeObject *self)
+{
+ Py_ssize_t len = self->length;
+ Py_UNICODE *s = self->str;
+ int status = 0;
+
+ if (len == 0)
+ return 0;
+ if (!Py_UNICODE_ISUPPER(*s)) {
+ *s = Py_UNICODE_TOUPPER(*s);
+ status = 1;
+ }
+ s++;
+ while (--len > 0) {
+ if (!Py_UNICODE_ISLOWER(*s)) {
+ *s = Py_UNICODE_TOLOWER(*s);
+ status = 1;
+ }
+ s++;
+ }
+ return status;
+}
+
+static
+int fixtitle(PyUnicodeObject *self)
+{
+ register Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register Py_UNICODE *e;
+ int previous_is_cased;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1) {
+ Py_UNICODE ch = Py_UNICODE_TOTITLE(*p);
+ if (*p != ch) {
+ *p = ch;
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ e = p + PyUnicode_GET_SIZE(self);
+ previous_is_cased = 0;
+ for (; p < e; p++) {
+ register const Py_UNICODE ch = *p;
+
+ if (previous_is_cased)
+ *p = Py_UNICODE_TOLOWER(ch);
+ else
+ *p = Py_UNICODE_TOTITLE(ch);
+
+ if (Py_UNICODE_ISLOWER(ch) ||
+ Py_UNICODE_ISUPPER(ch) ||
+ Py_UNICODE_ISTITLE(ch))
+ previous_is_cased = 1;
+ else
+ previous_is_cased = 0;
+ }
+ return 1;
+}
+
+PyObject *
+PyUnicode_Join(PyObject *separator, PyObject *seq)
+{
+ PyObject *internal_separator = NULL;
+ const Py_UNICODE blank = ' ';
+ const Py_UNICODE *sep = &blank;
+ Py_ssize_t seplen = 1;
+ PyUnicodeObject *res = NULL; /* the result */
+ Py_ssize_t res_alloc = 100; /* # allocated bytes for string in res */
+ Py_ssize_t res_used; /* # used bytes */
+ Py_UNICODE *res_p; /* pointer to free byte in res's string area */
+ PyObject *fseq; /* PySequence_Fast(seq) */
+ Py_ssize_t seqlen; /* len(fseq) -- number of items in sequence */
+ PyObject *item;
+ Py_ssize_t i;
+
+ fseq = PySequence_Fast(seq, "can only join an iterable");
+ if (fseq == NULL) {
+ return NULL;
+ }
+
+ /* Grrrr. A codec may be invoked to convert str objects to
+ * Unicode, and so it's possible to call back into Python code
+ * during PyUnicode_FromObject(), and so it's possible for a sick
+ * codec to change the size of fseq (if seq is a list). Therefore
+ * we have to keep refetching the size -- can't assume seqlen
+ * is invariant.
+ */
+ seqlen = PySequence_Fast_GET_SIZE(fseq);
+ /* If empty sequence, return u"". */
+ if (seqlen == 0) {
+ res = _PyUnicode_New(0); /* empty sequence; return u"" */
+ goto Done;
+ }
+ /* If singleton sequence with an exact Unicode, return that. */
+ if (seqlen == 1) {
+ item = PySequence_Fast_GET_ITEM(fseq, 0);
+ if (PyUnicode_CheckExact(item)) {
+ Py_INCREF(item);
+ res = (PyUnicodeObject *)item;
+ goto Done;
+ }
+ }
+
+ /* At least two items to join, or one that isn't exact Unicode. */
+ if (seqlen > 1) {
+ /* Set up sep and seplen -- they're needed. */
+ if (separator == NULL) {
+ sep = &blank;
+ seplen = 1;
+ }
+ else {
+ internal_separator = PyUnicode_FromObject(separator);
+ if (internal_separator == NULL)
+ goto onError;
+ sep = PyUnicode_AS_UNICODE(internal_separator);
+ seplen = PyUnicode_GET_SIZE(internal_separator);
+ /* In case PyUnicode_FromObject() mutated seq. */
+ seqlen = PySequence_Fast_GET_SIZE(fseq);
+ }
+ }
+
+ /* Get space. */
+ res = _PyUnicode_New(res_alloc);
+ if (res == NULL)
+ goto onError;
+ res_p = PyUnicode_AS_UNICODE(res);
+ res_used = 0;
+
+ for (i = 0; i < seqlen; ++i) {
+ Py_ssize_t itemlen;
+ Py_ssize_t new_res_used;
+
+ item = PySequence_Fast_GET_ITEM(fseq, i);
+ /* Convert item to Unicode. */
+ if (! PyUnicode_Check(item) && ! PyString_Check(item)) {
+ PyErr_Format(PyExc_TypeError,
+ "sequence item %zd: expected string or Unicode,"
+ " %.80s found",
+ i, Py_TYPE(item)->tp_name);
+ goto onError;
+ }
+ item = PyUnicode_FromObject(item);
+ if (item == NULL)
+ goto onError;
+ /* We own a reference to item from here on. */
+
+ /* In case PyUnicode_FromObject() mutated seq. */
+ seqlen = PySequence_Fast_GET_SIZE(fseq);
+
+ /* Make sure we have enough space for the separator and the item. */
+ itemlen = PyUnicode_GET_SIZE(item);
+ new_res_used = res_used + itemlen;
+ if (new_res_used < 0)
+ goto Overflow;
+ if (i < seqlen - 1) {
+ new_res_used += seplen;
+ if (new_res_used < 0)
+ goto Overflow;
+ }
+ if (new_res_used > res_alloc) {
+ /* double allocated size until it's big enough */
+ do {
+ res_alloc += res_alloc;
+ if (res_alloc <= 0)
+ goto Overflow;
+ } while (new_res_used > res_alloc);
+ if (_PyUnicode_Resize(&res, res_alloc) < 0) {
+ Py_DECREF(item);
+ goto onError;
+ }
+ res_p = PyUnicode_AS_UNICODE(res) + res_used;
+ }
+
+ /* Copy item, and maybe the separator. */
+ Py_UNICODE_COPY(res_p, PyUnicode_AS_UNICODE(item), itemlen);
+ res_p += itemlen;
+ if (i < seqlen - 1) {
+ Py_UNICODE_COPY(res_p, sep, seplen);
+ res_p += seplen;
+ }
+ Py_DECREF(item);
+ res_used = new_res_used;
+ }
+
+ /* Shrink res to match the used area; this probably can't fail,
+ * but it's cheap to check.
+ */
+ if (_PyUnicode_Resize(&res, res_used) < 0)
+ goto onError;
+
+ Done:
+ Py_XDECREF(internal_separator);
+ Py_DECREF(fseq);
+ return (PyObject *)res;
+
+ Overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "join() result is too long for a Python string");
+ Py_DECREF(item);
+ /* fall through */
+
+ onError:
+ Py_XDECREF(internal_separator);
+ Py_DECREF(fseq);
+ Py_XDECREF(res);
+ return NULL;
+}
+
+static
+PyUnicodeObject *pad(PyUnicodeObject *self,
+ Py_ssize_t left,
+ Py_ssize_t right,
+ Py_UNICODE fill)
+{
+ PyUnicodeObject *u;
+
+ if (left < 0)
+ left = 0;
+ if (right < 0)
+ right = 0;
+
+ if (left == 0 && right == 0 && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return self;
+ }
+
+ if (left > PY_SSIZE_T_MAX - self->length ||
+ right > PY_SSIZE_T_MAX - (left + self->length)) {
+ PyErr_SetString(PyExc_OverflowError, "padded string is too long");
+ return NULL;
+ }
+ u = _PyUnicode_New(left + self->length + right);
+ if (u) {
+ if (left)
+ Py_UNICODE_FILL(u->str, fill, left);
+ Py_UNICODE_COPY(u->str + left, self->str, self->length);
+ if (right)
+ Py_UNICODE_FILL(u->str + left + self->length, fill, right);
+ }
+
+ return u;
+}
+
+PyObject *PyUnicode_Splitlines(PyObject *string, int keepends)
+{
+ PyObject *list;
+
+ string = PyUnicode_FromObject(string);
+ if (string == NULL)
+ return NULL;
+
+ list = stringlib_splitlines(
+ (PyObject*) string, PyUnicode_AS_UNICODE(string),
+ PyUnicode_GET_SIZE(string), keepends);
+
+ Py_DECREF(string);
+ return list;
+}
+
+static
+PyObject *split(PyUnicodeObject *self,
+ PyUnicodeObject *substring,
+ Py_ssize_t maxcount)
+{
+ if (maxcount < 0)
+ maxcount = PY_SSIZE_T_MAX;
+
+ if (substring == NULL)
+ return stringlib_split_whitespace(
+ (PyObject*) self, self->str, self->length, maxcount
+ );
+
+ return stringlib_split(
+ (PyObject*) self, self->str, self->length,
+ substring->str, substring->length,
+ maxcount
+ );
+}
+
+static
+PyObject *rsplit(PyUnicodeObject *self,
+ PyUnicodeObject *substring,
+ Py_ssize_t maxcount)
+{
+ if (maxcount < 0)
+ maxcount = PY_SSIZE_T_MAX;
+
+ if (substring == NULL)
+ return stringlib_rsplit_whitespace(
+ (PyObject*) self, self->str, self->length, maxcount
+ );
+
+ return stringlib_rsplit(
+ (PyObject*) self, self->str, self->length,
+ substring->str, substring->length,
+ maxcount
+ );
+}
+
+static
+PyObject *replace(PyUnicodeObject *self,
+ PyUnicodeObject *str1,
+ PyUnicodeObject *str2,
+ Py_ssize_t maxcount)
+{
+ PyUnicodeObject *u;
+
+ if (maxcount < 0)
+ maxcount = PY_SSIZE_T_MAX;
+ else if (maxcount == 0 || self->length == 0)
+ goto nothing;
+
+ if (str1->length == str2->length) {
+ Py_ssize_t i;
+ /* same length */
+ if (str1->length == 0)
+ goto nothing;
+ if (str1->length == 1) {
+ /* replace characters */
+ Py_UNICODE u1, u2;
+ if (!findchar(self->str, self->length, str1->str[0]))
+ goto nothing;
+ u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+ if (!u)
+ return NULL;
+ Py_UNICODE_COPY(u->str, self->str, self->length);
+ u1 = str1->str[0];
+ u2 = str2->str[0];
+ for (i = 0; i < u->length; i++)
+ if (u->str[i] == u1) {
+ if (--maxcount < 0)
+ break;
+ u->str[i] = u2;
+ }
+ } else {
+ i = stringlib_find(
+ self->str, self->length, str1->str, str1->length, 0
+ );
+ if (i < 0)
+ goto nothing;
+ u = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, self->length);
+ if (!u)
+ return NULL;
+ Py_UNICODE_COPY(u->str, self->str, self->length);
+
+ /* change everything in-place, starting with this one */
+ Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+ i += str1->length;
+
+ while ( --maxcount > 0) {
+ i = stringlib_find(self->str+i, self->length-i,
+ str1->str, str1->length,
+ i);
+ if (i == -1)
+ break;
+ Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+ i += str1->length;
+ }
+ }
+ } else {
+
+ Py_ssize_t n, i, j;
+ Py_ssize_t product, new_size, delta;
+ Py_UNICODE *p;
+
+ /* replace strings */
+ n = stringlib_count(self->str, self->length, str1->str, str1->length,
+ maxcount);
+ if (n == 0)
+ goto nothing;
+ /* new_size = self->length + n * (str2->length - str1->length)); */
+ delta = (str2->length - str1->length);
+ if (delta == 0) {
+ new_size = self->length;
+ } else {
+ product = n * (str2->length - str1->length);
+ if ((product / (str2->length - str1->length)) != n) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+ new_size = self->length + product;
+ if (new_size < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "replace string is too long");
+ return NULL;
+ }
+ }
+ u = _PyUnicode_New(new_size);
+ if (!u)
+ return NULL;
+ i = 0;
+ p = u->str;
+ if (str1->length > 0) {
+ while (n-- > 0) {
+ /* look for next match */
+ j = stringlib_find(self->str+i, self->length-i,
+ str1->str, str1->length,
+ i);
+ if (j == -1)
+ break;
+ else if (j > i) {
+ /* copy unchanged part [i:j] */
+ Py_UNICODE_COPY(p, self->str+i, j-i);
+ p += j - i;
+ }
+ /* copy substitution string */
+ if (str2->length > 0) {
+ Py_UNICODE_COPY(p, str2->str, str2->length);
+ p += str2->length;
+ }
+ i = j + str1->length;
+ }
+ if (i < self->length)
+ /* copy tail [i:] */
+ Py_UNICODE_COPY(p, self->str+i, self->length-i);
+ } else {
+ /* interleave */
+ while (n > 0) {
+ Py_UNICODE_COPY(p, str2->str, str2->length);
+ p += str2->length;
+ if (--n <= 0)
+ break;
+ *p++ = self->str[i++];
+ }
+ Py_UNICODE_COPY(p, self->str+i, self->length-i);
+ }
+ }
+ return (PyObject *) u;
+
+ nothing:
+ /* nothing to replace; return original string (when possible) */
+ if (PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject *) self;
+ }
+ return PyUnicode_FromUnicode(self->str, self->length);
+}
+
+/* --- Unicode Object Methods --------------------------------------------- */
+
+PyDoc_STRVAR(title__doc__,
+ "S.title() -> unicode\n\
+\n\
+Return a titlecased version of S, i.e. words start with title case\n\
+characters, all remaining cased characters have lower case.");
+
+static PyObject*
+unicode_title(PyUnicodeObject *self)
+{
+ return fixup(self, fixtitle);
+}
+
+PyDoc_STRVAR(capitalize__doc__,
+ "S.capitalize() -> unicode\n\
+\n\
+Return a capitalized version of S, i.e. make the first character\n\
+have upper case and the rest lower case.");
+
+static PyObject*
+unicode_capitalize(PyUnicodeObject *self)
+{
+ return fixup(self, fixcapitalize);
+}
+
+#if 0
+PyDoc_STRVAR(capwords__doc__,
+ "S.capwords() -> unicode\n\
+\n\
+Apply .capitalize() to all words in S and return the result with\n\
+normalized whitespace (all whitespace strings are replaced by ' ').");
+
+static PyObject*
+unicode_capwords(PyUnicodeObject *self)
+{
+ PyObject *list;
+ PyObject *item;
+ Py_ssize_t i;
+
+ /* Split into words */
+ list = split(self, NULL, -1);
+ if (!list)
+ return NULL;
+
+ /* Capitalize each word */
+ for (i = 0; i < PyList_GET_SIZE(list); i++) {
+ item = fixup((PyUnicodeObject *)PyList_GET_ITEM(list, i),
+ fixcapitalize);
+ if (item == NULL)
+ goto onError;
+ Py_DECREF(PyList_GET_ITEM(list, i));
+ PyList_SET_ITEM(list, i, item);
+ }
+
+ /* Join the words to form a new string */
+ item = PyUnicode_Join(NULL, list);
+
+ onError:
+ Py_DECREF(list);
+ return (PyObject *)item;
+}
+#endif
+
+/* Argument converter. Coerces to a single unicode character */
+
+static int
+convert_uc(PyObject *obj, void *addr)
+{
+ Py_UNICODE *fillcharloc = (Py_UNICODE *)addr;
+ PyObject *uniobj;
+ Py_UNICODE *unistr;
+
+ uniobj = PyUnicode_FromObject(obj);
+ if (uniobj == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "The fill character cannot be converted to Unicode");
+ return 0;
+ }
+ if (PyUnicode_GET_SIZE(uniobj) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "The fill character must be exactly one character long");
+ Py_DECREF(uniobj);
+ return 0;
+ }
+ unistr = PyUnicode_AS_UNICODE(uniobj);
+ *fillcharloc = unistr[0];
+ Py_DECREF(uniobj);
+ return 1;
+}
+
+PyDoc_STRVAR(center__doc__,
+ "S.center(width[, fillchar]) -> unicode\n\
+\n\
+Return S centered in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space)");
+
+static PyObject *
+unicode_center(PyUnicodeObject *self, PyObject *args)
+{
+ Py_ssize_t marg, left;
+ Py_ssize_t width;
+ Py_UNICODE fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|O&:center", &width, convert_uc, &fillchar))
+ return NULL;
+
+ if (self->length >= width && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ marg = width - self->length;
+ left = marg / 2 + (marg & width & 1);
+
+ return (PyObject*) pad(self, left, marg - left, fillchar);
+}
+
+#if 0
+
+/* This code should go into some future Unicode collation support
+ module. The basic comparison should compare ordinals on a naive
+ basis (this is what Java does and thus Jython too). */
+
+/* speedy UTF-16 code point order comparison */
+/* gleaned from: */
+/* http://www-4.ibm.com/software/developer/library/utf16.html?dwzone=unicode */
+
+static short utf16Fixup[32] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x2000, -0x800, -0x800, -0x800, -0x800
+};
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+ Py_ssize_t len1, len2;
+
+ Py_UNICODE *s1 = str1->str;
+ Py_UNICODE *s2 = str2->str;
+
+ len1 = str1->length;
+ len2 = str2->length;
+
+ while (len1 > 0 && len2 > 0) {
+ Py_UNICODE c1, c2;
+
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 > (1<<11) * 26)
+ c1 += utf16Fixup[c1>>11];
+ if (c2 > (1<<11) * 26)
+ c2 += utf16Fixup[c2>>11];
+ /* now c1 and c2 are in UTF-32-compatible order */
+
+ if (c1 != c2)
+ return (c1 < c2) ? -1 : 1;
+
+ len1--; len2--;
+ }
+
+ return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#else
+
+static int
+unicode_compare(PyUnicodeObject *str1, PyUnicodeObject *str2)
+{
+ register Py_ssize_t len1, len2;
+
+ Py_UNICODE *s1 = str1->str;
+ Py_UNICODE *s2 = str2->str;
+
+ len1 = str1->length;
+ len2 = str2->length;
+
+ while (len1 > 0 && len2 > 0) {
+ Py_UNICODE c1, c2;
+
+ c1 = *s1++;
+ c2 = *s2++;
+
+ if (c1 != c2)
+ return (c1 < c2) ? -1 : 1;
+
+ len1--; len2--;
+ }
+
+ return (len1 < len2) ? -1 : (len1 != len2);
+}
+
+#endif
+
+int PyUnicode_Compare(PyObject *left,
+ PyObject *right)
+{
+ PyUnicodeObject *u = NULL, *v = NULL;
+ int result;
+
+ /* Coerce the two arguments */
+ u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+ if (u == NULL)
+ goto onError;
+ v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+ if (v == NULL)
+ goto onError;
+
+ /* Shortcut for empty or interned objects */
+ if (v == u) {
+ Py_DECREF(u);
+ Py_DECREF(v);
+ return 0;
+ }
+
+ result = unicode_compare(u, v);
+
+ Py_DECREF(u);
+ Py_DECREF(v);
+ return result;
+
+ onError:
+ Py_XDECREF(u);
+ Py_XDECREF(v);
+ return -1;
+}
+
+PyObject *PyUnicode_RichCompare(PyObject *left,
+ PyObject *right,
+ int op)
+{
+ int result;
+
+ result = PyUnicode_Compare(left, right);
+ if (result == -1 && PyErr_Occurred())
+ goto onError;
+
+ /* Convert the return value to a Boolean */
+ switch (op) {
+ case Py_EQ:
+ result = (result == 0);
+ break;
+ case Py_NE:
+ result = (result != 0);
+ break;
+ case Py_LE:
+ result = (result <= 0);
+ break;
+ case Py_GE:
+ result = (result >= 0);
+ break;
+ case Py_LT:
+ result = (result == -1);
+ break;
+ case Py_GT:
+ result = (result == 1);
+ break;
+ }
+ return PyBool_FromLong(result);
+
+ onError:
+
+ /* Standard case
+
+ Type errors mean that PyUnicode_FromObject() could not convert
+ one of the arguments (usually the right hand side) to Unicode,
+ ie. we can't handle the comparison request. However, it is
+ possible that the other object knows a comparison method, which
+ is why we return Py_NotImplemented to give the other object a
+ chance.
+
+ */
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+ PyErr_Clear();
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (op != Py_EQ && op != Py_NE)
+ return NULL;
+
+ /* Equality comparison.
+
+ This is a special case: we silence any PyExc_UnicodeDecodeError
+ and instead turn it into a PyErr_UnicodeWarning.
+
+ */
+ if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError))
+ return NULL;
+ PyErr_Clear();
+ if (PyErr_Warn(PyExc_UnicodeWarning,
+ (op == Py_EQ) ?
+ "Unicode equal comparison "
+ "failed to convert both arguments to Unicode - "
+ "interpreting them as being unequal" :
+ "Unicode unequal comparison "
+ "failed to convert both arguments to Unicode - "
+ "interpreting them as being unequal"
+ ) < 0)
+ return NULL;
+ result = (op == Py_NE);
+ return PyBool_FromLong(result);
+}
+
+int PyUnicode_Contains(PyObject *container,
+ PyObject *element)
+{
+ PyObject *str, *sub;
+ int result;
+
+ /* Coerce the two arguments */
+ sub = PyUnicode_FromObject(element);
+ if (!sub) {
+ return -1;
+ }
+
+ str = PyUnicode_FromObject(container);
+ if (!str) {
+ Py_DECREF(sub);
+ return -1;
+ }
+
+ result = stringlib_contains_obj(str, sub);
+
+ Py_DECREF(str);
+ Py_DECREF(sub);
+
+ return result;
+}
+
+/* Concat to string or Unicode object giving a new Unicode object. */
+
+PyObject *PyUnicode_Concat(PyObject *left,
+ PyObject *right)
+{
+ PyUnicodeObject *u = NULL, *v = NULL, *w;
+
+ /* Coerce the two arguments */
+ u = (PyUnicodeObject *)PyUnicode_FromObject(left);
+ if (u == NULL)
+ goto onError;
+ v = (PyUnicodeObject *)PyUnicode_FromObject(right);
+ if (v == NULL)
+ goto onError;
+
+ /* Shortcuts */
+ if (v == unicode_empty) {
+ Py_DECREF(v);
+ return (PyObject *)u;
+ }
+ if (u == unicode_empty) {
+ Py_DECREF(u);
+ return (PyObject *)v;
+ }
+
+ /* Concat the two Unicode strings */
+ w = _PyUnicode_New(u->length + v->length);
+ if (w == NULL)
+ goto onError;
+ Py_UNICODE_COPY(w->str, u->str, u->length);
+ Py_UNICODE_COPY(w->str + u->length, v->str, v->length);
+
+ Py_DECREF(u);
+ Py_DECREF(v);
+ return (PyObject *)w;
+
+ onError:
+ Py_XDECREF(u);
+ Py_XDECREF(v);
+ return NULL;
+}
+
+PyDoc_STRVAR(count__doc__,
+ "S.count(sub[, start[, end]]) -> int\n\
+\n\
+Return the number of non-overlapping occurrences of substring sub in\n\
+Unicode string S[start:end]. Optional arguments start and end are\n\
+interpreted as in slice notation.");
+
+static PyObject *
+unicode_count(PyUnicodeObject *self, PyObject *args)
+{
+ PyUnicodeObject *substring;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ PyObject *result;
+
+ if (!stringlib_parse_args_finds_unicode("count", args, &substring,
+ &start, &end))
+ return NULL;
+
+ ADJUST_INDICES(start, end, self->length);
+ result = PyInt_FromSsize_t(
+ stringlib_count(self->str + start, end - start,
+ substring->str, substring->length,
+ PY_SSIZE_T_MAX)
+ );
+
+ Py_DECREF(substring);
+
+ return result;
+}
+
+PyDoc_STRVAR(encode__doc__,
+ "S.encode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Encodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
+'xmlcharrefreplace' as well as any other name registered with\n\
+codecs.register_error that can handle UnicodeEncodeErrors.");
+
+static PyObject *
+unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"encoding", "errors", 0};
+ char *encoding = NULL;
+ char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode",
+ kwlist, &encoding, &errors))
+ return NULL;
+ v = PyUnicode_AsEncodedObject((PyObject *)self, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "encoder did not return a string/unicode object "
+ "(type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ return NULL;
+ }
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyDoc_STRVAR(decode__doc__,
+ "S.decode([encoding[,errors]]) -> string or unicode\n\
+\n\
+Decodes S using the codec registered for encoding. encoding defaults\n\
+to the default encoding. errors may be given to set a different error\n\
+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
+a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
+as well as any other name registered with codecs.register_error that is\n\
+able to handle UnicodeDecodeErrors.");
+
+static PyObject *
+unicode_decode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"encoding", "errors", 0};
+ char *encoding = NULL;
+ char *errors = NULL;
+ PyObject *v;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+ kwlist, &encoding, &errors))
+ return NULL;
+ v = PyUnicode_AsDecodedObject((PyObject *)self, encoding, errors);
+ if (v == NULL)
+ goto onError;
+ if (!PyString_Check(v) && !PyUnicode_Check(v)) {
+ PyErr_Format(PyExc_TypeError,
+ "decoder did not return a string/unicode object "
+ "(type=%.400s)",
+ Py_TYPE(v)->tp_name);
+ Py_DECREF(v);
+ return NULL;
+ }
+ return v;
+
+ onError:
+ return NULL;
+}
+
+PyDoc_STRVAR(expandtabs__doc__,
+ "S.expandtabs([tabsize]) -> unicode\n\
+\n\
+Return a copy of S where all tab characters are expanded using spaces.\n\
+If tabsize is not given, a tab size of 8 characters is assumed.");
+
+static PyObject*
+unicode_expandtabs(PyUnicodeObject *self, PyObject *args)
+{
+ Py_UNICODE *e;
+ Py_UNICODE *p;
+ Py_UNICODE *q;
+ Py_UNICODE *qe;
+ Py_ssize_t i, j, incr;
+ PyUnicodeObject *u;
+ int tabsize = 8;
+
+ if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+ return NULL;
+
+ /* First pass: determine size of output string */
+ i = 0; /* chars up to and including most recent \n or \r */
+ j = 0; /* chars since most recent \n or \r (use in tab calculations) */
+ e = self->str + self->length; /* end of input */
+ for (p = self->str; p < e; p++)
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ incr = tabsize - (j % tabsize); /* cannot overflow */
+ if (j > PY_SSIZE_T_MAX - incr)
+ goto overflow1;
+ j += incr;
+ }
+ }
+ else {
+ if (j > PY_SSIZE_T_MAX - 1)
+ goto overflow1;
+ j++;
+ if (*p == '\n' || *p == '\r') {
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow1;
+ i += j;
+ j = 0;
+ }
+ }
+
+ if (i > PY_SSIZE_T_MAX - j)
+ goto overflow1;
+
+ /* Second pass: create output string and fill it */
+ u = _PyUnicode_New(i + j);
+ if (!u)
+ return NULL;
+
+ j = 0; /* same as in first pass */
+ q = u->str; /* next output char */
+ qe = u->str + u->length; /* end of output */
+
+ for (p = self->str; p < e; p++)
+ if (*p == '\t') {
+ if (tabsize > 0) {
+ i = tabsize - (j % tabsize);
+ j += i;
+ while (i--) {
+ if (q >= qe)
+ goto overflow2;
+ *q++ = ' ';
+ }
+ }
+ }
+ else {
+ if (q >= qe)
+ goto overflow2;
+ *q++ = *p;
+ j++;
+ if (*p == '\n' || *p == '\r')
+ j = 0;
+ }
+
+ return (PyObject*) u;
+
+ overflow2:
+ Py_DECREF(u);
+ overflow1:
+ PyErr_SetString(PyExc_OverflowError, "new string is too long");
+ return NULL;
+}
+
+PyDoc_STRVAR(find__doc__,
+ "S.find(sub [,start [,end]]) -> int\n\
+\n\
+Return the lowest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_find(PyUnicodeObject *self, PyObject *args)
+{
+ PyUnicodeObject *substring;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ Py_ssize_t result;
+
+ if (!stringlib_parse_args_finds_unicode("find", args, &substring,
+ &start, &end))
+ return NULL;
+
+ result = stringlib_find_slice(
+ PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+ PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+ start, end
+ );
+
+ Py_DECREF(substring);
+
+ return PyInt_FromSsize_t(result);
+}
+
+static PyObject *
+unicode_getitem(PyUnicodeObject *self, Py_ssize_t index)
+{
+ if (index < 0 || index >= self->length) {
+ PyErr_SetString(PyExc_IndexError, "string index out of range");
+ return NULL;
+ }
+
+ return (PyObject*) PyUnicode_FromUnicode(&self->str[index], 1);
+}
+
+static long
+unicode_hash(PyUnicodeObject *self)
+{
+ /* Since Unicode objects compare equal to their ASCII string
+ counterparts, they should use the individual character values
+ as basis for their hash value. This is needed to assure that
+ strings and Unicode objects behave in the same way as
+ dictionary keys. */
+
+ register Py_ssize_t len;
+ register Py_UNICODE *p;
+ register long x;
+
+#ifdef Py_DEBUG
+ assert(_Py_HashSecret_Initialized);
+#endif
+ if (self->hash != -1)
+ return self->hash;
+ len = PyUnicode_GET_SIZE(self);
+ /*
+ We make the hash of the empty string be 0, rather than using
+ (prefix ^ suffix), since this slightly obfuscates the hash secret
+ */
+ if (len == 0) {
+ self->hash = 0;
+ return 0;
+ }
+ p = PyUnicode_AS_UNICODE(self);
+ x = _Py_HashSecret.prefix;
+ x ^= *p << 7;
+ while (--len >= 0)
+ x = (1000003*x) ^ *p++;
+ x ^= PyUnicode_GET_SIZE(self);
+ x ^= _Py_HashSecret.suffix;
+ if (x == -1)
+ x = -2;
+ self->hash = x;
+ return x;
+}
+
+PyDoc_STRVAR(index__doc__,
+ "S.index(sub [,start [,end]]) -> int\n\
+\n\
+Like S.find() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_index(PyUnicodeObject *self, PyObject *args)
+{
+ Py_ssize_t result;
+ PyUnicodeObject *substring;
+ Py_ssize_t start;
+ Py_ssize_t end;
+
+ if (!stringlib_parse_args_finds_unicode("index", args, &substring,
+ &start, &end))
+ return NULL;
+
+ result = stringlib_find_slice(
+ PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+ PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+ start, end
+ );
+
+ Py_DECREF(substring);
+
+ if (result < 0) {
+ PyErr_SetString(PyExc_ValueError, "substring not found");
+ return NULL;
+ }
+
+ return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(islower__doc__,
+ "S.islower() -> bool\n\
+\n\
+Return True if all cased characters in S are lowercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_islower(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1)
+ return PyBool_FromLong(Py_UNICODE_ISLOWER(*p));
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ cased = 0;
+ for (; p < e; p++) {
+ register const Py_UNICODE ch = *p;
+
+ if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch))
+ return PyBool_FromLong(0);
+ else if (!cased && Py_UNICODE_ISLOWER(ch))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isupper__doc__,
+ "S.isupper() -> bool\n\
+\n\
+Return True if all cased characters in S are uppercase and there is\n\
+at least one cased character in S, False otherwise.");
+
+static PyObject*
+unicode_isupper(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+ int cased;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1)
+ return PyBool_FromLong(Py_UNICODE_ISUPPER(*p) != 0);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ cased = 0;
+ for (; p < e; p++) {
+ register const Py_UNICODE ch = *p;
+
+ if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch))
+ return PyBool_FromLong(0);
+ else if (!cased && Py_UNICODE_ISUPPER(ch))
+ cased = 1;
+ }
+ return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(istitle__doc__,
+ "S.istitle() -> bool\n\
+\n\
+Return True if S is a titlecased string and there is at least one\n\
+character in S, i.e. upper- and titlecase characters may only\n\
+follow uncased characters and lowercase characters only cased ones.\n\
+Return False otherwise.");
+
+static PyObject*
+unicode_istitle(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+ int cased, previous_is_cased;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1)
+ return PyBool_FromLong((Py_UNICODE_ISTITLE(*p) != 0) ||
+ (Py_UNICODE_ISUPPER(*p) != 0));
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ cased = 0;
+ previous_is_cased = 0;
+ for (; p < e; p++) {
+ register const Py_UNICODE ch = *p;
+
+ if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) {
+ if (previous_is_cased)
+ return PyBool_FromLong(0);
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else if (Py_UNICODE_ISLOWER(ch)) {
+ if (!previous_is_cased)
+ return PyBool_FromLong(0);
+ previous_is_cased = 1;
+ cased = 1;
+ }
+ else
+ previous_is_cased = 0;
+ }
+ return PyBool_FromLong(cased);
+}
+
+PyDoc_STRVAR(isspace__doc__,
+ "S.isspace() -> bool\n\
+\n\
+Return True if all characters in S are whitespace\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isspace(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISSPACE(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISSPACE(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalpha__doc__,
+ "S.isalpha() -> bool\n\
+\n\
+Return True if all characters in S are alphabetic\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalpha(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISALPHA(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISALPHA(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isalnum__doc__,
+ "S.isalnum() -> bool\n\
+\n\
+Return True if all characters in S are alphanumeric\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isalnum(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISALNUM(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISALNUM(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdecimal__doc__,
+ "S.isdecimal() -> bool\n\
+\n\
+Return True if there are only decimal characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isdecimal(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISDECIMAL(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISDECIMAL(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isdigit__doc__,
+ "S.isdigit() -> bool\n\
+\n\
+Return True if all characters in S are digits\n\
+and there is at least one character in S, False otherwise.");
+
+static PyObject*
+unicode_isdigit(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISDIGIT(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISDIGIT(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(isnumeric__doc__,
+ "S.isnumeric() -> bool\n\
+\n\
+Return True if there are only numeric characters in S,\n\
+False otherwise.");
+
+static PyObject*
+unicode_isnumeric(PyUnicodeObject *self)
+{
+ register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+ register const Py_UNICODE *e;
+
+ /* Shortcut for single character strings */
+ if (PyUnicode_GET_SIZE(self) == 1 &&
+ Py_UNICODE_ISNUMERIC(*p))
+ return PyBool_FromLong(1);
+
+ /* Special case for empty strings */
+ if (PyUnicode_GET_SIZE(self) == 0)
+ return PyBool_FromLong(0);
+
+ e = p + PyUnicode_GET_SIZE(self);
+ for (; p < e; p++) {
+ if (!Py_UNICODE_ISNUMERIC(*p))
+ return PyBool_FromLong(0);
+ }
+ return PyBool_FromLong(1);
+}
+
+PyDoc_STRVAR(join__doc__,
+ "S.join(iterable) -> unicode\n\
+\n\
+Return a string which is the concatenation of the strings in the\n\
+iterable. The separator between elements is S.");
+
+static PyObject*
+unicode_join(PyObject *self, PyObject *data)
+{
+ return PyUnicode_Join(self, data);
+}
+
+static Py_ssize_t
+unicode_length(PyUnicodeObject *self)
+{
+ return self->length;
+}
+
+PyDoc_STRVAR(ljust__doc__,
+ "S.ljust(width[, fillchar]) -> int\n\
+\n\
+Return S left-justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_ljust(PyUnicodeObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ Py_UNICODE fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|O&:ljust", &width, convert_uc, &fillchar))
+ return NULL;
+
+ if (self->length >= width && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ return (PyObject*) pad(self, 0, width - self->length, fillchar);
+}
+
+PyDoc_STRVAR(lower__doc__,
+ "S.lower() -> unicode\n\
+\n\
+Return a copy of the string S converted to lowercase.");
+
+static PyObject*
+unicode_lower(PyUnicodeObject *self)
+{
+ return fixup(self, fixlower);
+}
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
+/* Arrays indexed by above */
+static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
+
+#define STRIPNAME(i) (stripformat[i]+3)
+
+/* externally visible for str.strip(unicode) */
+PyObject *
+_PyUnicode_XStrip(PyUnicodeObject *self, int striptype, PyObject *sepobj)
+{
+ Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+ Py_ssize_t len = PyUnicode_GET_SIZE(self);
+ Py_UNICODE *sep = PyUnicode_AS_UNICODE(sepobj);
+ Py_ssize_t seplen = PyUnicode_GET_SIZE(sepobj);
+ Py_ssize_t i, j;
+
+ BLOOM_MASK sepmask = make_bloom_mask(sep, seplen);
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && BLOOM_MEMBER(sepmask, s[i], sep, seplen)) {
+ i++;
+ }
+ }
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && BLOOM_MEMBER(sepmask, s[j], sep, seplen));
+ j++;
+ }
+
+ if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+ else
+ return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_strip(PyUnicodeObject *self, int striptype)
+{
+ Py_UNICODE *s = PyUnicode_AS_UNICODE(self);
+ Py_ssize_t len = PyUnicode_GET_SIZE(self), i, j;
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && Py_UNICODE_ISSPACE(s[i])) {
+ i++;
+ }
+ }
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && Py_UNICODE_ISSPACE(s[j]));
+ j++;
+ }
+
+ if (i == 0 && j == len && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*)self;
+ }
+ else
+ return PyUnicode_FromUnicode(s+i, j-i);
+}
+
+
+static PyObject *
+do_argstrip(PyUnicodeObject *self, int striptype, PyObject *args)
+{
+ PyObject *sep = NULL;
+
+ if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+ return NULL;
+
+ if (sep != NULL && sep != Py_None) {
+ if (PyUnicode_Check(sep))
+ return _PyUnicode_XStrip(self, striptype, sep);
+ else if (PyString_Check(sep)) {
+ PyObject *res;
+ sep = PyUnicode_FromObject(sep);
+ if (sep==NULL)
+ return NULL;
+ res = _PyUnicode_XStrip(self, striptype, sep);
+ Py_DECREF(sep);
+ return res;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%s arg must be None, unicode or str",
+ STRIPNAME(striptype));
+ return NULL;
+ }
+ }
+
+ return do_strip(self, striptype);
+}
+
+
+PyDoc_STRVAR(strip__doc__,
+ "S.strip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading and trailing\n\
+whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_strip(PyUnicodeObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, BOTHSTRIP); /* Common case */
+ else
+ return do_argstrip(self, BOTHSTRIP, args);
+}
+
+
+PyDoc_STRVAR(lstrip__doc__,
+ "S.lstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with leading whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_lstrip(PyUnicodeObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, LEFTSTRIP); /* Common case */
+ else
+ return do_argstrip(self, LEFTSTRIP, args);
+}
+
+
+PyDoc_STRVAR(rstrip__doc__,
+ "S.rstrip([chars]) -> unicode\n\
+\n\
+Return a copy of the string S with trailing whitespace removed.\n\
+If chars is given and not None, remove characters in chars instead.\n\
+If chars is a str, it will be converted to unicode before stripping");
+
+static PyObject *
+unicode_rstrip(PyUnicodeObject *self, PyObject *args)
+{
+ if (PyTuple_GET_SIZE(args) == 0)
+ return do_strip(self, RIGHTSTRIP); /* Common case */
+ else
+ return do_argstrip(self, RIGHTSTRIP, args);
+}
+
+
+static PyObject*
+unicode_repeat(PyUnicodeObject *str, Py_ssize_t len)
+{
+ PyUnicodeObject *u;
+ Py_UNICODE *p;
+ Py_ssize_t nchars;
+ size_t nbytes;
+
+ if (len < 0)
+ len = 0;
+
+ if (len == 1 && PyUnicode_CheckExact(str)) {
+ /* no repeat, return original string */
+ Py_INCREF(str);
+ return (PyObject*) str;
+ }
+
+ /* ensure # of chars needed doesn't overflow int and # of bytes
+ * needed doesn't overflow size_t
+ */
+ nchars = len * str->length;
+ if (len && nchars / len != str->length) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ nbytes = (nchars + 1) * sizeof(Py_UNICODE);
+ if (nbytes / sizeof(Py_UNICODE) != (size_t)(nchars + 1)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "repeated string is too long");
+ return NULL;
+ }
+ u = _PyUnicode_New(nchars);
+ if (!u)
+ return NULL;
+
+ p = u->str;
+
+ if (str->length == 1 && len > 0) {
+ Py_UNICODE_FILL(p, str->str[0], len);
+ } else {
+ Py_ssize_t done = 0; /* number of characters copied this far */
+ if (done < nchars) {
+ Py_UNICODE_COPY(p, str->str, str->length);
+ done = str->length;
+ }
+ while (done < nchars) {
+ Py_ssize_t n = (done <= nchars-done) ? done : nchars-done;
+ Py_UNICODE_COPY(p+done, p, n);
+ done += n;
+ }
+ }
+
+ return (PyObject*) u;
+}
+
+PyObject *PyUnicode_Replace(PyObject *obj,
+ PyObject *subobj,
+ PyObject *replobj,
+ Py_ssize_t maxcount)
+{
+ PyObject *self;
+ PyObject *str1;
+ PyObject *str2;
+ PyObject *result;
+
+ self = PyUnicode_FromObject(obj);
+ if (self == NULL)
+ return NULL;
+ str1 = PyUnicode_FromObject(subobj);
+ if (str1 == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ str2 = PyUnicode_FromObject(replobj);
+ if (str2 == NULL) {
+ Py_DECREF(self);
+ Py_DECREF(str1);
+ return NULL;
+ }
+ result = replace((PyUnicodeObject *)self,
+ (PyUnicodeObject *)str1,
+ (PyUnicodeObject *)str2,
+ maxcount);
+ Py_DECREF(self);
+ Py_DECREF(str1);
+ Py_DECREF(str2);
+ return result;
+}
+
+PyDoc_STRVAR(replace__doc__,
+ "S.replace(old, new[, count]) -> unicode\n\
+\n\
+Return a copy of S with all occurrences of substring\n\
+old replaced by new. If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
+
+static PyObject*
+unicode_replace(PyUnicodeObject *self, PyObject *args)
+{
+ PyUnicodeObject *str1;
+ PyUnicodeObject *str2;
+ Py_ssize_t maxcount = -1;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "OO|n:replace", &str1, &str2, &maxcount))
+ return NULL;
+ str1 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str1);
+ if (str1 == NULL)
+ return NULL;
+ str2 = (PyUnicodeObject *)PyUnicode_FromObject((PyObject *)str2);
+ if (str2 == NULL) {
+ Py_DECREF(str1);
+ return NULL;
+ }
+
+ result = replace(self, str1, str2, maxcount);
+
+ Py_DECREF(str1);
+ Py_DECREF(str2);
+ return result;
+}
+
+static
+PyObject *unicode_repr(PyObject *unicode)
+{
+ return unicodeescape_string(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ 1);
+}
+
+PyDoc_STRVAR(rfind__doc__,
+ "S.rfind(sub [,start [,end]]) -> int\n\
+\n\
+Return the highest index in S where substring sub is found,\n\
+such that sub is contained within S[start:end]. Optional\n\
+arguments start and end are interpreted as in slice notation.\n\
+\n\
+Return -1 on failure.");
+
+static PyObject *
+unicode_rfind(PyUnicodeObject *self, PyObject *args)
+{
+ PyUnicodeObject *substring;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ Py_ssize_t result;
+
+ if (!stringlib_parse_args_finds_unicode("rfind", args, &substring,
+ &start, &end))
+ return NULL;
+
+ result = stringlib_rfind_slice(
+ PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+ PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+ start, end
+ );
+
+ Py_DECREF(substring);
+
+ return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rindex__doc__,
+ "S.rindex(sub [,start [,end]]) -> int\n\
+\n\
+Like S.rfind() but raise ValueError when the substring is not found.");
+
+static PyObject *
+unicode_rindex(PyUnicodeObject *self, PyObject *args)
+{
+ PyUnicodeObject *substring;
+ Py_ssize_t start;
+ Py_ssize_t end;
+ Py_ssize_t result;
+
+ if (!stringlib_parse_args_finds_unicode("rindex", args, &substring,
+ &start, &end))
+ return NULL;
+
+ result = stringlib_rfind_slice(
+ PyUnicode_AS_UNICODE(self), PyUnicode_GET_SIZE(self),
+ PyUnicode_AS_UNICODE(substring), PyUnicode_GET_SIZE(substring),
+ start, end
+ );
+
+ Py_DECREF(substring);
+
+ if (result < 0) {
+ PyErr_SetString(PyExc_ValueError, "substring not found");
+ return NULL;
+ }
+ return PyInt_FromSsize_t(result);
+}
+
+PyDoc_STRVAR(rjust__doc__,
+ "S.rjust(width[, fillchar]) -> unicode\n\
+\n\
+Return S right-justified in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space).");
+
+static PyObject *
+unicode_rjust(PyUnicodeObject *self, PyObject *args)
+{
+ Py_ssize_t width;
+ Py_UNICODE fillchar = ' ';
+
+ if (!PyArg_ParseTuple(args, "n|O&:rjust", &width, convert_uc, &fillchar))
+ return NULL;
+
+ if (self->length >= width && PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ return (PyObject*) pad(self, width - self->length, 0, fillchar);
+}
+
+static PyObject*
+unicode_slice(PyUnicodeObject *self, Py_ssize_t start, Py_ssize_t end)
+{
+ /* standard clamping */
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = 0;
+ if (end > self->length)
+ end = self->length;
+ if (start == 0 && end == self->length && PyUnicode_CheckExact(self)) {
+ /* full slice, return original string */
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+ if (start > end)
+ start = end;
+ /* copy slice */
+ return (PyObject*) PyUnicode_FromUnicode(self->str + start,
+ end - start);
+}
+
+PyObject *PyUnicode_Split(PyObject *s,
+ PyObject *sep,
+ Py_ssize_t maxsplit)
+{
+ PyObject *result;
+
+ s = PyUnicode_FromObject(s);
+ if (s == NULL)
+ return NULL;
+ if (sep != NULL) {
+ sep = PyUnicode_FromObject(sep);
+ if (sep == NULL) {
+ Py_DECREF(s);
+ return NULL;
+ }
+ }
+
+ result = split((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+ Py_DECREF(s);
+ Py_XDECREF(sep);
+ return result;
+}
+
+PyDoc_STRVAR(split__doc__,
+ "S.split([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string. If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator and empty strings are\n\
+removed from the result.");
+
+static PyObject*
+unicode_split(PyUnicodeObject *self, PyObject *args)
+{
+ PyObject *substring = Py_None;
+ Py_ssize_t maxcount = -1;
+
+ if (!PyArg_ParseTuple(args, "|On:split", &substring, &maxcount))
+ return NULL;
+
+ if (substring == Py_None)
+ return split(self, NULL, maxcount);
+ else if (PyUnicode_Check(substring))
+ return split(self, (PyUnicodeObject *)substring, maxcount);
+ else
+ return PyUnicode_Split((PyObject *)self, substring, maxcount);
+}
+
+PyObject *
+PyUnicode_Partition(PyObject *str_in, PyObject *sep_in)
+{
+ PyObject* str_obj;
+ PyObject* sep_obj;
+ PyObject* out;
+
+ str_obj = PyUnicode_FromObject(str_in);
+ if (!str_obj)
+ return NULL;
+ sep_obj = PyUnicode_FromObject(sep_in);
+ if (!sep_obj) {
+ Py_DECREF(str_obj);
+ return NULL;
+ }
+
+ out = stringlib_partition(
+ str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+ sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+ );
+
+ Py_DECREF(sep_obj);
+ Py_DECREF(str_obj);
+
+ return out;
+}
+
+
+PyObject *
+PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in)
+{
+ PyObject* str_obj;
+ PyObject* sep_obj;
+ PyObject* out;
+
+ str_obj = PyUnicode_FromObject(str_in);
+ if (!str_obj)
+ return NULL;
+ sep_obj = PyUnicode_FromObject(sep_in);
+ if (!sep_obj) {
+ Py_DECREF(str_obj);
+ return NULL;
+ }
+
+ out = stringlib_rpartition(
+ str_obj, PyUnicode_AS_UNICODE(str_obj), PyUnicode_GET_SIZE(str_obj),
+ sep_obj, PyUnicode_AS_UNICODE(sep_obj), PyUnicode_GET_SIZE(sep_obj)
+ );
+
+ Py_DECREF(sep_obj);
+ Py_DECREF(str_obj);
+
+ return out;
+}
+
+PyDoc_STRVAR(partition__doc__,
+ "S.partition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, and return the part before it,\n\
+the separator itself, and the part after it. If the separator is not\n\
+found, return S and two empty strings.");
+
+static PyObject*
+unicode_partition(PyUnicodeObject *self, PyObject *separator)
+{
+ return PyUnicode_Partition((PyObject *)self, separator);
+}
+
+PyDoc_STRVAR(rpartition__doc__,
+ "S.rpartition(sep) -> (head, sep, tail)\n\
+\n\
+Search for the separator sep in S, starting at the end of S, and return\n\
+the part before it, the separator itself, and the part after it. If the\n\
+separator is not found, return two empty strings and S.");
+
+static PyObject*
+unicode_rpartition(PyUnicodeObject *self, PyObject *separator)
+{
+ return PyUnicode_RPartition((PyObject *)self, separator);
+}
+
+PyObject *PyUnicode_RSplit(PyObject *s,
+ PyObject *sep,
+ Py_ssize_t maxsplit)
+{
+ PyObject *result;
+
+ s = PyUnicode_FromObject(s);
+ if (s == NULL)
+ return NULL;
+ if (sep != NULL) {
+ sep = PyUnicode_FromObject(sep);
+ if (sep == NULL) {
+ Py_DECREF(s);
+ return NULL;
+ }
+ }
+
+ result = rsplit((PyUnicodeObject *)s, (PyUnicodeObject *)sep, maxsplit);
+
+ Py_DECREF(s);
+ Py_XDECREF(sep);
+ return result;
+}
+
+PyDoc_STRVAR(rsplit__doc__,
+ "S.rsplit([sep [,maxsplit]]) -> list of strings\n\
+\n\
+Return a list of the words in S, using sep as the\n\
+delimiter string, starting at the end of the string and\n\
+working to the front. If maxsplit is given, at most maxsplit\n\
+splits are done. If sep is not specified, any whitespace string\n\
+is a separator.");
+
+static PyObject*
+unicode_rsplit(PyUnicodeObject *self, PyObject *args)
+{
+ PyObject *substring = Py_None;
+ Py_ssize_t maxcount = -1;
+
+ if (!PyArg_ParseTuple(args, "|On:rsplit", &substring, &maxcount))
+ return NULL;
+
+ if (substring == Py_None)
+ return rsplit(self, NULL, maxcount);
+ else if (PyUnicode_Check(substring))
+ return rsplit(self, (PyUnicodeObject *)substring, maxcount);
+ else
+ return PyUnicode_RSplit((PyObject *)self, substring, maxcount);
+}
+
+PyDoc_STRVAR(splitlines__doc__,
+ "S.splitlines(keepends=False) -> list of strings\n\
+\n\
+Return a list of the lines in S, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+unicode_splitlines(PyUnicodeObject *self, PyObject *args)
+{
+ int keepends = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+ return NULL;
+
+ return PyUnicode_Splitlines((PyObject *)self, keepends);
+}
+
+static
+PyObject *unicode_str(PyUnicodeObject *self)
+{
+ return PyUnicode_AsEncodedString((PyObject *)self, NULL, NULL);
+}
+
+PyDoc_STRVAR(swapcase__doc__,
+ "S.swapcase() -> unicode\n\
+\n\
+Return a copy of S with uppercase characters converted to lowercase\n\
+and vice versa.");
+
+static PyObject*
+unicode_swapcase(PyUnicodeObject *self)
+{
+ return fixup(self, fixswapcase);
+}
+
+PyDoc_STRVAR(translate__doc__,
+ "S.translate(table) -> unicode\n\
+\n\
+Return a copy of the string S, where all characters have been mapped\n\
+through the given translation table, which must be a mapping of\n\
+Unicode ordinals to Unicode ordinals, Unicode strings or None.\n\
+Unmapped characters are left untouched. Characters mapped to None\n\
+are deleted.");
+
+static PyObject*
+unicode_translate(PyUnicodeObject *self, PyObject *table)
+{
+ return PyUnicode_TranslateCharmap(self->str,
+ self->length,
+ table,
+ "ignore");
+}
+
+PyDoc_STRVAR(upper__doc__,
+ "S.upper() -> unicode\n\
+\n\
+Return a copy of S converted to uppercase.");
+
+static PyObject*
+unicode_upper(PyUnicodeObject *self)
+{
+ return fixup(self, fixupper);
+}
+
+PyDoc_STRVAR(zfill__doc__,
+ "S.zfill(width) -> unicode\n\
+\n\
+Pad a numeric string S with zeros on the left, to fill a field\n\
+of the specified width. The string S is never truncated.");
+
+static PyObject *
+unicode_zfill(PyUnicodeObject *self, PyObject *args)
+{
+ Py_ssize_t fill;
+ PyUnicodeObject *u;
+
+ Py_ssize_t width;
+ if (!PyArg_ParseTuple(args, "n:zfill", &width))
+ return NULL;
+
+ if (self->length >= width) {
+ if (PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+ else
+ return PyUnicode_FromUnicode(
+ PyUnicode_AS_UNICODE(self),
+ PyUnicode_GET_SIZE(self)
+ );
+ }
+
+ fill = width - self->length;
+
+ u = pad(self, fill, 0, '0');
+
+ if (u == NULL)
+ return NULL;
+
+ if (u->str[fill] == '+' || u->str[fill] == '-') {
+ /* move sign to beginning of string */
+ u->str[0] = u->str[fill];
+ u->str[fill] = '0';
+ }
+
+ return (PyObject*) u;
+}
+
+#if 0
+static PyObject*
+free_listsize(PyUnicodeObject *self)
+{
+ return PyInt_FromLong(numfree);
+}
+#endif
+
+PyDoc_STRVAR(startswith__doc__,
+ "S.startswith(prefix[, start[, end]]) -> bool\n\
+\n\
+Return True if S starts with the specified prefix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+prefix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_startswith(PyUnicodeObject *self,
+ PyObject *args)
+{
+ PyObject *subobj;
+ PyUnicodeObject *substring;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ int result;
+
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ substring = (PyUnicodeObject *)PyUnicode_FromObject(
+ PyTuple_GET_ITEM(subobj, i));
+ if (substring == NULL)
+ return NULL;
+ result = tailmatch(self, substring, start, end, -1);
+ Py_DECREF(substring);
+ if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ /* nothing matched */
+ Py_RETURN_FALSE;
+ }
+ substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+ if (substring == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+ return NULL;
+ }
+ result = tailmatch(self, substring, start, end, -1);
+ Py_DECREF(substring);
+ return PyBool_FromLong(result);
+}
+
+
+PyDoc_STRVAR(endswith__doc__,
+ "S.endswith(suffix[, start[, end]]) -> bool\n\
+\n\
+Return True if S ends with the specified suffix, False otherwise.\n\
+With optional start, test S beginning at that position.\n\
+With optional end, stop comparing S at that position.\n\
+suffix can also be a tuple of strings to try.");
+
+static PyObject *
+unicode_endswith(PyUnicodeObject *self,
+ PyObject *args)
+{
+ PyObject *subobj;
+ PyUnicodeObject *substring;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ int result;
+
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
+ return NULL;
+ if (PyTuple_Check(subobj)) {
+ Py_ssize_t i;
+ for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
+ substring = (PyUnicodeObject *)PyUnicode_FromObject(
+ PyTuple_GET_ITEM(subobj, i));
+ if (substring == NULL)
+ return NULL;
+ result = tailmatch(self, substring, start, end, +1);
+ Py_DECREF(substring);
+ if (result) {
+ Py_RETURN_TRUE;
+ }
+ }
+ Py_RETURN_FALSE;
+ }
+ substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
+ if (substring == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
+ return NULL;
+ }
+ result = tailmatch(self, substring, start, end, +1);
+ Py_DECREF(substring);
+ return PyBool_FromLong(result);
+}
+
+
+/* Implements do_string_format, which is unicode because of stringlib */
+#include "stringlib/string_format.h"
+
+PyDoc_STRVAR(format__doc__,
+ "S.format(*args, **kwargs) -> unicode\n\
+\n\
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
+
+static PyObject *
+unicode__format__(PyObject *self, PyObject *args)
+{
+ PyObject *format_spec;
+ PyObject *result = NULL;
+ PyObject *tmp = NULL;
+
+ /* If 2.x, convert format_spec to the same type as value */
+ /* This is to allow things like u''.format('') */
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ goto done;
+ if (!(PyBytes_Check(format_spec) || PyUnicode_Check(format_spec))) {
+ PyErr_Format(PyExc_TypeError, "__format__ arg must be str "
+ "or unicode, not %s", Py_TYPE(format_spec)->tp_name);
+ goto done;
+ }
+ tmp = PyObject_Unicode(format_spec);
+ if (tmp == NULL)
+ goto done;
+ format_spec = tmp;
+
+ result = _PyUnicode_FormatAdvanced(self,
+ PyUnicode_AS_UNICODE(format_spec),
+ PyUnicode_GET_SIZE(format_spec));
+ done:
+ Py_XDECREF(tmp);
+ return result;
+}
+
+PyDoc_STRVAR(p_format__doc__,
+ "S.__format__(format_spec) -> unicode\n\
+\n\
+Return a formatted version of S as described by format_spec.");
+
+static PyObject *
+unicode__sizeof__(PyUnicodeObject *v)
+{
+ return PyInt_FromSsize_t(sizeof(PyUnicodeObject) +
+ sizeof(Py_UNICODE) * (v->length + 1));
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+ "S.__sizeof__() -> size of S in memory, in bytes\n\
+\n\
+");
+
+static PyObject *
+unicode_getnewargs(PyUnicodeObject *v)
+{
+ return Py_BuildValue("(u#)", v->str, v->length);
+}
+
+
+static PyMethodDef unicode_methods[] = {
+ {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
+ {"replace", (PyCFunction) unicode_replace, METH_VARARGS, replace__doc__},
+ {"split", (PyCFunction) unicode_split, METH_VARARGS, split__doc__},
+ {"rsplit", (PyCFunction) unicode_rsplit, METH_VARARGS, rsplit__doc__},
+ {"join", (PyCFunction) unicode_join, METH_O, join__doc__},
+ {"capitalize", (PyCFunction) unicode_capitalize, METH_NOARGS, capitalize__doc__},
+ {"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__},
+ {"center", (PyCFunction) unicode_center, METH_VARARGS, center__doc__},
+ {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__},
+ {"expandtabs", (PyCFunction) unicode_expandtabs, METH_VARARGS, expandtabs__doc__},
+ {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__},
+ {"partition", (PyCFunction) unicode_partition, METH_O, partition__doc__},
+ {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__},
+ {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__},
+ {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__},
+ {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__doc__},
+ {"decode", (PyCFunction) unicode_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
+/* {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS, maketrans__doc__}, */
+ {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__},
+ {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__},
+ {"rjust", (PyCFunction) unicode_rjust, METH_VARARGS, rjust__doc__},
+ {"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__doc__},
+ {"rpartition", (PyCFunction) unicode_rpartition, METH_O, rpartition__doc__},
+ {"splitlines", (PyCFunction) unicode_splitlines, METH_VARARGS, splitlines__doc__},
+ {"strip", (PyCFunction) unicode_strip, METH_VARARGS, strip__doc__},
+ {"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__},
+ {"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__},
+ {"upper", (PyCFunction) unicode_upper, METH_NOARGS, upper__doc__},
+ {"startswith", (PyCFunction) unicode_startswith, METH_VARARGS, startswith__doc__},
+ {"endswith", (PyCFunction) unicode_endswith, METH_VARARGS, endswith__doc__},
+ {"islower", (PyCFunction) unicode_islower, METH_NOARGS, islower__doc__},
+ {"isupper", (PyCFunction) unicode_isupper, METH_NOARGS, isupper__doc__},
+ {"istitle", (PyCFunction) unicode_istitle, METH_NOARGS, istitle__doc__},
+ {"isspace", (PyCFunction) unicode_isspace, METH_NOARGS, isspace__doc__},
+ {"isdecimal", (PyCFunction) unicode_isdecimal, METH_NOARGS, isdecimal__doc__},
+ {"isdigit", (PyCFunction) unicode_isdigit, METH_NOARGS, isdigit__doc__},
+ {"isnumeric", (PyCFunction) unicode_isnumeric, METH_NOARGS, isnumeric__doc__},
+ {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
+ {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
+ {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
+ {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+ {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
+ {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
+ {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
+ {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
+#if 0
+ {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
+#endif
+
+#if 0
+ /* This one is just used for debugging the implementation. */
+ {"freelistsize", (PyCFunction) free_listsize, METH_NOARGS},
+#endif
+
+ {"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS},
+ {NULL, NULL}
+};
+
+static PyObject *
+unicode_mod(PyObject *v, PyObject *w)
+{
+ if (!PyUnicode_Check(v)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ return PyUnicode_Format(v, w);
+}
+
+static PyNumberMethods unicode_as_number = {
+ 0, /*nb_add*/
+ 0, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ unicode_mod, /*nb_remainder*/
+};
+
+static PySequenceMethods unicode_as_sequence = {
+ (lenfunc) unicode_length, /* sq_length */
+ PyUnicode_Concat, /* sq_concat */
+ (ssizeargfunc) unicode_repeat, /* sq_repeat */
+ (ssizeargfunc) unicode_getitem, /* sq_item */
+ (ssizessizeargfunc) unicode_slice, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ PyUnicode_Contains, /* sq_contains */
+};
+
+static PyObject*
+unicode_subscript(PyUnicodeObject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyUnicode_GET_SIZE(self);
+ return unicode_getitem(self, i);
+ } else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
+ Py_UNICODE* source_buf;
+ Py_UNICODE* result_buf;
+ PyObject* result;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyUnicode_FromUnicode(NULL, 0);
+ } else if (start == 0 && step == 1 && slicelength == self->length &&
+ PyUnicode_CheckExact(self)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ } else if (step == 1) {
+ return PyUnicode_FromUnicode(self->str + start, slicelength);
+ } else {
+ source_buf = PyUnicode_AS_UNICODE((PyObject*)self);
+ result_buf = (Py_UNICODE *)PyObject_MALLOC(slicelength*
+ sizeof(Py_UNICODE));
+
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
+
+ for (cur = start, i = 0; i < slicelength; cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+
+ result = PyUnicode_FromUnicode(result_buf, slicelength);
+ PyObject_FREE(result_buf);
+ return result;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "string indices must be integers");
+ return NULL;
+ }
+}
+
+static PyMappingMethods unicode_as_mapping = {
+ (lenfunc)unicode_length, /* mp_length */
+ (binaryfunc)unicode_subscript, /* mp_subscript */
+ (objobjargproc)0, /* mp_ass_subscript */
+};
+
+static Py_ssize_t
+unicode_buffer_getreadbuf(PyUnicodeObject *self,
+ Py_ssize_t index,
+ const void **ptr)
+{
+ if (index != 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent unicode segment");
+ return -1;
+ }
+ *ptr = (void *) self->str;
+ return PyUnicode_GET_DATA_SIZE(self);
+}
+
+static Py_ssize_t
+unicode_buffer_getwritebuf(PyUnicodeObject *self, Py_ssize_t index,
+ const void **ptr)
+{
+ PyErr_SetString(PyExc_TypeError,
+ "cannot use unicode as modifiable buffer");
+ return -1;
+}
+
+static int
+unicode_buffer_getsegcount(PyUnicodeObject *self,
+ Py_ssize_t *lenp)
+{
+ if (lenp)
+ *lenp = PyUnicode_GET_DATA_SIZE(self);
+ return 1;
+}
+
+static Py_ssize_t
+unicode_buffer_getcharbuf(PyUnicodeObject *self,
+ Py_ssize_t index,
+ const void **ptr)
+{
+ PyObject *str;
+
+ if (index != 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent unicode segment");
+ return -1;
+ }
+ str = _PyUnicode_AsDefaultEncodedString((PyObject *)self, NULL);
+ if (str == NULL)
+ return -1;
+ *ptr = (void *) PyString_AS_STRING(str);
+ return PyString_GET_SIZE(str);
+}
+
+/* Helpers for PyUnicode_Format() */
+
+static PyObject *
+getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
+{
+ Py_ssize_t argidx = *p_argidx;
+ if (argidx < arglen) {
+ (*p_argidx)++;
+ if (arglen < 0)
+ return args;
+ else
+ return PyTuple_GetItem(args, argidx);
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "not enough arguments for format string");
+ return NULL;
+}
+
+#define F_LJUST (1<<0)
+#define F_SIGN (1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT (1<<3)
+#define F_ZERO (1<<4)
+
+static Py_ssize_t
+strtounicode(Py_UNICODE *buffer, const char *charbuffer)
+{
+ register Py_ssize_t i;
+ Py_ssize_t len = strlen(charbuffer);
+ for (i = len - 1; i >= 0; i--)
+ buffer[i] = (Py_UNICODE) charbuffer[i];
+
+ return len;
+}
+
+static int
+longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
+{
+ Py_ssize_t result;
+
+ PyOS_snprintf((char *)buffer, len, format, x);
+ result = strtounicode(buffer, (char *)buffer);
+ return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
+}
+
+/* XXX To save some code duplication, formatfloat/long/int could have been
+ shared with stringobject.c, converting from 8-bit to Unicode after the
+ formatting is done. */
+
+/* Returns a new reference to a PyUnicode object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
+{
+ char *p;
+ PyObject *result;
+ double x;
+
+ x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+
+ if (prec < 0)
+ prec = 6;
+
+ p = PyOS_double_to_string(x, type, prec,
+ (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
+ if (p == NULL)
+ return NULL;
+ result = PyUnicode_FromStringAndSize(p, strlen(p));
+ PyMem_Free(p);
+ return result;
+}
+
+static PyObject*
+formatlong(PyObject *val, int flags, int prec, int type)
+{
+ char *buf;
+ int i, len;
+ PyObject *str; /* temporary string object. */
+ PyUnicodeObject *result;
+
+ str = _PyString_FormatLong(val, flags, prec, type, &buf, &len);
+ if (!str)
+ return NULL;
+ result = _PyUnicode_New(len);
+ if (!result) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ for (i = 0; i < len; i++)
+ result->str[i] = buf[i];
+ result->str[len] = 0;
+ Py_DECREF(str);
+ return (PyObject*)result;
+}
+
+static int
+formatint(Py_UNICODE *buf,
+ size_t buflen,
+ int flags,
+ int prec,
+ int type,
+ PyObject *v)
+{
+ /* fmt = '%#.' + `prec` + 'l' + `type`
+ * worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+ * + 1 + 1
+ * = 24
+ */
+ char fmt[64]; /* plenty big enough! */
+ char *sign;
+ long x;
+
+ x = PyInt_AsLong(v);
+ if (x == -1 && PyErr_Occurred())
+ return -1;
+ if (x < 0 && type == 'u') {
+ type = 'd';
+ }
+ if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
+ sign = "-";
+ else
+ sign = "";
+ if (prec < 0)
+ prec = 1;
+
+ /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
+ * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
+ */
+ if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
+ PyErr_SetString(PyExc_OverflowError,
+ "formatted integer is too long (precision too large?)");
+ return -1;
+ }
+
+ if ((flags & F_ALT) &&
+ (type == 'x' || type == 'X')) {
+ /* When converting under %#x or %#X, there are a number
+ * of issues that cause pain:
+ * - when 0 is being converted, the C standard leaves off
+ * the '0x' or '0X', which is inconsistent with other
+ * %#x/%#X conversions and inconsistent with Python's
+ * hex() function
+ * - there are platforms that violate the standard and
+ * convert 0 with the '0x' or '0X'
+ * (Metrowerks, Compaq Tru64)
+ * - there are platforms that give '0x' when converting
+ * under %#X, but convert 0 in accordance with the
+ * standard (OS/2 EMX)
+ *
+ * We can achieve the desired consistency by inserting our
+ * own '0x' or '0X' prefix, and substituting %x/%X in place
+ * of %#x/%#X.
+ *
+ * Note that this is the same approach as used in
+ * formatint() in stringobject.c
+ */
+ PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
+ sign, type, prec, type);
+ }
+ else {
+ PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
+ sign, (flags&F_ALT) ? "#" : "",
+ prec, type);
+ }
+ if (sign[0])
+ return longtounicode(buf, buflen, fmt, -x);
+ else
+ return longtounicode(buf, buflen, fmt, x);
+}
+
+static int
+formatchar(Py_UNICODE *buf,
+ size_t buflen,
+ PyObject *v)
+{
+ PyObject *unistr;
+ char *str;
+ /* presume that the buffer is at least 2 characters long */
+ if (PyUnicode_Check(v)) {
+ if (PyUnicode_GET_SIZE(v) != 1)
+ goto onError;
+ buf[0] = PyUnicode_AS_UNICODE(v)[0];
+ }
+
+ else if (PyString_Check(v)) {
+ if (PyString_GET_SIZE(v) != 1)
+ goto onError;
+ /* #7649: "u'%c' % char" should behave like "u'%s' % char" and fail
+ with a UnicodeDecodeError if 'char' is not decodable with the
+ default encoding (usually ASCII, but it might be something else) */
+ str = PyString_AS_STRING(v);
+ if ((unsigned char)str[0] > 0x7F) {
+ /* the char is not ASCII; try to decode the string using the
+ default encoding and return -1 to let the UnicodeDecodeError
+ be raised if the string can't be decoded */
+ unistr = PyUnicode_Decode(str, 1, NULL, "strict");
+ if (unistr == NULL)
+ return -1;
+ buf[0] = PyUnicode_AS_UNICODE(unistr)[0];
+ Py_DECREF(unistr);
+ }
+ else
+ buf[0] = (Py_UNICODE)str[0];
+ }
+
+ else {
+ /* Integer input truncated to a character */
+ long x;
+ x = PyInt_AsLong(v);
+ if (x == -1 && PyErr_Occurred())
+ goto onError;
+#ifdef Py_UNICODE_WIDE
+ if (x < 0 || x > 0x10ffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x110000) "
+ "(wide Python build)");
+ return -1;
+ }
+#else
+ if (x < 0 || x > 0xffff) {
+ PyErr_SetString(PyExc_OverflowError,
+ "%c arg not in range(0x10000) "
+ "(narrow Python build)");
+ return -1;
+ }
+#endif
+ buf[0] = (Py_UNICODE) x;
+ }
+ buf[1] = '\0';
+ return 1;
+
+ onError:
+ PyErr_SetString(PyExc_TypeError,
+ "%c requires int or char");
+ return -1;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
+
+ FORMATBUFLEN is the length of the buffer in which the ints &
+ chars are formatted. XXX This is a magic number. Each formatting
+ routine does bounds checking to ensure no overflow, but a better
+ solution may be to malloc a buffer of appropriate size for each
+ format. For now, the current solution is sufficient.
+*/
+#define FORMATBUFLEN (size_t)120
+
+PyObject *PyUnicode_Format(PyObject *format,
+ PyObject *args)
+{
+ Py_UNICODE *fmt, *res;
+ Py_ssize_t fmtcnt, rescnt, reslen, arglen, argidx;
+ int args_owned = 0;
+ PyUnicodeObject *result = NULL;
+ PyObject *dict = NULL;
+ PyObject *uformat;
+
+ if (format == NULL || args == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ uformat = PyUnicode_FromObject(format);
+ if (uformat == NULL)
+ return NULL;
+ fmt = PyUnicode_AS_UNICODE(uformat);
+ fmtcnt = PyUnicode_GET_SIZE(uformat);
+
+ reslen = rescnt = fmtcnt + 100;
+ result = _PyUnicode_New(reslen);
+ if (result == NULL)
+ goto onError;
+ res = PyUnicode_AS_UNICODE(result);
+
+ if (PyTuple_Check(args)) {
+ arglen = PyTuple_Size(args);
+ argidx = 0;
+ }
+ else {
+ arglen = -1;
+ argidx = -2;
+ }
+ if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript &&
+ !PyTuple_Check(args) && !PyObject_TypeCheck(args, &PyBaseString_Type))
+ dict = args;
+
+ while (--fmtcnt >= 0) {
+ if (*fmt != '%') {
+ if (--rescnt < 0) {
+ rescnt = fmtcnt + 100;
+ reslen += rescnt;
+ if (_PyUnicode_Resize(&result, reslen) < 0)
+ goto onError;
+ res = PyUnicode_AS_UNICODE(result) + reslen - rescnt;
+ --rescnt;
+ }
+ *res++ = *fmt++;
+ }
+ else {
+ /* Got a format specifier */
+ int flags = 0;
+ Py_ssize_t width = -1;
+ int prec = -1;
+ Py_UNICODE c = '\0';
+ Py_UNICODE fill;
+ int isnumok;
+ PyObject *v = NULL;
+ PyObject *temp = NULL;
+ Py_UNICODE *pbuf;
+ Py_UNICODE sign;
+ Py_ssize_t len;
+ Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{int,char}() */
+
+ fmt++;
+ if (*fmt == '(') {
+ Py_UNICODE *keystart;
+ Py_ssize_t keylen;
+ PyObject *key;
+ int pcount = 1;
+
+ if (dict == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "format requires a mapping");
+ goto onError;
+ }
+ ++fmt;
+ --fmtcnt;
+ keystart = fmt;
+ /* Skip over balanced parentheses */
+ while (pcount > 0 && --fmtcnt >= 0) {
+ if (*fmt == ')')
+ --pcount;
+ else if (*fmt == '(')
+ ++pcount;
+ fmt++;
+ }
+ keylen = fmt - keystart - 1;
+ if (fmtcnt < 0 || pcount > 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "incomplete format key");
+ goto onError;
+ }
+#if 0
+ /* keys are converted to strings using UTF-8 and
+ then looked up since Python uses strings to hold
+ variables names etc. in its namespaces and we
+ wouldn't want to break common idioms. */
+ key = PyUnicode_EncodeUTF8(keystart,
+ keylen,
+ NULL);
+#else
+ key = PyUnicode_FromUnicode(keystart, keylen);
+#endif
+ if (key == NULL)
+ goto onError;
+ if (args_owned) {
+ Py_DECREF(args);
+ args_owned = 0;
+ }
+ args = PyObject_GetItem(dict, key);
+ Py_DECREF(key);
+ if (args == NULL) {
+ goto onError;
+ }
+ args_owned = 1;
+ arglen = -1;
+ argidx = -2;
+ }
+ while (--fmtcnt >= 0) {
+ switch (c = *fmt++) {
+ case '-': flags |= F_LJUST; continue;
+ case '+': flags |= F_SIGN; continue;
+ case ' ': flags |= F_BLANK; continue;
+ case '#': flags |= F_ALT; continue;
+ case '0': flags |= F_ZERO; continue;
+ }
+ break;
+ }
+ if (c == '*') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto onError;
+ if (!PyInt_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "* wants int");
+ goto onError;
+ }
+ width = PyInt_AsSsize_t(v);
+ if (width == -1 && PyErr_Occurred())
+ goto onError;
+ if (width < 0) {
+ flags |= F_LJUST;
+ width = -width;
+ }
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ else if (c >= '0' && c <= '9') {
+ width = c - '0';
+ while (--fmtcnt >= 0) {
+ c = *fmt++;
+ if (c < '0' || c > '9')
+ break;
+ if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) {
+ PyErr_SetString(PyExc_ValueError,
+ "width too big");
+ goto onError;
+ }
+ width = width*10 + (c - '0');
+ }
+ }
+ if (c == '.') {
+ prec = 0;
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ if (c == '*') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto onError;
+ if (!PyInt_Check(v)) {
+ PyErr_SetString(PyExc_TypeError,
+ "* wants int");
+ goto onError;
+ }
+ prec = _PyInt_AsInt(v);
+ if (prec == -1 && PyErr_Occurred())
+ goto onError;
+ if (prec < 0)
+ prec = 0;
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ else if (c >= '0' && c <= '9') {
+ prec = c - '0';
+ while (--fmtcnt >= 0) {
+ c = *fmt++;
+ if (c < '0' || c > '9')
+ break;
+ if (prec > (INT_MAX - ((int)c - '0')) / 10) {
+ PyErr_SetString(PyExc_ValueError,
+ "prec too big");
+ goto onError;
+ }
+ prec = prec*10 + (c - '0');
+ }
+ }
+ } /* prec */
+ if (fmtcnt >= 0) {
+ if (c == 'h' || c == 'l' || c == 'L') {
+ if (--fmtcnt >= 0)
+ c = *fmt++;
+ }
+ }
+ if (fmtcnt < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "incomplete format");
+ goto onError;
+ }
+ if (c != '%') {
+ v = getnextarg(args, arglen, &argidx);
+ if (v == NULL)
+ goto onError;
+ }
+ sign = 0;
+ fill = ' ';
+ switch (c) {
+
+ case '%':
+ pbuf = formatbuf;
+ /* presume that buffer length is at least 1 */
+ pbuf[0] = '%';
+ len = 1;
+ break;
+
+ case 's':
+ case 'r':
+ if (PyUnicode_CheckExact(v) && c == 's') {
+ temp = v;
+ Py_INCREF(temp);
+ }
+ else {
+ PyObject *unicode;
+ if (c == 's')
+ temp = PyObject_Unicode(v);
+ else
+ temp = PyObject_Repr(v);
+ if (temp == NULL)
+ goto onError;
+ if (PyUnicode_Check(temp))
+ /* nothing to do */;
+ else if (PyString_Check(temp)) {
+ /* convert to string to Unicode */
+ unicode = PyUnicode_Decode(PyString_AS_STRING(temp),
+ PyString_GET_SIZE(temp),
+ NULL,
+ "strict");
+ Py_DECREF(temp);
+ temp = unicode;
+ if (temp == NULL)
+ goto onError;
+ }
+ else {
+ Py_DECREF(temp);
+ PyErr_SetString(PyExc_TypeError,
+ "%s argument has non-string str()");
+ goto onError;
+ }
+ }
+ pbuf = PyUnicode_AS_UNICODE(temp);
+ len = PyUnicode_GET_SIZE(temp);
+ if (prec >= 0 && len > prec)
+ len = prec;
+ break;
+
+ case 'i':
+ case 'd':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ if (c == 'i')
+ c = 'd';
+ isnumok = 0;
+ if (PyNumber_Check(v)) {
+ PyObject *iobj=NULL;
+
+ if (PyInt_Check(v) || (PyLong_Check(v))) {
+ iobj = v;
+ Py_INCREF(iobj);
+ }
+ else {
+ iobj = PyNumber_Int(v);
+ if (iobj==NULL) iobj = PyNumber_Long(v);
+ }
+ if (iobj!=NULL) {
+ if (PyInt_Check(iobj)) {
+ isnumok = 1;
+ pbuf = formatbuf;
+ len = formatint(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
+ flags, prec, c, iobj);
+ Py_DECREF(iobj);
+ if (len < 0)
+ goto onError;
+ sign = 1;
+ }
+ else if (PyLong_Check(iobj)) {
+ isnumok = 1;
+ temp = formatlong(iobj, flags, prec, c);
+ Py_DECREF(iobj);
+ if (!temp)
+ goto onError;
+ pbuf = PyUnicode_AS_UNICODE(temp);
+ len = PyUnicode_GET_SIZE(temp);
+ sign = 1;
+ }
+ else {
+ Py_DECREF(iobj);
+ }
+ }
+ }
+ if (!isnumok) {
+ PyErr_Format(PyExc_TypeError,
+ "%%%c format: a number is required, "
+ "not %.200s", (char)c, Py_TYPE(v)->tp_name);
+ goto onError;
+ }
+ if (flags & F_ZERO)
+ fill = '0';
+ break;
+
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ temp = formatfloat(v, flags, prec, c);
+ if (temp == NULL)
+ goto onError;
+ pbuf = PyUnicode_AS_UNICODE(temp);
+ len = PyUnicode_GET_SIZE(temp);
+ sign = 1;
+ if (flags & F_ZERO)
+ fill = '0';
+ break;
+
+ case 'c':
+ pbuf = formatbuf;
+ len = formatchar(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE), v);
+ if (len < 0)
+ goto onError;
+ break;
+
+ default:
+ PyErr_Format(PyExc_ValueError,
+ "unsupported format character '%c' (0x%x) "
+ "at index %zd",
+ (31<=c && c<=126) ? (char)c : '?',
+ (int)c,
+ (Py_ssize_t)(fmt - 1 -
+ PyUnicode_AS_UNICODE(uformat)));
+ goto onError;
+ }
+ if (sign) {
+ if (*pbuf == '-' || *pbuf == '+') {
+ sign = *pbuf++;
+ len--;
+ }
+ else if (flags & F_SIGN)
+ sign = '+';
+ else if (flags & F_BLANK)
+ sign = ' ';
+ else
+ sign = 0;
+ }
+ if (width < len)
+ width = len;
+ if (rescnt - (sign != 0) < width) {
+ reslen -= rescnt;
+ rescnt = width + fmtcnt + 100;
+ reslen += rescnt;
+ if (reslen < 0) {
+ Py_XDECREF(temp);
+ PyErr_NoMemory();
+ goto onError;
+ }
+ if (_PyUnicode_Resize(&result, reslen) < 0) {
+ Py_XDECREF(temp);
+ goto onError;
+ }
+ res = PyUnicode_AS_UNICODE(result)
+ + reslen - rescnt;
+ }
+ if (sign) {
+ if (fill != ' ')
+ *res++ = sign;
+ rescnt--;
+ if (width > len)
+ width--;
+ }
+ if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+ assert(pbuf[0] == '0');
+ assert(pbuf[1] == c);
+ if (fill != ' ') {
+ *res++ = *pbuf++;
+ *res++ = *pbuf++;
+ }
+ rescnt -= 2;
+ width -= 2;
+ if (width < 0)
+ width = 0;
+ len -= 2;
+ }
+ if (width > len && !(flags & F_LJUST)) {
+ do {
+ --rescnt;
+ *res++ = fill;
+ } while (--width > len);
+ }
+ if (fill == ' ') {
+ if (sign)
+ *res++ = sign;
+ if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+ assert(pbuf[0] == '0');
+ assert(pbuf[1] == c);
+ *res++ = *pbuf++;
+ *res++ = *pbuf++;
+ }
+ }
+ Py_UNICODE_COPY(res, pbuf, len);
+ res += len;
+ rescnt -= len;
+ while (--width >= len) {
+ --rescnt;
+ *res++ = ' ';
+ }
+ if (dict && (argidx < arglen) && c != '%') {
+ PyErr_SetString(PyExc_TypeError,
+ "not all arguments converted during string formatting");
+ Py_XDECREF(temp);
+ goto onError;
+ }
+ Py_XDECREF(temp);
+ } /* '%' */
+ } /* until end */
+ if (argidx < arglen && !dict) {
+ PyErr_SetString(PyExc_TypeError,
+ "not all arguments converted during string formatting");
+ goto onError;
+ }
+
+ if (_PyUnicode_Resize(&result, reslen - rescnt) < 0)
+ goto onError;
+ if (args_owned) {
+ Py_DECREF(args);
+ }
+ Py_DECREF(uformat);
+ return (PyObject *)result;
+
+ onError:
+ Py_XDECREF(result);
+ Py_DECREF(uformat);
+ if (args_owned) {
+ Py_DECREF(args);
+ }
+ return NULL;
+}
+
+static PyBufferProcs unicode_as_buffer = {
+ (readbufferproc) unicode_buffer_getreadbuf,
+ (writebufferproc) unicode_buffer_getwritebuf,
+ (segcountproc) unicode_buffer_getsegcount,
+ (charbufferproc) unicode_buffer_getcharbuf,
+};
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *x = NULL;
+ static char *kwlist[] = {"string", "encoding", "errors", 0};
+ char *encoding = NULL;
+ char *errors = NULL;
+
+ if (type != &PyUnicode_Type)
+ return unicode_subtype_new(type, args, kwds);
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:unicode",
+ kwlist, &x, &encoding, &errors))
+ return NULL;
+ if (x == NULL)
+ return (PyObject *)_PyUnicode_New(0);
+ if (encoding == NULL && errors == NULL)
+ return PyObject_Unicode(x);
+ else
+ return PyUnicode_FromEncodedObject(x, encoding, errors);
+}
+
+static PyObject *
+unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyUnicodeObject *tmp, *pnew;
+ Py_ssize_t n;
+
+ assert(PyType_IsSubtype(type, &PyUnicode_Type));
+ tmp = (PyUnicodeObject *)unicode_new(&PyUnicode_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyUnicode_Check(tmp));
+ pnew = (PyUnicodeObject *) type->tp_alloc(type, n = tmp->length);
+ if (pnew == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ pnew->str = (Py_UNICODE*) PyObject_MALLOC(sizeof(Py_UNICODE) * (n+1));
+ if (pnew->str == NULL) {
+ _Py_ForgetReference((PyObject *)pnew);
+ PyObject_Del(pnew);
+ Py_DECREF(tmp);
+ return PyErr_NoMemory();
+ }
+ Py_UNICODE_COPY(pnew->str, tmp->str, n+1);
+ pnew->length = n;
+ pnew->hash = tmp->hash;
+ Py_DECREF(tmp);
+ return (PyObject *)pnew;
+}
+
+PyDoc_STRVAR(unicode_doc,
+ "unicode(object='') -> unicode object\n\
+unicode(string[, encoding[, errors]]) -> unicode object\n\
+\n\
+Create a new Unicode object from the given encoded string.\n\
+encoding defaults to the current default string encoding.\n\
+errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
+
+PyTypeObject PyUnicode_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "unicode", /* tp_name */
+ sizeof(PyUnicodeObject), /* tp_size */
+ 0, /* tp_itemsize */
+ /* Slots */
+ (destructor)unicode_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ unicode_repr, /* tp_repr */
+ &unicode_as_number, /* tp_as_number */
+ &unicode_as_sequence, /* tp_as_sequence */
+ &unicode_as_mapping, /* tp_as_mapping */
+ (hashfunc) unicode_hash, /* tp_hash*/
+ 0, /* tp_call*/
+ (reprfunc) unicode_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &unicode_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */
+ unicode_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ PyUnicode_RichCompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ unicode_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &PyBaseString_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ unicode_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+/* Initialize the Unicode implementation */
+
+void _PyUnicode_Init(void)
+{
+ /* XXX - move this array to unicodectype.c ? */
+ Py_UNICODE linebreak[] = {
+ 0x000A, /* LINE FEED */
+ 0x000D, /* CARRIAGE RETURN */
+ 0x001C, /* FILE SEPARATOR */
+ 0x001D, /* GROUP SEPARATOR */
+ 0x001E, /* RECORD SEPARATOR */
+ 0x0085, /* NEXT LINE */
+ 0x2028, /* LINE SEPARATOR */
+ 0x2029, /* PARAGRAPH SEPARATOR */
+ };
+
+ /* Init the implementation */
+ if (!unicode_empty) {
+ unicode_empty = _PyUnicode_New(0);
+ if (!unicode_empty)
+ return;
+ }
+
+ if (PyType_Ready(&PyUnicode_Type) < 0)
+ Py_FatalError("Can't initialize 'unicode'");
+
+ /* initialize the linebreak bloom filter */
+ bloom_linebreak = make_bloom_mask(
+ linebreak, sizeof(linebreak) / sizeof(linebreak[0])
+ );
+
+ PyType_Ready(&EncodingMapType);
+
+ if (PyType_Ready(&PyFieldNameIter_Type) < 0)
+ Py_FatalError("Can't initialize field name iterator type");
+
+ if (PyType_Ready(&PyFormatterIter_Type) < 0)
+ Py_FatalError("Can't initialize formatter iter type");
+}
+
+/* Finalize the Unicode implementation */
+
+int
+PyUnicode_ClearFreeList(void)
+{
+ int freelist_size = numfree;
+ PyUnicodeObject *u;
+
+ for (u = free_list; u != NULL;) {
+ PyUnicodeObject *v = u;
+ u = *(PyUnicodeObject **)u;
+ if (v->str)
+ PyObject_DEL(v->str);
+ Py_XDECREF(v->defenc);
+ PyObject_Del(v);
+ numfree--;
+ }
+ free_list = NULL;
+ assert(numfree == 0);
+ return freelist_size;
+}
+
+void
+_PyUnicode_Fini(void)
+{
+ int i;
+
+ Py_CLEAR(unicode_empty);
+
+ for (i = 0; i < 256; i++)
+ Py_CLEAR(unicode_latin1[i]);
+
+ (void)PyUnicode_ClearFreeList();
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodetype_db.h b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodetype_db.h
new file mode 100644
index 0000000000..0423400ed5
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/unicodetype_db.h
@@ -0,0 +1,3337 @@
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.6 */
+
+/* a list of unique character type descriptors */
+const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 32},
+ {0, 0, 0, 0, 0, 48},
+ {0, 0, 0, 0, 0, 518},
+ {0, 0, 0, 1, 1, 518},
+ {0, 0, 0, 2, 2, 518},
+ {0, 0, 0, 3, 3, 518},
+ {0, 0, 0, 4, 4, 518},
+ {0, 0, 0, 5, 5, 518},
+ {0, 0, 0, 6, 6, 518},
+ {0, 0, 0, 7, 7, 518},
+ {0, 0, 0, 8, 8, 518},
+ {0, 0, 0, 9, 9, 518},
+ {0, 32, 0, 0, 0, 129},
+ {65504, 0, 65504, 0, 0, 9},
+ {0, 0, 0, 0, 0, 9},
+ {0, 0, 0, 0, 2, 516},
+ {0, 0, 0, 0, 3, 516},
+ {743, 0, 743, 0, 0, 9},
+ {0, 0, 0, 0, 1, 516},
+ {0, 0, 0, 0, 0, 512},
+ {121, 0, 121, 0, 0, 9},
+ {0, 1, 0, 0, 0, 129},
+ {65535, 0, 65535, 0, 0, 9},
+ {0, 65337, 0, 0, 0, 129},
+ {65304, 0, 65304, 0, 0, 9},
+ {0, 65415, 0, 0, 0, 129},
+ {65236, 0, 65236, 0, 0, 9},
+ {195, 0, 195, 0, 0, 9},
+ {0, 210, 0, 0, 0, 129},
+ {0, 206, 0, 0, 0, 129},
+ {0, 205, 0, 0, 0, 129},
+ {0, 79, 0, 0, 0, 129},
+ {0, 202, 0, 0, 0, 129},
+ {0, 203, 0, 0, 0, 129},
+ {0, 207, 0, 0, 0, 129},
+ {97, 0, 97, 0, 0, 9},
+ {0, 211, 0, 0, 0, 129},
+ {0, 209, 0, 0, 0, 129},
+ {163, 0, 163, 0, 0, 9},
+ {0, 213, 0, 0, 0, 129},
+ {130, 0, 130, 0, 0, 9},
+ {0, 214, 0, 0, 0, 129},
+ {0, 218, 0, 0, 0, 129},
+ {0, 217, 0, 0, 0, 129},
+ {0, 219, 0, 0, 0, 129},
+ {0, 0, 0, 0, 0, 1},
+ {56, 0, 56, 0, 0, 9},
+ {0, 2, 1, 0, 0, 129},
+ {65535, 1, 0, 0, 0, 65},
+ {65534, 0, 65535, 0, 0, 9},
+ {65457, 0, 65457, 0, 0, 9},
+ {0, 65439, 0, 0, 0, 129},
+ {0, 65480, 0, 0, 0, 129},
+ {0, 65406, 0, 0, 0, 129},
+ {0, 10795, 0, 0, 0, 129},
+ {0, 65373, 0, 0, 0, 129},
+ {0, 10792, 0, 0, 0, 129},
+ {10815, 0, 10815, 0, 0, 9},
+ {0, 65341, 0, 0, 0, 129},
+ {0, 69, 0, 0, 0, 129},
+ {0, 71, 0, 0, 0, 129},
+ {10783, 0, 10783, 0, 0, 9},
+ {10780, 0, 10780, 0, 0, 9},
+ {10782, 0, 10782, 0, 0, 9},
+ {65326, 0, 65326, 0, 0, 9},
+ {65330, 0, 65330, 0, 0, 9},
+ {65331, 0, 65331, 0, 0, 9},
+ {65334, 0, 65334, 0, 0, 9},
+ {65333, 0, 65333, 0, 0, 9},
+ {65329, 0, 65329, 0, 0, 9},
+ {65327, 0, 65327, 0, 0, 9},
+ {65325, 0, 65325, 0, 0, 9},
+ {10743, 0, 10743, 0, 0, 9},
+ {10749, 0, 10749, 0, 0, 9},
+ {65323, 0, 65323, 0, 0, 9},
+ {65322, 0, 65322, 0, 0, 9},
+ {10727, 0, 10727, 0, 0, 9},
+ {65318, 0, 65318, 0, 0, 9},
+ {65467, 0, 65467, 0, 0, 9},
+ {65319, 0, 65319, 0, 0, 9},
+ {65465, 0, 65465, 0, 0, 9},
+ {65317, 0, 65317, 0, 0, 9},
+ {84, 0, 84, 0, 0, 0},
+ {0, 38, 0, 0, 0, 129},
+ {0, 37, 0, 0, 0, 129},
+ {0, 64, 0, 0, 0, 129},
+ {0, 63, 0, 0, 0, 129},
+ {65498, 0, 65498, 0, 0, 9},
+ {65499, 0, 65499, 0, 0, 9},
+ {65505, 0, 65505, 0, 0, 9},
+ {65472, 0, 65472, 0, 0, 9},
+ {65473, 0, 65473, 0, 0, 9},
+ {0, 8, 0, 0, 0, 129},
+ {65474, 0, 65474, 0, 0, 9},
+ {65479, 0, 65479, 0, 0, 9},
+ {0, 0, 0, 0, 0, 129},
+ {65489, 0, 65489, 0, 0, 9},
+ {65482, 0, 65482, 0, 0, 9},
+ {65528, 0, 65528, 0, 0, 9},
+ {65450, 0, 65450, 0, 0, 9},
+ {65456, 0, 65456, 0, 0, 9},
+ {7, 0, 7, 0, 0, 9},
+ {0, 65476, 0, 0, 0, 129},
+ {65440, 0, 65440, 0, 0, 9},
+ {0, 65529, 0, 0, 0, 129},
+ {0, 80, 0, 0, 0, 129},
+ {0, 15, 0, 0, 0, 129},
+ {65521, 0, 65521, 0, 0, 9},
+ {0, 48, 0, 0, 0, 129},
+ {65488, 0, 65488, 0, 0, 9},
+ {0, 7264, 0, 0, 0, 129},
+ {0, 0, 0, 0, 4, 516},
+ {0, 0, 0, 0, 5, 516},
+ {0, 0, 0, 0, 6, 516},
+ {0, 0, 0, 0, 7, 516},
+ {0, 0, 0, 0, 8, 516},
+ {0, 0, 0, 0, 9, 516},
+ {42877, 7545, 42877, 0, 0, 265},
+ {3814, 0, 3814, 0, 0, 9},
+ {65477, 0, 65477, 0, 0, 9},
+ {0, 57921, 0, 0, 0, 129},
+ {8, 0, 8, 0, 0, 9},
+ {0, 65528, 0, 0, 0, 129},
+ {74, 0, 74, 0, 0, 9},
+ {86, 0, 86, 0, 0, 9},
+ {100, 0, 100, 0, 0, 9},
+ {128, 0, 128, 0, 0, 9},
+ {112, 0, 112, 0, 0, 9},
+ {126, 0, 126, 0, 0, 9},
+ {0, 65528, 0, 0, 0, 65},
+ {9, 0, 9, 0, 0, 9},
+ {0, 65462, 0, 0, 0, 129},
+ {0, 65527, 0, 0, 0, 65},
+ {58331, 0, 58331, 0, 0, 9},
+ {0, 65450, 0, 0, 0, 129},
+ {0, 65436, 0, 0, 0, 129},
+ {0, 65424, 0, 0, 0, 129},
+ {0, 65408, 0, 0, 0, 129},
+ {0, 65410, 0, 0, 0, 129},
+ {0, 0, 0, 0, 0, 516},
+ {0, 58019, 0, 0, 0, 129},
+ {0, 57153, 0, 0, 0, 129},
+ {0, 57274, 0, 0, 0, 129},
+ {0, 28, 0, 0, 0, 129},
+ {65508, 0, 65508, 0, 0, 9},
+ {0, 16, 0, 0, 0, 512},
+ {65520, 0, 65520, 0, 0, 512},
+ {0, 26, 0, 0, 0, 0},
+ {65510, 0, 65510, 0, 0, 0},
+ {0, 54793, 0, 0, 0, 129},
+ {0, 61722, 0, 0, 0, 129},
+ {0, 54809, 0, 0, 0, 129},
+ {54741, 0, 54741, 0, 0, 9},
+ {54744, 0, 54744, 0, 0, 9},
+ {0, 54756, 0, 0, 0, 129},
+ {0, 54787, 0, 0, 0, 129},
+ {0, 54753, 0, 0, 0, 129},
+ {0, 54754, 0, 0, 0, 129},
+ {0, 54721, 0, 0, 0, 129},
+ {58272, 0, 58272, 0, 0, 9},
+ {0, 0, 0, 0, 0, 513},
+ {42877, 7545, 42877, 0, 0, 385},
+ {0, 40, 0, 0, 0, 129},
+ {65496, 0, 65496, 0, 0, 9},
+};
+
+/* type indexes */
+#define SHIFT 7
+static unsigned char index1[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37,
+ 38, 39, 34, 34, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 65, 66, 67, 64,
+ 64, 64, 68, 69, 70, 64, 64, 64, 64, 64, 64, 71, 17, 72, 73, 74, 75, 76,
+ 77, 64, 78, 79, 80, 81, 82, 83, 84, 64, 64, 85, 86, 34, 34, 34, 34, 34,
+ 34, 87, 34, 34, 34, 34, 34, 88, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 89, 90, 91, 92, 34, 34, 34, 93, 34, 34,
+ 34, 94, 95, 34, 34, 34, 34, 34, 96, 34, 34, 34, 97, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 98, 99, 100, 34, 34, 34, 34, 34, 34, 101, 102, 34,
+ 34, 34, 34, 34, 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34,
+ 101, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 106, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 107, 108, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 109, 110, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 111, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 112, 34, 34, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 17, 123, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 124, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 125, 126, 127, 128,
+ 129, 130, 34, 34, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 17,
+ 141, 142, 143, 144, 145, 17, 17, 17, 17, 17, 17, 146, 17, 147, 17, 148,
+ 17, 149, 17, 150, 17, 17, 17, 151, 17, 17, 17, 17, 152, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 153, 17, 154, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 155, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 64, 156, 157, 158, 159, 17, 160, 17, 161, 162, 163, 164, 165, 166, 167,
+ 168, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 169, 170, 171, 172,
+ 173, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 174, 175, 176, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 177, 34, 178, 179, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 180, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 181, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 182, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 183, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 184, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 185, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 34, 180, 34, 34, 186, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 187, 17, 64, 188, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 189, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 189,
+};
+
+static unsigned char index2[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1,
+ 1, 1, 1, 1, 17, 18, 1, 19, 1, 1, 1, 20, 16, 1, 21, 21, 21, 1, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 16, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15,
+ 15, 15, 15, 15, 15, 15, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 25, 26, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 27, 23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24,
+ 32, 32, 23, 24, 16, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40,
+ 16, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 16, 16, 23,
+ 24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 16, 47, 23, 24, 16,
+ 48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 52, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 49, 50, 51, 23,
+ 24, 53, 54, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 55, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 16, 16, 16, 16, 16, 56, 23, 24,
+ 57, 58, 59, 59, 23, 24, 60, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 63, 64, 65, 66, 67, 16, 68, 68, 16, 69, 16, 70, 16, 16, 16, 16, 68,
+ 16, 16, 71, 16, 16, 16, 16, 72, 73, 16, 74, 16, 16, 16, 73, 16, 75, 76,
+ 16, 16, 77, 16, 16, 16, 16, 16, 16, 16, 78, 16, 16, 79, 16, 16, 79, 16,
+ 16, 16, 16, 79, 80, 81, 81, 82, 16, 16, 16, 16, 16, 83, 16, 47, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 47, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24,
+ 23, 24, 47, 1, 23, 24, 0, 0, 47, 42, 42, 42, 1, 0, 0, 0, 0, 0, 1, 1, 85,
+ 1, 86, 86, 86, 0, 87, 0, 88, 88, 16, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 89, 90, 90, 90, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 93, 93, 94,
+ 95, 96, 97, 97, 97, 98, 99, 100, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 101, 102, 103,
+ 16, 104, 105, 1, 23, 24, 106, 23, 24, 16, 55, 55, 55, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 108, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 109, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 47, 1, 1, 1, 1, 1, 1, 0,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 16, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 1, 1, 1, 1, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 1, 1, 47,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1, 47, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 1, 1, 47, 1, 1, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 47, 1,
+ 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47,
+ 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0,
+ 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47, 47, 1,
+ 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 1, 1, 21, 21, 21, 21,
+ 21, 21, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47,
+ 0, 47, 47, 0, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
+ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 0, 47, 0, 0, 0,
+ 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 47, 47, 47, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 0, 1, 1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,
+ 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0,
+ 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47,
+ 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47,
+ 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 0, 47, 47, 47, 47, 47, 47, 0, 0,
+ 0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 0,
+ 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1,
+ 1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 0, 0, 0, 0, 0, 0,
+ 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 21, 21, 21, 21, 21, 21, 21, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 47, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 0, 0, 1, 1,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 0,
+ 0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0,
+ 47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 1, 1, 1, 1, 1, 1, 0, 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 47, 47, 47, 47, 1, 1, 1, 47, 1, 1, 1, 47, 47, 1, 1, 1, 1, 1, 1, 1, 47,
+ 47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 1, 1, 1, 1, 1, 1, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115,
+ 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 21, 21, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 47, 47, 47, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 47, 1, 1, 1, 1, 47, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1,
+ 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 5, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 47, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 0, 0, 0, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 47, 119, 16, 16, 16, 120, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 16, 16, 16, 16, 16, 121, 16, 16, 122, 16, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 123,
+ 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 124,
+ 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124, 124, 124, 124, 0,
+ 0, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124,
+ 124, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124,
+ 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124,
+ 124, 124, 124, 0, 0, 16, 123, 16, 123, 16, 123, 16, 123, 0, 124, 0, 124,
+ 0, 124, 0, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124,
+ 124, 124, 124, 124, 124, 125, 125, 126, 126, 126, 126, 127, 127, 128,
+ 128, 129, 129, 130, 130, 0, 0, 123, 123, 123, 123, 123, 123, 123, 123,
+ 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123, 123, 123,
+ 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123,
+ 123, 123, 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 16,
+ 132, 16, 0, 16, 16, 124, 124, 133, 133, 134, 1, 135, 1, 1, 1, 16, 132,
+ 16, 0, 16, 16, 136, 136, 136, 136, 134, 1, 1, 1, 123, 123, 16, 16, 0, 0,
+ 16, 16, 124, 124, 137, 137, 0, 1, 1, 1, 123, 123, 16, 16, 16, 103, 16,
+ 16, 124, 124, 138, 138, 106, 1, 1, 1, 0, 0, 16, 132, 16, 0, 16, 16, 139,
+ 139, 140, 140, 134, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 141, 47, 0, 0, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 47, 141,
+ 20, 17, 18, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 0, 47, 47, 47,
+ 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 97, 1, 1, 1, 1, 97, 1, 1,
+ 16, 97, 97, 97, 16, 16, 97, 97, 97, 16, 1, 97, 1, 1, 1, 97, 97, 97, 97,
+ 97, 1, 1, 1, 1, 1, 1, 97, 1, 142, 1, 97, 1, 143, 144, 97, 97, 1, 16, 97,
+ 97, 145, 97, 16, 47, 47, 47, 47, 16, 1, 1, 16, 16, 97, 97, 1, 1, 1, 1, 1,
+ 97, 16, 16, 16, 16, 1, 1, 1, 1, 146, 1, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 147, 147, 147, 147, 147, 147, 147, 147,
+ 147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148,
+ 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 21, 21, 21, 23, 24, 21,
+ 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113,
+ 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,
+ 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
+ 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
+ 141, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 17, 18, 113, 114, 115,
+ 116, 117, 118, 21, 141, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
+ 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115, 116,
+ 117, 118, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 20, 17, 18,
+ 113, 114, 115, 116, 117, 118, 21, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 0,
+ 23, 24, 151, 152, 153, 154, 155, 23, 24, 23, 24, 23, 24, 156, 157, 158,
+ 159, 16, 23, 24, 16, 23, 24, 16, 16, 16, 16, 16, 16, 47, 160, 160, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 21, 1, 1, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0,
+ 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 47, 47, 21, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 1, 1, 21, 21,
+ 21, 47, 47, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 0, 1, 1, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 1, 21, 21, 21, 21, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 162, 47, 47, 162,
+ 47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47,
+ 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 162,
+ 162, 162, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 162, 162, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162, 162, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 47, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 16, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 47, 16, 16, 16, 16,
+ 16, 16, 16, 16, 23, 24, 23, 24, 163, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 47, 1, 1, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 1, 47, 47, 47, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 0, 0, 0, 0, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 1, 1, 1,
+ 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 1, 47, 1, 1, 1, 47, 47, 1, 1, 47, 47, 47, 47,
+ 47, 1, 1, 47, 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1,
+ 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47,
+ 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 21, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21,
+ 47, 47, 47, 47, 47, 47, 47, 47, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 21,
+ 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21,
+ 21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 1, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 20,
+ 17, 18, 113, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 21, 21, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 21, 21, 21,
+ 21, 21, 21, 21, 21, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 0, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16,
+ 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 97, 0, 97, 97, 0, 0, 97, 0, 0, 97, 97, 0, 0, 97, 97, 97, 97, 0,
+ 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 0, 16, 0, 16, 16, 16, 16,
+ 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97,
+ 97, 97, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 0, 97, 97, 97, 97, 97, 97,
+ 97, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97, 97, 97, 0, 97,
+ 97, 97, 97, 97, 0, 97, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 0, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16,
+ 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16,
+ 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97,
+ 16, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 141, 141, 20, 17, 18, 113, 114, 115, 116, 117, 118, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+};
+
+/* Returns the numeric value as double for Unicode characters
+ * having this property, -1.0 otherwise.
+ */
+double _PyUnicode_ToNumeric(Py_UNICODE ch)
+{
+ switch (ch) {
+ case 0x0F33:
+ return (double) -1.0/2.0;
+ case 0x0030:
+ case 0x0660:
+ case 0x06F0:
+ case 0x07C0:
+ case 0x0966:
+ case 0x09E6:
+ case 0x0A66:
+ case 0x0AE6:
+ case 0x0B66:
+ case 0x0BE6:
+ case 0x0C66:
+ case 0x0C78:
+ case 0x0CE6:
+ case 0x0D66:
+ case 0x0E50:
+ case 0x0ED0:
+ case 0x0F20:
+ case 0x1040:
+ case 0x1090:
+ case 0x17E0:
+ case 0x17F0:
+ case 0x1810:
+ case 0x1946:
+ case 0x19D0:
+ case 0x1A80:
+ case 0x1A90:
+ case 0x1B50:
+ case 0x1BB0:
+ case 0x1C40:
+ case 0x1C50:
+ case 0x2070:
+ case 0x2080:
+ case 0x2189:
+ case 0x24EA:
+ case 0x24FF:
+ case 0x3007:
+ case 0x96F6:
+ case 0xA620:
+ case 0xA6EF:
+ case 0xA8D0:
+ case 0xA900:
+ case 0xA9D0:
+ case 0xAA50:
+ case 0xABF0:
+ case 0xF9B2:
+ case 0xFF10:
+#ifdef Py_UNICODE_WIDE
+ case 0x1018A:
+ case 0x104A0:
+ case 0x1D7CE:
+ case 0x1D7D8:
+ case 0x1D7E2:
+ case 0x1D7EC:
+ case 0x1D7F6:
+ case 0x1F100:
+ case 0x1F101:
+#endif
+ return (double) 0.0;
+ case 0x0031:
+ case 0x00B9:
+ case 0x0661:
+ case 0x06F1:
+ case 0x07C1:
+ case 0x0967:
+ case 0x09E7:
+ case 0x0A67:
+ case 0x0AE7:
+ case 0x0B67:
+ case 0x0BE7:
+ case 0x0C67:
+ case 0x0C79:
+ case 0x0C7C:
+ case 0x0CE7:
+ case 0x0D67:
+ case 0x0E51:
+ case 0x0ED1:
+ case 0x0F21:
+ case 0x1041:
+ case 0x1091:
+ case 0x1369:
+ case 0x17E1:
+ case 0x17F1:
+ case 0x1811:
+ case 0x1947:
+ case 0x19D1:
+ case 0x19DA:
+ case 0x1A81:
+ case 0x1A91:
+ case 0x1B51:
+ case 0x1BB1:
+ case 0x1C41:
+ case 0x1C51:
+ case 0x2081:
+ case 0x215F:
+ case 0x2160:
+ case 0x2170:
+ case 0x2460:
+ case 0x2474:
+ case 0x2488:
+ case 0x24F5:
+ case 0x2776:
+ case 0x2780:
+ case 0x278A:
+ case 0x3021:
+ case 0x3192:
+ case 0x3220:
+ case 0x3280:
+ case 0x4E00:
+ case 0x58F1:
+ case 0x58F9:
+ case 0x5E7A:
+ case 0x5F0C:
+ case 0xA621:
+ case 0xA6E6:
+ case 0xA8D1:
+ case 0xA901:
+ case 0xA9D1:
+ case 0xAA51:
+ case 0xABF1:
+ case 0xFF11:
+#ifdef Py_UNICODE_WIDE
+ case 0x10107:
+ case 0x10142:
+ case 0x10158:
+ case 0x10159:
+ case 0x1015A:
+ case 0x10320:
+ case 0x103D1:
+ case 0x104A1:
+ case 0x10858:
+ case 0x10916:
+ case 0x10A40:
+ case 0x10A7D:
+ case 0x10B58:
+ case 0x10B78:
+ case 0x10E60:
+ case 0x12415:
+ case 0x1241E:
+ case 0x1242C:
+ case 0x12434:
+ case 0x1244F:
+ case 0x12458:
+ case 0x1D360:
+ case 0x1D7CF:
+ case 0x1D7D9:
+ case 0x1D7E3:
+ case 0x1D7ED:
+ case 0x1D7F7:
+ case 0x1F102:
+ case 0x2092A:
+#endif
+ return (double) 1.0;
+ case 0x2152:
+ return (double) 1.0/10.0;
+ case 0x09F4:
+ case 0xA833:
+ return (double) 1.0/16.0;
+ case 0x00BD:
+ case 0x0D74:
+ case 0x0F2A:
+ case 0x2CFD:
+ case 0xA831:
+#ifdef Py_UNICODE_WIDE
+ case 0x10141:
+ case 0x10175:
+ case 0x10176:
+ case 0x10E7B:
+#endif
+ return (double) 1.0/2.0;
+ case 0x2153:
+#ifdef Py_UNICODE_WIDE
+ case 0x10E7D:
+ case 0x1245A:
+ case 0x1245D:
+#endif
+ return (double) 1.0/3.0;
+ case 0x00BC:
+ case 0x09F7:
+ case 0x0D73:
+ case 0xA830:
+#ifdef Py_UNICODE_WIDE
+ case 0x10140:
+ case 0x10E7C:
+ case 0x12460:
+ case 0x12462:
+#endif
+ return (double) 1.0/4.0;
+ case 0x2155:
+ return (double) 1.0/5.0;
+ case 0x2159:
+#ifdef Py_UNICODE_WIDE
+ case 0x12461:
+#endif
+ return (double) 1.0/6.0;
+ case 0x2150:
+ return (double) 1.0/7.0;
+ case 0x09F5:
+ case 0x215B:
+ case 0xA834:
+#ifdef Py_UNICODE_WIDE
+ case 0x1245F:
+#endif
+ return (double) 1.0/8.0;
+ case 0x2151:
+ return (double) 1.0/9.0;
+ case 0x0BF0:
+ case 0x0D70:
+ case 0x1372:
+ case 0x2169:
+ case 0x2179:
+ case 0x2469:
+ case 0x247D:
+ case 0x2491:
+ case 0x24FE:
+ case 0x277F:
+ case 0x2789:
+ case 0x2793:
+ case 0x3038:
+ case 0x3229:
+ case 0x3289:
+ case 0x4EC0:
+ case 0x5341:
+ case 0x62FE:
+ case 0xF973:
+ case 0xF9FD:
+#ifdef Py_UNICODE_WIDE
+ case 0x10110:
+ case 0x10149:
+ case 0x10150:
+ case 0x10157:
+ case 0x10160:
+ case 0x10161:
+ case 0x10162:
+ case 0x10163:
+ case 0x10164:
+ case 0x10322:
+ case 0x103D3:
+ case 0x1085B:
+ case 0x10917:
+ case 0x10A44:
+ case 0x10B5C:
+ case 0x10B7C:
+ case 0x10E69:
+ case 0x1D369:
+#endif
+ return (double) 10.0;
+ case 0x0BF1:
+ case 0x0D71:
+ case 0x137B:
+ case 0x216D:
+ case 0x217D:
+ case 0x4F70:
+ case 0x767E:
+ case 0x964C:
+#ifdef Py_UNICODE_WIDE
+ case 0x10119:
+ case 0x1014B:
+ case 0x10152:
+ case 0x1016A:
+ case 0x103D5:
+ case 0x1085D:
+ case 0x10919:
+ case 0x10A46:
+ case 0x10B5E:
+ case 0x10B7E:
+ case 0x10E72:
+#endif
+ return (double) 100.0;
+ case 0x0BF2:
+ case 0x0D72:
+ case 0x216F:
+ case 0x217F:
+ case 0x2180:
+ case 0x4EDF:
+ case 0x5343:
+ case 0x9621:
+#ifdef Py_UNICODE_WIDE
+ case 0x10122:
+ case 0x1014D:
+ case 0x10154:
+ case 0x10171:
+ case 0x1085E:
+ case 0x10A47:
+ case 0x10B5F:
+ case 0x10B7F:
+#endif
+ return (double) 1000.0;
+ case 0x137C:
+ case 0x2182:
+ case 0x4E07:
+ case 0x842C:
+#ifdef Py_UNICODE_WIDE
+ case 0x1012B:
+ case 0x10155:
+ case 0x1085F:
+#endif
+ return (double) 10000.0;
+ case 0x2188:
+ return (double) 100000.0;
+ case 0x4EBF:
+ case 0x5104:
+ return (double) 100000000.0;
+ case 0x5146:
+ return (double) 1000000000000.0;
+ case 0x216A:
+ case 0x217A:
+ case 0x246A:
+ case 0x247E:
+ case 0x2492:
+ case 0x24EB:
+ return (double) 11.0;
+ case 0x0F2F:
+ return (double) 11.0/2.0;
+ case 0x216B:
+ case 0x217B:
+ case 0x246B:
+ case 0x247F:
+ case 0x2493:
+ case 0x24EC:
+ return (double) 12.0;
+ case 0x246C:
+ case 0x2480:
+ case 0x2494:
+ case 0x24ED:
+ return (double) 13.0;
+ case 0x0F30:
+ return (double) 13.0/2.0;
+ case 0x246D:
+ case 0x2481:
+ case 0x2495:
+ case 0x24EE:
+ return (double) 14.0;
+ case 0x246E:
+ case 0x2482:
+ case 0x2496:
+ case 0x24EF:
+ return (double) 15.0;
+ case 0x0F31:
+ return (double) 15.0/2.0;
+ case 0x09F9:
+ case 0x246F:
+ case 0x2483:
+ case 0x2497:
+ case 0x24F0:
+ return (double) 16.0;
+ case 0x16EE:
+ case 0x2470:
+ case 0x2484:
+ case 0x2498:
+ case 0x24F1:
+ return (double) 17.0;
+ case 0x0F32:
+ return (double) 17.0/2.0;
+ case 0x16EF:
+ case 0x2471:
+ case 0x2485:
+ case 0x2499:
+ case 0x24F2:
+ return (double) 18.0;
+ case 0x16F0:
+ case 0x2472:
+ case 0x2486:
+ case 0x249A:
+ case 0x24F3:
+ return (double) 19.0;
+ case 0x0032:
+ case 0x00B2:
+ case 0x0662:
+ case 0x06F2:
+ case 0x07C2:
+ case 0x0968:
+ case 0x09E8:
+ case 0x0A68:
+ case 0x0AE8:
+ case 0x0B68:
+ case 0x0BE8:
+ case 0x0C68:
+ case 0x0C7A:
+ case 0x0C7D:
+ case 0x0CE8:
+ case 0x0D68:
+ case 0x0E52:
+ case 0x0ED2:
+ case 0x0F22:
+ case 0x1042:
+ case 0x1092:
+ case 0x136A:
+ case 0x17E2:
+ case 0x17F2:
+ case 0x1812:
+ case 0x1948:
+ case 0x19D2:
+ case 0x1A82:
+ case 0x1A92:
+ case 0x1B52:
+ case 0x1BB2:
+ case 0x1C42:
+ case 0x1C52:
+ case 0x2082:
+ case 0x2161:
+ case 0x2171:
+ case 0x2461:
+ case 0x2475:
+ case 0x2489:
+ case 0x24F6:
+ case 0x2777:
+ case 0x2781:
+ case 0x278B:
+ case 0x3022:
+ case 0x3193:
+ case 0x3221:
+ case 0x3281:
+ case 0x3483:
+ case 0x4E8C:
+ case 0x5169:
+ case 0x5F0D:
+ case 0x5F10:
+ case 0x8CAE:
+ case 0x8CB3:
+ case 0x8D30:
+ case 0xA622:
+ case 0xA6E7:
+ case 0xA8D2:
+ case 0xA902:
+ case 0xA9D2:
+ case 0xAA52:
+ case 0xABF2:
+ case 0xF978:
+ case 0xFF12:
+#ifdef Py_UNICODE_WIDE
+ case 0x10108:
+ case 0x1015B:
+ case 0x1015C:
+ case 0x1015D:
+ case 0x1015E:
+ case 0x103D2:
+ case 0x104A2:
+ case 0x10859:
+ case 0x1091A:
+ case 0x10A41:
+ case 0x10B59:
+ case 0x10B79:
+ case 0x10E61:
+ case 0x12400:
+ case 0x12416:
+ case 0x1241F:
+ case 0x12423:
+ case 0x1242D:
+ case 0x12435:
+ case 0x1244A:
+ case 0x12450:
+ case 0x12459:
+ case 0x1D361:
+ case 0x1D7D0:
+ case 0x1D7DA:
+ case 0x1D7E4:
+ case 0x1D7EE:
+ case 0x1D7F8:
+ case 0x1F103:
+ case 0x22390:
+#endif
+ return (double) 2.0;
+ case 0x2154:
+#ifdef Py_UNICODE_WIDE
+ case 0x10177:
+ case 0x10E7E:
+ case 0x1245B:
+ case 0x1245E:
+#endif
+ return (double) 2.0/3.0;
+ case 0x2156:
+ return (double) 2.0/5.0;
+ case 0x1373:
+ case 0x2473:
+ case 0x2487:
+ case 0x249B:
+ case 0x24F4:
+ case 0x3039:
+ case 0x5344:
+ case 0x5EFF:
+#ifdef Py_UNICODE_WIDE
+ case 0x10111:
+ case 0x103D4:
+ case 0x1085C:
+ case 0x10918:
+ case 0x10A45:
+ case 0x10B5D:
+ case 0x10B7D:
+ case 0x10E6A:
+ case 0x1D36A:
+#endif
+ return (double) 20.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011A:
+ case 0x10E73:
+ return (double) 200.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10123:
+ return (double) 2000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012C:
+ return (double) 20000.0;
+#endif
+ case 0x3251:
+ return (double) 21.0;
+ case 0x3252:
+ return (double) 22.0;
+ case 0x3253:
+ return (double) 23.0;
+ case 0x3254:
+ return (double) 24.0;
+ case 0x3255:
+ return (double) 25.0;
+ case 0x3256:
+ return (double) 26.0;
+ case 0x3257:
+ return (double) 27.0;
+ case 0x3258:
+ return (double) 28.0;
+ case 0x3259:
+ return (double) 29.0;
+ case 0x0033:
+ case 0x00B3:
+ case 0x0663:
+ case 0x06F3:
+ case 0x07C3:
+ case 0x0969:
+ case 0x09E9:
+ case 0x0A69:
+ case 0x0AE9:
+ case 0x0B69:
+ case 0x0BE9:
+ case 0x0C69:
+ case 0x0C7B:
+ case 0x0C7E:
+ case 0x0CE9:
+ case 0x0D69:
+ case 0x0E53:
+ case 0x0ED3:
+ case 0x0F23:
+ case 0x1043:
+ case 0x1093:
+ case 0x136B:
+ case 0x17E3:
+ case 0x17F3:
+ case 0x1813:
+ case 0x1949:
+ case 0x19D3:
+ case 0x1A83:
+ case 0x1A93:
+ case 0x1B53:
+ case 0x1BB3:
+ case 0x1C43:
+ case 0x1C53:
+ case 0x2083:
+ case 0x2162:
+ case 0x2172:
+ case 0x2462:
+ case 0x2476:
+ case 0x248A:
+ case 0x24F7:
+ case 0x2778:
+ case 0x2782:
+ case 0x278C:
+ case 0x3023:
+ case 0x3194:
+ case 0x3222:
+ case 0x3282:
+ case 0x4E09:
+ case 0x4EE8:
+ case 0x53C1:
+ case 0x53C2:
+ case 0x53C3:
+ case 0x53C4:
+ case 0x5F0E:
+ case 0xA623:
+ case 0xA6E8:
+ case 0xA8D3:
+ case 0xA903:
+ case 0xA9D3:
+ case 0xAA53:
+ case 0xABF3:
+ case 0xF96B:
+ case 0xFF13:
+#ifdef Py_UNICODE_WIDE
+ case 0x10109:
+ case 0x104A3:
+ case 0x1085A:
+ case 0x1091B:
+ case 0x10A42:
+ case 0x10B5A:
+ case 0x10B7A:
+ case 0x10E62:
+ case 0x12401:
+ case 0x12408:
+ case 0x12417:
+ case 0x12420:
+ case 0x12424:
+ case 0x12425:
+ case 0x1242E:
+ case 0x1242F:
+ case 0x12436:
+ case 0x12437:
+ case 0x1243A:
+ case 0x1243B:
+ case 0x1244B:
+ case 0x12451:
+ case 0x1D362:
+ case 0x1D7D1:
+ case 0x1D7DB:
+ case 0x1D7E5:
+ case 0x1D7EF:
+ case 0x1D7F9:
+ case 0x1F104:
+ case 0x20AFD:
+ case 0x20B19:
+ case 0x22998:
+ case 0x23B1B:
+#endif
+ return (double) 3.0;
+ case 0x09F6:
+ case 0xA835:
+ return (double) 3.0/16.0;
+ case 0x0F2B:
+ return (double) 3.0/2.0;
+ case 0x00BE:
+ case 0x09F8:
+ case 0x0D75:
+ case 0xA832:
+#ifdef Py_UNICODE_WIDE
+ case 0x10178:
+#endif
+ return (double) 3.0/4.0;
+ case 0x2157:
+ return (double) 3.0/5.0;
+ case 0x215C:
+ return (double) 3.0/8.0;
+ case 0x1374:
+ case 0x303A:
+ case 0x325A:
+ case 0x5345:
+#ifdef Py_UNICODE_WIDE
+ case 0x10112:
+ case 0x10165:
+ case 0x10E6B:
+ case 0x1D36B:
+ case 0x20983:
+#endif
+ return (double) 30.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011B:
+ case 0x1016B:
+ case 0x10E74:
+ return (double) 300.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10124:
+ return (double) 3000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012D:
+ return (double) 30000.0;
+#endif
+ case 0x325B:
+ return (double) 31.0;
+ case 0x325C:
+ return (double) 32.0;
+ case 0x325D:
+ return (double) 33.0;
+ case 0x325E:
+ return (double) 34.0;
+ case 0x325F:
+ return (double) 35.0;
+ case 0x32B1:
+ return (double) 36.0;
+ case 0x32B2:
+ return (double) 37.0;
+ case 0x32B3:
+ return (double) 38.0;
+ case 0x32B4:
+ return (double) 39.0;
+ case 0x0034:
+ case 0x0664:
+ case 0x06F4:
+ case 0x07C4:
+ case 0x096A:
+ case 0x09EA:
+ case 0x0A6A:
+ case 0x0AEA:
+ case 0x0B6A:
+ case 0x0BEA:
+ case 0x0C6A:
+ case 0x0CEA:
+ case 0x0D6A:
+ case 0x0E54:
+ case 0x0ED4:
+ case 0x0F24:
+ case 0x1044:
+ case 0x1094:
+ case 0x136C:
+ case 0x17E4:
+ case 0x17F4:
+ case 0x1814:
+ case 0x194A:
+ case 0x19D4:
+ case 0x1A84:
+ case 0x1A94:
+ case 0x1B54:
+ case 0x1BB4:
+ case 0x1C44:
+ case 0x1C54:
+ case 0x2074:
+ case 0x2084:
+ case 0x2163:
+ case 0x2173:
+ case 0x2463:
+ case 0x2477:
+ case 0x248B:
+ case 0x24F8:
+ case 0x2779:
+ case 0x2783:
+ case 0x278D:
+ case 0x3024:
+ case 0x3195:
+ case 0x3223:
+ case 0x3283:
+ case 0x4E96:
+ case 0x56DB:
+ case 0x8086:
+ case 0xA624:
+ case 0xA6E9:
+ case 0xA8D4:
+ case 0xA904:
+ case 0xA9D4:
+ case 0xAA54:
+ case 0xABF4:
+ case 0xFF14:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010A:
+ case 0x104A4:
+ case 0x10A43:
+ case 0x10B5B:
+ case 0x10B7B:
+ case 0x10E63:
+ case 0x12402:
+ case 0x12409:
+ case 0x1240F:
+ case 0x12418:
+ case 0x12421:
+ case 0x12426:
+ case 0x12430:
+ case 0x12438:
+ case 0x1243C:
+ case 0x1243D:
+ case 0x1243E:
+ case 0x1243F:
+ case 0x1244C:
+ case 0x12452:
+ case 0x12453:
+ case 0x1D363:
+ case 0x1D7D2:
+ case 0x1D7DC:
+ case 0x1D7E6:
+ case 0x1D7F0:
+ case 0x1D7FA:
+ case 0x1F105:
+ case 0x20064:
+ case 0x200E2:
+ case 0x2626D:
+#endif
+ return (double) 4.0;
+ case 0x2158:
+ return (double) 4.0/5.0;
+ case 0x1375:
+ case 0x32B5:
+ case 0x534C:
+#ifdef Py_UNICODE_WIDE
+ case 0x10113:
+ case 0x10E6C:
+ case 0x1D36C:
+ case 0x2098C:
+ case 0x2099C:
+#endif
+ return (double) 40.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011C:
+ case 0x10E75:
+ return (double) 400.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10125:
+ return (double) 4000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012E:
+ return (double) 40000.0;
+#endif
+ case 0x32B6:
+ return (double) 41.0;
+ case 0x32B7:
+ return (double) 42.0;
+ case 0x32B8:
+ return (double) 43.0;
+ case 0x32B9:
+ return (double) 44.0;
+ case 0x32BA:
+ return (double) 45.0;
+ case 0x32BB:
+ return (double) 46.0;
+ case 0x32BC:
+ return (double) 47.0;
+ case 0x32BD:
+ return (double) 48.0;
+ case 0x32BE:
+ return (double) 49.0;
+ case 0x0035:
+ case 0x0665:
+ case 0x06F5:
+ case 0x07C5:
+ case 0x096B:
+ case 0x09EB:
+ case 0x0A6B:
+ case 0x0AEB:
+ case 0x0B6B:
+ case 0x0BEB:
+ case 0x0C6B:
+ case 0x0CEB:
+ case 0x0D6B:
+ case 0x0E55:
+ case 0x0ED5:
+ case 0x0F25:
+ case 0x1045:
+ case 0x1095:
+ case 0x136D:
+ case 0x17E5:
+ case 0x17F5:
+ case 0x1815:
+ case 0x194B:
+ case 0x19D5:
+ case 0x1A85:
+ case 0x1A95:
+ case 0x1B55:
+ case 0x1BB5:
+ case 0x1C45:
+ case 0x1C55:
+ case 0x2075:
+ case 0x2085:
+ case 0x2164:
+ case 0x2174:
+ case 0x2464:
+ case 0x2478:
+ case 0x248C:
+ case 0x24F9:
+ case 0x277A:
+ case 0x2784:
+ case 0x278E:
+ case 0x3025:
+ case 0x3224:
+ case 0x3284:
+ case 0x3405:
+ case 0x382A:
+ case 0x4E94:
+ case 0x4F0D:
+ case 0xA625:
+ case 0xA6EA:
+ case 0xA8D5:
+ case 0xA905:
+ case 0xA9D5:
+ case 0xAA55:
+ case 0xABF5:
+ case 0xFF15:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010B:
+ case 0x10143:
+ case 0x10148:
+ case 0x1014F:
+ case 0x1015F:
+ case 0x10173:
+ case 0x10321:
+ case 0x104A5:
+ case 0x10E64:
+ case 0x12403:
+ case 0x1240A:
+ case 0x12410:
+ case 0x12419:
+ case 0x12422:
+ case 0x12427:
+ case 0x12431:
+ case 0x12439:
+ case 0x1244D:
+ case 0x12454:
+ case 0x12455:
+ case 0x1D364:
+ case 0x1D7D3:
+ case 0x1D7DD:
+ case 0x1D7E7:
+ case 0x1D7F1:
+ case 0x1D7FB:
+ case 0x1F106:
+ case 0x20121:
+#endif
+ return (double) 5.0;
+ case 0x0F2C:
+ return (double) 5.0/2.0;
+ case 0x215A:
+#ifdef Py_UNICODE_WIDE
+ case 0x1245C:
+#endif
+ return (double) 5.0/6.0;
+ case 0x215D:
+ return (double) 5.0/8.0;
+ case 0x1376:
+ case 0x216C:
+ case 0x217C:
+ case 0x2186:
+ case 0x32BF:
+#ifdef Py_UNICODE_WIDE
+ case 0x10114:
+ case 0x10144:
+ case 0x1014A:
+ case 0x10151:
+ case 0x10166:
+ case 0x10167:
+ case 0x10168:
+ case 0x10169:
+ case 0x10174:
+ case 0x10323:
+ case 0x10A7E:
+ case 0x10E6D:
+ case 0x1D36D:
+#endif
+ return (double) 50.0;
+ case 0x216E:
+ case 0x217E:
+#ifdef Py_UNICODE_WIDE
+ case 0x1011D:
+ case 0x10145:
+ case 0x1014C:
+ case 0x10153:
+ case 0x1016C:
+ case 0x1016D:
+ case 0x1016E:
+ case 0x1016F:
+ case 0x10170:
+ case 0x10E76:
+#endif
+ return (double) 500.0;
+ case 0x2181:
+#ifdef Py_UNICODE_WIDE
+ case 0x10126:
+ case 0x10146:
+ case 0x1014E:
+ case 0x10172:
+#endif
+ return (double) 5000.0;
+ case 0x2187:
+#ifdef Py_UNICODE_WIDE
+ case 0x1012F:
+ case 0x10147:
+ case 0x10156:
+#endif
+ return (double) 50000.0;
+ case 0x0036:
+ case 0x0666:
+ case 0x06F6:
+ case 0x07C6:
+ case 0x096C:
+ case 0x09EC:
+ case 0x0A6C:
+ case 0x0AEC:
+ case 0x0B6C:
+ case 0x0BEC:
+ case 0x0C6C:
+ case 0x0CEC:
+ case 0x0D6C:
+ case 0x0E56:
+ case 0x0ED6:
+ case 0x0F26:
+ case 0x1046:
+ case 0x1096:
+ case 0x136E:
+ case 0x17E6:
+ case 0x17F6:
+ case 0x1816:
+ case 0x194C:
+ case 0x19D6:
+ case 0x1A86:
+ case 0x1A96:
+ case 0x1B56:
+ case 0x1BB6:
+ case 0x1C46:
+ case 0x1C56:
+ case 0x2076:
+ case 0x2086:
+ case 0x2165:
+ case 0x2175:
+ case 0x2185:
+ case 0x2465:
+ case 0x2479:
+ case 0x248D:
+ case 0x24FA:
+ case 0x277B:
+ case 0x2785:
+ case 0x278F:
+ case 0x3026:
+ case 0x3225:
+ case 0x3285:
+ case 0x516D:
+ case 0x9646:
+ case 0x9678:
+ case 0xA626:
+ case 0xA6EB:
+ case 0xA8D6:
+ case 0xA906:
+ case 0xA9D6:
+ case 0xAA56:
+ case 0xABF6:
+ case 0xF9D1:
+ case 0xF9D3:
+ case 0xFF16:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010C:
+ case 0x104A6:
+ case 0x10E65:
+ case 0x12404:
+ case 0x1240B:
+ case 0x12411:
+ case 0x1241A:
+ case 0x12428:
+ case 0x12440:
+ case 0x1244E:
+ case 0x1D365:
+ case 0x1D7D4:
+ case 0x1D7DE:
+ case 0x1D7E8:
+ case 0x1D7F2:
+ case 0x1D7FC:
+ case 0x1F107:
+ case 0x20AEA:
+#endif
+ return (double) 6.0;
+ case 0x1377:
+#ifdef Py_UNICODE_WIDE
+ case 0x10115:
+ case 0x10E6E:
+ case 0x1D36E:
+#endif
+ return (double) 60.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011E:
+ case 0x10E77:
+ return (double) 600.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10127:
+ return (double) 6000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10130:
+ return (double) 60000.0;
+#endif
+ case 0x0037:
+ case 0x0667:
+ case 0x06F7:
+ case 0x07C7:
+ case 0x096D:
+ case 0x09ED:
+ case 0x0A6D:
+ case 0x0AED:
+ case 0x0B6D:
+ case 0x0BED:
+ case 0x0C6D:
+ case 0x0CED:
+ case 0x0D6D:
+ case 0x0E57:
+ case 0x0ED7:
+ case 0x0F27:
+ case 0x1047:
+ case 0x1097:
+ case 0x136F:
+ case 0x17E7:
+ case 0x17F7:
+ case 0x1817:
+ case 0x194D:
+ case 0x19D7:
+ case 0x1A87:
+ case 0x1A97:
+ case 0x1B57:
+ case 0x1BB7:
+ case 0x1C47:
+ case 0x1C57:
+ case 0x2077:
+ case 0x2087:
+ case 0x2166:
+ case 0x2176:
+ case 0x2466:
+ case 0x247A:
+ case 0x248E:
+ case 0x24FB:
+ case 0x277C:
+ case 0x2786:
+ case 0x2790:
+ case 0x3027:
+ case 0x3226:
+ case 0x3286:
+ case 0x3B4D:
+ case 0x4E03:
+ case 0x67D2:
+ case 0x6F06:
+ case 0xA627:
+ case 0xA6EC:
+ case 0xA8D7:
+ case 0xA907:
+ case 0xA9D7:
+ case 0xAA57:
+ case 0xABF7:
+ case 0xFF17:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010D:
+ case 0x104A7:
+ case 0x10E66:
+ case 0x12405:
+ case 0x1240C:
+ case 0x12412:
+ case 0x1241B:
+ case 0x12429:
+ case 0x12441:
+ case 0x12442:
+ case 0x12443:
+ case 0x1D366:
+ case 0x1D7D5:
+ case 0x1D7DF:
+ case 0x1D7E9:
+ case 0x1D7F3:
+ case 0x1D7FD:
+ case 0x1F108:
+ case 0x20001:
+#endif
+ return (double) 7.0;
+ case 0x0F2D:
+ return (double) 7.0/2.0;
+ case 0x215E:
+ return (double) 7.0/8.0;
+ case 0x1378:
+#ifdef Py_UNICODE_WIDE
+ case 0x10116:
+ case 0x10E6F:
+ case 0x1D36F:
+#endif
+ return (double) 70.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011F:
+ case 0x10E78:
+ return (double) 700.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10128:
+ return (double) 7000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10131:
+ return (double) 70000.0;
+#endif
+ case 0x0038:
+ case 0x0668:
+ case 0x06F8:
+ case 0x07C8:
+ case 0x096E:
+ case 0x09EE:
+ case 0x0A6E:
+ case 0x0AEE:
+ case 0x0B6E:
+ case 0x0BEE:
+ case 0x0C6E:
+ case 0x0CEE:
+ case 0x0D6E:
+ case 0x0E58:
+ case 0x0ED8:
+ case 0x0F28:
+ case 0x1048:
+ case 0x1098:
+ case 0x1370:
+ case 0x17E8:
+ case 0x17F8:
+ case 0x1818:
+ case 0x194E:
+ case 0x19D8:
+ case 0x1A88:
+ case 0x1A98:
+ case 0x1B58:
+ case 0x1BB8:
+ case 0x1C48:
+ case 0x1C58:
+ case 0x2078:
+ case 0x2088:
+ case 0x2167:
+ case 0x2177:
+ case 0x2467:
+ case 0x247B:
+ case 0x248F:
+ case 0x24FC:
+ case 0x277D:
+ case 0x2787:
+ case 0x2791:
+ case 0x3028:
+ case 0x3227:
+ case 0x3287:
+ case 0x516B:
+ case 0x634C:
+ case 0xA628:
+ case 0xA6ED:
+ case 0xA8D8:
+ case 0xA908:
+ case 0xA9D8:
+ case 0xAA58:
+ case 0xABF8:
+ case 0xFF18:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010E:
+ case 0x104A8:
+ case 0x10E67:
+ case 0x12406:
+ case 0x1240D:
+ case 0x12413:
+ case 0x1241C:
+ case 0x1242A:
+ case 0x12444:
+ case 0x12445:
+ case 0x1D367:
+ case 0x1D7D6:
+ case 0x1D7E0:
+ case 0x1D7EA:
+ case 0x1D7F4:
+ case 0x1D7FE:
+ case 0x1F109:
+#endif
+ return (double) 8.0;
+ case 0x1379:
+#ifdef Py_UNICODE_WIDE
+ case 0x10117:
+ case 0x10E70:
+ case 0x1D370:
+#endif
+ return (double) 80.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x10120:
+ case 0x10E79:
+ return (double) 800.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10129:
+ return (double) 8000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10132:
+ return (double) 80000.0;
+#endif
+ case 0x0039:
+ case 0x0669:
+ case 0x06F9:
+ case 0x07C9:
+ case 0x096F:
+ case 0x09EF:
+ case 0x0A6F:
+ case 0x0AEF:
+ case 0x0B6F:
+ case 0x0BEF:
+ case 0x0C6F:
+ case 0x0CEF:
+ case 0x0D6F:
+ case 0x0E59:
+ case 0x0ED9:
+ case 0x0F29:
+ case 0x1049:
+ case 0x1099:
+ case 0x1371:
+ case 0x17E9:
+ case 0x17F9:
+ case 0x1819:
+ case 0x194F:
+ case 0x19D9:
+ case 0x1A89:
+ case 0x1A99:
+ case 0x1B59:
+ case 0x1BB9:
+ case 0x1C49:
+ case 0x1C59:
+ case 0x2079:
+ case 0x2089:
+ case 0x2168:
+ case 0x2178:
+ case 0x2468:
+ case 0x247C:
+ case 0x2490:
+ case 0x24FD:
+ case 0x277E:
+ case 0x2788:
+ case 0x2792:
+ case 0x3029:
+ case 0x3228:
+ case 0x3288:
+ case 0x4E5D:
+ case 0x5EFE:
+ case 0x7396:
+ case 0xA629:
+ case 0xA6EE:
+ case 0xA8D9:
+ case 0xA909:
+ case 0xA9D9:
+ case 0xAA59:
+ case 0xABF9:
+ case 0xFF19:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010F:
+ case 0x104A9:
+ case 0x10E68:
+ case 0x12407:
+ case 0x1240E:
+ case 0x12414:
+ case 0x1241D:
+ case 0x1242B:
+ case 0x12446:
+ case 0x12447:
+ case 0x12448:
+ case 0x12449:
+ case 0x1D368:
+ case 0x1D7D7:
+ case 0x1D7E1:
+ case 0x1D7EB:
+ case 0x1D7F5:
+ case 0x1D7FF:
+ case 0x1F10A:
+ case 0x2F890:
+#endif
+ return (double) 9.0;
+ case 0x0F2E:
+ return (double) 9.0/2.0;
+ case 0x137A:
+#ifdef Py_UNICODE_WIDE
+ case 0x10118:
+ case 0x10341:
+ case 0x10E71:
+ case 0x1D371:
+#endif
+ return (double) 90.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x10121:
+ case 0x1034A:
+ case 0x10E7A:
+ return (double) 900.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012A:
+ return (double) 9000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10133:
+ return (double) 90000.0;
+#endif
+ }
+ return -1.0;
+}
+
+/* Returns 1 for Unicode characters having the bidirectional
+ * type 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise.
+ */
+int _PyUnicode_IsWhitespace(register const Py_UNICODE ch)
+{
+#ifdef WANT_WCTYPE_FUNCTIONS
+ return iswspace(ch);
+#else
+ switch (ch) {
+ case 0x0009:
+ case 0x000A:
+ case 0x000B:
+ case 0x000C:
+ case 0x000D:
+ case 0x001C:
+ case 0x001D:
+ case 0x001E:
+ case 0x001F:
+ case 0x0020:
+ case 0x0085:
+ case 0x00A0:
+ case 0x1680:
+ case 0x180E:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x2028:
+ case 0x2029:
+ case 0x202F:
+ case 0x205F:
+ case 0x3000:
+ return 1;
+ }
+ return 0;
+#endif
+}
+
+/* Returns 1 for Unicode characters having the line break
+ * property 'BK', 'CR', 'LF' or 'NL' or having bidirectional
+ * type 'B', 0 otherwise.
+ */
+int _PyUnicode_IsLinebreak(register const Py_UNICODE ch)
+{
+ switch (ch) {
+ case 0x000A:
+ case 0x000B:
+ case 0x000C:
+ case 0x000D:
+ case 0x001C:
+ case 0x001D:
+ case 0x001E:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/weakrefobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/weakrefobject.c
new file mode 100644
index 0000000000..dbb87d191a
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/Objects/weakrefobject.c
@@ -0,0 +1,981 @@
+#include "Python.h"
+#include "structmember.h"
+
+
+#define GET_WEAKREFS_LISTPTR(o) \
+ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
+
+
+Py_ssize_t
+_PyWeakref_GetWeakrefCount(PyWeakReference *head)
+{
+ Py_ssize_t count = 0;
+
+ while (head != NULL) {
+ ++count;
+ head = head->wr_next;
+ }
+ return count;
+}
+
+
+static void
+init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback)
+{
+ self->hash = -1;
+ self->wr_object = ob;
+ Py_XINCREF(callback);
+ self->wr_callback = callback;
+}
+
+static PyWeakReference *
+new_weakref(PyObject *ob, PyObject *callback)
+{
+ PyWeakReference *result;
+
+ result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType);
+ if (result) {
+ init_weakref(result, ob, callback);
+ PyObject_GC_Track(result);
+ }
+ return result;
+}
+
+
+/* This function clears the passed-in reference and removes it from the
+ * list of weak references for the referent. This is the only code that
+ * removes an item from the doubly-linked list of weak references for an
+ * object; it is also responsible for clearing the callback slot.
+ */
+static void
+clear_weakref(PyWeakReference *self)
+{
+ PyObject *callback = self->wr_callback;
+
+ if (self->wr_object != Py_None) {
+ PyWeakReference **list = GET_WEAKREFS_LISTPTR(self->wr_object);
+
+ if (*list == self)
+ /* If 'self' is the end of the list (and thus self->wr_next == NULL)
+ then the weakref list itself (and thus the value of *list) will
+ end up being set to NULL. */
+ *list = self->wr_next;
+ self->wr_object = Py_None;
+ if (self->wr_prev != NULL)
+ self->wr_prev->wr_next = self->wr_next;
+ if (self->wr_next != NULL)
+ self->wr_next->wr_prev = self->wr_prev;
+ self->wr_prev = NULL;
+ self->wr_next = NULL;
+ }
+ if (callback != NULL) {
+ Py_DECREF(callback);
+ self->wr_callback = NULL;
+ }
+}
+
+/* Cyclic gc uses this to *just* clear the passed-in reference, leaving
+ * the callback intact and uncalled. It must be possible to call self's
+ * tp_dealloc() after calling this, so self has to be left in a sane enough
+ * state for that to work. We expect tp_dealloc to decref the callback
+ * then. The reason for not letting clear_weakref() decref the callback
+ * right now is that if the callback goes away, that may in turn trigger
+ * another callback (if a weak reference to the callback exists) -- running
+ * arbitrary Python code in the middle of gc is a disaster. The convolution
+ * here allows gc to delay triggering such callbacks until the world is in
+ * a sane state again.
+ */
+void
+_PyWeakref_ClearRef(PyWeakReference *self)
+{
+ PyObject *callback;
+
+ assert(self != NULL);
+ assert(PyWeakref_Check(self));
+ /* Preserve and restore the callback around clear_weakref. */
+ callback = self->wr_callback;
+ self->wr_callback = NULL;
+ clear_weakref(self);
+ self->wr_callback = callback;
+}
+
+static void
+weakref_dealloc(PyObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ clear_weakref((PyWeakReference *) self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+
+static int
+gc_traverse(PyWeakReference *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->wr_callback);
+ return 0;
+}
+
+
+static int
+gc_clear(PyWeakReference *self)
+{
+ clear_weakref(self);
+ return 0;
+}
+
+
+static PyObject *
+weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] = {NULL};
+
+ if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) {
+ PyObject *object = PyWeakref_GET_OBJECT(self);
+ Py_INCREF(object);
+ return (object);
+ }
+ return NULL;
+}
+
+
+static long
+weakref_hash(PyWeakReference *self)
+{
+ if (self->hash != -1)
+ return self->hash;
+ if (PyWeakref_GET_OBJECT(self) == Py_None) {
+ PyErr_SetString(PyExc_TypeError, "weak object has gone away");
+ return -1;
+ }
+ self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self));
+ return self->hash;
+}
+
+
+static PyObject *
+weakref_repr(PyWeakReference *self)
+{
+ char buffer[256];
+ if (PyWeakref_GET_OBJECT(self) == Py_None) {
+ PyOS_snprintf(buffer, sizeof(buffer), "<weakref at %p; dead>", self);
+ }
+ else {
+ char *name = NULL;
+ PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self),
+ "__name__");
+ if (nameobj == NULL)
+ PyErr_Clear();
+ else if (PyString_Check(nameobj))
+ name = PyString_AS_STRING(nameobj);
+ if (name != NULL) {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "<weakref at %p; to '%.50s' at %p (%s)>",
+ self,
+ Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name,
+ PyWeakref_GET_OBJECT(self),
+ name);
+ }
+ else {
+ PyOS_snprintf(buffer, sizeof(buffer),
+ "<weakref at %p; to '%.50s' at %p>",
+ self,
+ Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name,
+ PyWeakref_GET_OBJECT(self));
+ }
+ Py_XDECREF(nameobj);
+ }
+ return PyString_FromString(buffer);
+}
+
+/* Weak references only support equality, not ordering. Two weak references
+ are equal if the underlying objects are equal. If the underlying object has
+ gone away, they are equal if they are identical. */
+
+static PyObject *
+weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op)
+{
+ if ((op != Py_EQ && op != Py_NE) || self->ob_type != other->ob_type) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if (PyWeakref_GET_OBJECT(self) == Py_None
+ || PyWeakref_GET_OBJECT(other) == Py_None) {
+ int res = (self == other);
+ if (op == Py_NE)
+ res = !res;
+ if (res)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+ return PyObject_RichCompare(PyWeakref_GET_OBJECT(self),
+ PyWeakref_GET_OBJECT(other), op);
+}
+
+/* Given the head of an object's list of weak references, extract the
+ * two callback-less refs (ref and proxy). Used to determine if the
+ * shared references exist and to determine the back link for newly
+ * inserted references.
+ */
+static void
+get_basic_refs(PyWeakReference *head,
+ PyWeakReference **refp, PyWeakReference **proxyp)
+{
+ *refp = NULL;
+ *proxyp = NULL;
+
+ if (head != NULL && head->wr_callback == NULL) {
+ /* We need to be careful that the "basic refs" aren't
+ subclasses of the main types. That complicates this a
+ little. */
+ if (PyWeakref_CheckRefExact(head)) {
+ *refp = head;
+ head = head->wr_next;
+ }
+ if (head != NULL
+ && head->wr_callback == NULL
+ && PyWeakref_CheckProxy(head)) {
+ *proxyp = head;
+ /* head = head->wr_next; */
+ }
+ }
+}
+
+/* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */
+static void
+insert_after(PyWeakReference *newref, PyWeakReference *prev)
+{
+ newref->wr_prev = prev;
+ newref->wr_next = prev->wr_next;
+ if (prev->wr_next != NULL)
+ prev->wr_next->wr_prev = newref;
+ prev->wr_next = newref;
+}
+
+/* Insert 'newref' at the head of the list; 'list' points to the variable
+ * that stores the head.
+ */
+static void
+insert_head(PyWeakReference *newref, PyWeakReference **list)
+{
+ PyWeakReference *next = *list;
+
+ newref->wr_prev = NULL;
+ newref->wr_next = next;
+ if (next != NULL)
+ next->wr_prev = newref;
+ *list = newref;
+}
+
+static int
+parse_weakref_init_args(char *funcname, PyObject *args, PyObject *kwargs,
+ PyObject **obp, PyObject **callbackp)
+{
+ /* XXX Should check that kwargs == NULL or is empty. */
+ return PyArg_UnpackTuple(args, funcname, 1, 2, obp, callbackp);
+}
+
+static PyObject *
+weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyWeakReference *self = NULL;
+ PyObject *ob, *callback = NULL;
+
+ if (parse_weakref_init_args("__new__", args, kwargs, &ob, &callback)) {
+ PyWeakReference *ref, *proxy;
+ PyWeakReference **list;
+
+ if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create weak reference to '%s' object",
+ Py_TYPE(ob)->tp_name);
+ return NULL;
+ }
+ if (callback == Py_None)
+ callback = NULL;
+ list = GET_WEAKREFS_LISTPTR(ob);
+ get_basic_refs(*list, &ref, &proxy);
+ if (callback == NULL && type == &_PyWeakref_RefType) {
+ if (ref != NULL) {
+ /* We can re-use an existing reference. */
+ Py_INCREF(ref);
+ return (PyObject *)ref;
+ }
+ }
+ /* We have to create a new reference. */
+ /* Note: the tp_alloc() can trigger cyclic GC, so the weakref
+ list on ob can be mutated. This means that the ref and
+ proxy pointers we got back earlier may have been collected,
+ so we need to compute these values again before we use
+ them. */
+ self = (PyWeakReference *) (type->tp_alloc(type, 0));
+ if (self != NULL) {
+ init_weakref(self, ob, callback);
+ if (callback == NULL && type == &_PyWeakref_RefType) {
+ insert_head(self, list);
+ }
+ else {
+ PyWeakReference *prev;
+
+ get_basic_refs(*list, &ref, &proxy);
+ prev = (proxy == NULL) ? ref : proxy;
+ if (prev == NULL)
+ insert_head(self, list);
+ else
+ insert_after(self, prev);
+ }
+ }
+ }
+ return (PyObject *)self;
+}
+
+static int
+weakref___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *tmp;
+
+ if (parse_weakref_init_args("__init__", args, kwargs, &tmp, &tmp))
+ return 0;
+ else
+ return -1;
+}
+
+
+PyTypeObject
+_PyWeakref_RefType = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "weakref",
+ sizeof(PyWeakReference),
+ 0,
+ weakref_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc)weakref_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)weakref_hash, /*tp_hash*/
+ (ternaryfunc)weakref_call, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE
+ | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ (traverseproc)gc_traverse, /*tp_traverse*/
+ (inquiry)gc_clear, /*tp_clear*/
+ (richcmpfunc)weakref_richcompare, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ weakref___init__, /*tp_init*/
+ PyType_GenericAlloc, /*tp_alloc*/
+ weakref___new__, /*tp_new*/
+ PyObject_GC_Del, /*tp_free*/
+};
+
+
+static int
+proxy_checkref(PyWeakReference *proxy)
+{
+ if (PyWeakref_GET_OBJECT(proxy) == Py_None) {
+ PyErr_SetString(PyExc_ReferenceError,
+ "weakly-referenced object no longer exists");
+ return 0;
+ }
+ return 1;
+}
+
+
+/* If a parameter is a proxy, check that it is still "live" and wrap it,
+ * replacing the original value with the raw object. Raises ReferenceError
+ * if the param is a dead proxy.
+ */
+#define UNWRAP(o) \
+ if (PyWeakref_CheckProxy(o)) { \
+ if (!proxy_checkref((PyWeakReference *)o)) \
+ return NULL; \
+ o = PyWeakref_GET_OBJECT(o); \
+ }
+
+#define UNWRAP_I(o) \
+ if (PyWeakref_CheckProxy(o)) { \
+ if (!proxy_checkref((PyWeakReference *)o)) \
+ return -1; \
+ o = PyWeakref_GET_OBJECT(o); \
+ }
+
+#define WRAP_UNARY(method, generic) \
+ static PyObject * \
+ method(PyObject *proxy) { \
+ UNWRAP(proxy); \
+ return generic(proxy); \
+ }
+
+#define WRAP_BINARY(method, generic) \
+ static PyObject * \
+ method(PyObject *x, PyObject *y) { \
+ UNWRAP(x); \
+ UNWRAP(y); \
+ return generic(x, y); \
+ }
+
+/* Note that the third arg needs to be checked for NULL since the tp_call
+ * slot can receive NULL for this arg.
+ */
+#define WRAP_TERNARY(method, generic) \
+ static PyObject * \
+ method(PyObject *proxy, PyObject *v, PyObject *w) { \
+ UNWRAP(proxy); \
+ UNWRAP(v); \
+ if (w != NULL) \
+ UNWRAP(w); \
+ return generic(proxy, v, w); \
+ }
+
+#define WRAP_METHOD(method, special) \
+ static PyObject * \
+ method(PyObject *proxy) { \
+ UNWRAP(proxy); \
+ return PyObject_CallMethod(proxy, special, ""); \
+ }
+
+
+/* direct slots */
+
+WRAP_BINARY(proxy_getattr, PyObject_GetAttr)
+WRAP_UNARY(proxy_str, PyObject_Str)
+WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords)
+
+static PyObject *
+proxy_repr(PyWeakReference *proxy)
+{
+ char buf[160];
+ PyOS_snprintf(buf, sizeof(buf),
+ "<weakproxy at %p to %.100s at %p>", proxy,
+ Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name,
+ PyWeakref_GET_OBJECT(proxy));
+ return PyString_FromString(buf);
+}
+
+
+static int
+proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value)
+{
+ if (!proxy_checkref(proxy))
+ return -1;
+ return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value);
+}
+
+static int
+proxy_compare(PyObject *proxy, PyObject *v)
+{
+ UNWRAP_I(proxy);
+ UNWRAP_I(v);
+ return PyObject_Compare(proxy, v);
+}
+
+/* number slots */
+WRAP_BINARY(proxy_add, PyNumber_Add)
+WRAP_BINARY(proxy_sub, PyNumber_Subtract)
+WRAP_BINARY(proxy_mul, PyNumber_Multiply)
+WRAP_BINARY(proxy_div, PyNumber_Divide)
+WRAP_BINARY(proxy_floor_div, PyNumber_FloorDivide)
+WRAP_BINARY(proxy_true_div, PyNumber_TrueDivide)
+WRAP_BINARY(proxy_mod, PyNumber_Remainder)
+WRAP_BINARY(proxy_divmod, PyNumber_Divmod)
+WRAP_TERNARY(proxy_pow, PyNumber_Power)
+WRAP_UNARY(proxy_neg, PyNumber_Negative)
+WRAP_UNARY(proxy_pos, PyNumber_Positive)
+WRAP_UNARY(proxy_abs, PyNumber_Absolute)
+WRAP_UNARY(proxy_invert, PyNumber_Invert)
+WRAP_BINARY(proxy_lshift, PyNumber_Lshift)
+WRAP_BINARY(proxy_rshift, PyNumber_Rshift)
+WRAP_BINARY(proxy_and, PyNumber_And)
+WRAP_BINARY(proxy_xor, PyNumber_Xor)
+WRAP_BINARY(proxy_or, PyNumber_Or)
+WRAP_UNARY(proxy_int, PyNumber_Int)
+WRAP_UNARY(proxy_long, PyNumber_Long)
+WRAP_UNARY(proxy_float, PyNumber_Float)
+WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd)
+WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract)
+WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply)
+WRAP_BINARY(proxy_idiv, PyNumber_InPlaceDivide)
+WRAP_BINARY(proxy_ifloor_div, PyNumber_InPlaceFloorDivide)
+WRAP_BINARY(proxy_itrue_div, PyNumber_InPlaceTrueDivide)
+WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder)
+WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower)
+WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift)
+WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift)
+WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd)
+WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
+WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
+WRAP_UNARY(proxy_index, PyNumber_Index)
+
+static int
+proxy_nonzero(PyWeakReference *proxy)
+{
+ PyObject *o = PyWeakref_GET_OBJECT(proxy);
+ if (!proxy_checkref(proxy))
+ return -1;
+ return PyObject_IsTrue(o);
+}
+
+static void
+proxy_dealloc(PyWeakReference *self)
+{
+ if (self->wr_callback != NULL)
+ PyObject_GC_UnTrack((PyObject *)self);
+ clear_weakref(self);
+ PyObject_GC_Del(self);
+}
+
+/* sequence slots */
+
+static PyObject *
+proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j)
+{
+ if (!proxy_checkref(proxy))
+ return NULL;
+ return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);
+}
+
+static int
+proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
+{
+ if (!proxy_checkref(proxy))
+ return -1;
+ return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
+}
+
+static int
+proxy_contains(PyWeakReference *proxy, PyObject *value)
+{
+ if (!proxy_checkref(proxy))
+ return -1;
+ return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value);
+}
+
+
+/* mapping slots */
+
+static Py_ssize_t
+proxy_length(PyWeakReference *proxy)
+{
+ if (!proxy_checkref(proxy))
+ return -1;
+ return PyObject_Length(PyWeakref_GET_OBJECT(proxy));
+}
+
+WRAP_BINARY(proxy_getitem, PyObject_GetItem)
+
+static int
+proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value)
+{
+ if (!proxy_checkref(proxy))
+ return -1;
+
+ if (value == NULL)
+ return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key);
+ else
+ return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value);
+}
+
+/* iterator slots */
+
+static PyObject *
+proxy_iter(PyWeakReference *proxy)
+{
+ if (!proxy_checkref(proxy))
+ return NULL;
+ return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy));
+}
+
+static PyObject *
+proxy_iternext(PyWeakReference *proxy)
+{
+ if (!proxy_checkref(proxy))
+ return NULL;
+ return PyIter_Next(PyWeakref_GET_OBJECT(proxy));
+}
+
+
+WRAP_METHOD(proxy_unicode, "__unicode__");
+
+
+static PyMethodDef proxy_methods[] = {
+ {"__unicode__", (PyCFunction)proxy_unicode, METH_NOARGS},
+ {NULL, NULL}
+};
+
+
+static PyNumberMethods proxy_as_number = {
+ proxy_add, /*nb_add*/
+ proxy_sub, /*nb_subtract*/
+ proxy_mul, /*nb_multiply*/
+ proxy_div, /*nb_divide*/
+ proxy_mod, /*nb_remainder*/
+ proxy_divmod, /*nb_divmod*/
+ proxy_pow, /*nb_power*/
+ proxy_neg, /*nb_negative*/
+ proxy_pos, /*nb_positive*/
+ proxy_abs, /*nb_absolute*/
+ (inquiry)proxy_nonzero, /*nb_nonzero*/
+ proxy_invert, /*nb_invert*/
+ proxy_lshift, /*nb_lshift*/
+ proxy_rshift, /*nb_rshift*/
+ proxy_and, /*nb_and*/
+ proxy_xor, /*nb_xor*/
+ proxy_or, /*nb_or*/
+ 0, /*nb_coerce*/
+ proxy_int, /*nb_int*/
+ proxy_long, /*nb_long*/
+ proxy_float, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
+ proxy_iadd, /*nb_inplace_add*/
+ proxy_isub, /*nb_inplace_subtract*/
+ proxy_imul, /*nb_inplace_multiply*/
+ proxy_idiv, /*nb_inplace_divide*/
+ proxy_imod, /*nb_inplace_remainder*/
+ proxy_ipow, /*nb_inplace_power*/
+ proxy_ilshift, /*nb_inplace_lshift*/
+ proxy_irshift, /*nb_inplace_rshift*/
+ proxy_iand, /*nb_inplace_and*/
+ proxy_ixor, /*nb_inplace_xor*/
+ proxy_ior, /*nb_inplace_or*/
+ proxy_floor_div, /*nb_floor_divide*/
+ proxy_true_div, /*nb_true_divide*/
+ proxy_ifloor_div, /*nb_inplace_floor_divide*/
+ proxy_itrue_div, /*nb_inplace_true_divide*/
+ proxy_index, /*nb_index*/
+};
+
+static PySequenceMethods proxy_as_sequence = {
+ (lenfunc)proxy_length, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ 0, /*sq_item*/
+ (ssizessizeargfunc)proxy_slice, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ (ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
+ (objobjproc)proxy_contains, /* sq_contains */
+};
+
+static PyMappingMethods proxy_as_mapping = {
+ (lenfunc)proxy_length, /*mp_length*/
+ proxy_getitem, /*mp_subscript*/
+ (objobjargproc)proxy_setitem, /*mp_ass_subscript*/
+};
+
+
+PyTypeObject
+_PyWeakref_ProxyType = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "weakproxy",
+ sizeof(PyWeakReference),
+ 0,
+ /* methods */
+ (destructor)proxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ proxy_compare, /* tp_compare */
+ (reprfunc)proxy_repr, /* tp_repr */
+ &proxy_as_number, /* tp_as_number */
+ &proxy_as_sequence, /* tp_as_sequence */
+ &proxy_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ proxy_str, /* tp_str */
+ proxy_getattr, /* tp_getattro */
+ (setattrofunc)proxy_setattr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)gc_traverse, /* tp_traverse */
+ (inquiry)gc_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)proxy_iter, /* tp_iter */
+ (iternextfunc)proxy_iternext, /* tp_iternext */
+ proxy_methods, /* tp_methods */
+};
+
+
+PyTypeObject
+_PyWeakref_CallableProxyType = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "weakcallableproxy",
+ sizeof(PyWeakReference),
+ 0,
+ /* methods */
+ (destructor)proxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ proxy_compare, /* tp_compare */
+ (unaryfunc)proxy_repr, /* tp_repr */
+ &proxy_as_number, /* tp_as_number */
+ &proxy_as_sequence, /* tp_as_sequence */
+ &proxy_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ proxy_call, /* tp_call */
+ proxy_str, /* tp_str */
+ proxy_getattr, /* tp_getattro */
+ (setattrofunc)proxy_setattr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
+ | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)gc_traverse, /* tp_traverse */
+ (inquiry)gc_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)proxy_iter, /* tp_iter */
+ (iternextfunc)proxy_iternext, /* tp_iternext */
+};
+
+
+
+PyObject *
+PyWeakref_NewRef(PyObject *ob, PyObject *callback)
+{
+ PyWeakReference *result = NULL;
+ PyWeakReference **list;
+ PyWeakReference *ref, *proxy;
+
+ if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create weak reference to '%s' object",
+ Py_TYPE(ob)->tp_name);
+ return NULL;
+ }
+ list = GET_WEAKREFS_LISTPTR(ob);
+ get_basic_refs(*list, &ref, &proxy);
+ if (callback == Py_None)
+ callback = NULL;
+ if (callback == NULL)
+ /* return existing weak reference if it exists */
+ result = ref;
+ if (result != NULL)
+ Py_INCREF(result);
+ else {
+ /* Note: new_weakref() can trigger cyclic GC, so the weakref
+ list on ob can be mutated. This means that the ref and
+ proxy pointers we got back earlier may have been collected,
+ so we need to compute these values again before we use
+ them. */
+ result = new_weakref(ob, callback);
+ if (result != NULL) {
+ get_basic_refs(*list, &ref, &proxy);
+ if (callback == NULL) {
+ if (ref == NULL)
+ insert_head(result, list);
+ else {
+ /* Someone else added a ref without a callback
+ during GC. Return that one instead of this one
+ to avoid violating the invariants of the list
+ of weakrefs for ob. */
+ Py_DECREF(result);
+ Py_INCREF(ref);
+ result = ref;
+ }
+ }
+ else {
+ PyWeakReference *prev;
+
+ prev = (proxy == NULL) ? ref : proxy;
+ if (prev == NULL)
+ insert_head(result, list);
+ else
+ insert_after(result, prev);
+ }
+ }
+ }
+ return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_NewProxy(PyObject *ob, PyObject *callback)
+{
+ PyWeakReference *result = NULL;
+ PyWeakReference **list;
+ PyWeakReference *ref, *proxy;
+
+ if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create weak reference to '%s' object",
+ Py_TYPE(ob)->tp_name);
+ return NULL;
+ }
+ list = GET_WEAKREFS_LISTPTR(ob);
+ get_basic_refs(*list, &ref, &proxy);
+ if (callback == Py_None)
+ callback = NULL;
+ if (callback == NULL)
+ /* attempt to return an existing weak reference if it exists */
+ result = proxy;
+ if (result != NULL)
+ Py_INCREF(result);
+ else {
+ /* Note: new_weakref() can trigger cyclic GC, so the weakref
+ list on ob can be mutated. This means that the ref and
+ proxy pointers we got back earlier may have been collected,
+ so we need to compute these values again before we use
+ them. */
+ result = new_weakref(ob, callback);
+ if (result != NULL) {
+ PyWeakReference *prev;
+
+ if (PyCallable_Check(ob))
+ Py_TYPE(result) = &_PyWeakref_CallableProxyType;
+ else
+ Py_TYPE(result) = &_PyWeakref_ProxyType;
+ get_basic_refs(*list, &ref, &proxy);
+ if (callback == NULL) {
+ if (proxy != NULL) {
+ /* Someone else added a proxy without a callback
+ during GC. Return that one instead of this one
+ to avoid violating the invariants of the list
+ of weakrefs for ob. */
+ Py_DECREF(result);
+ Py_INCREF(result = proxy);
+ goto skip_insert;
+ }
+ prev = ref;
+ }
+ else
+ prev = (proxy == NULL) ? ref : proxy;
+
+ if (prev == NULL)
+ insert_head(result, list);
+ else
+ insert_after(result, prev);
+ skip_insert:
+ ;
+ }
+ }
+ return (PyObject *) result;
+}
+
+
+PyObject *
+PyWeakref_GetObject(PyObject *ref)
+{
+ if (ref == NULL || !PyWeakref_Check(ref)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ return PyWeakref_GET_OBJECT(ref);
+}
+
+/* Note that there's an inlined copy-paste of handle_callback() in gcmodule.c's
+ * handle_weakrefs().
+ */
+static void
+handle_callback(PyWeakReference *ref, PyObject *callback)
+{
+ PyObject *cbresult = PyObject_CallFunctionObjArgs(callback, ref, NULL);
+
+ if (cbresult == NULL)
+ PyErr_WriteUnraisable(callback);
+ else
+ Py_DECREF(cbresult);
+}
+
+/* This function is called by the tp_dealloc handler to clear weak references.
+ *
+ * This iterates through the weak references for 'object' and calls callbacks
+ * for those references which have one. It returns when all callbacks have
+ * been attempted.
+ */
+void
+PyObject_ClearWeakRefs(PyObject *object)
+{
+ PyWeakReference **list;
+
+ if (object == NULL
+ || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
+ || object->ob_refcnt != 0) {
+ PyErr_BadInternalCall();
+ return;
+ }
+ list = GET_WEAKREFS_LISTPTR(object);
+ /* Remove the callback-less basic and proxy references */
+ if (*list != NULL && (*list)->wr_callback == NULL) {
+ clear_weakref(*list);
+ if (*list != NULL && (*list)->wr_callback == NULL)
+ clear_weakref(*list);
+ }
+ if (*list != NULL) {
+ PyWeakReference *current = *list;
+ Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
+ PyObject *err_type, *err_value, *err_tb;
+
+ PyErr_Fetch(&err_type, &err_value, &err_tb);
+ if (count == 1) {
+ PyObject *callback = current->wr_callback;
+
+ current->wr_callback = NULL;
+ clear_weakref(current);
+ if (callback != NULL) {
+ if (current->ob_refcnt > 0)
+ handle_callback(current, callback);
+ Py_DECREF(callback);
+ }
+ }
+ else {
+ PyObject *tuple;
+ Py_ssize_t i = 0;
+
+ tuple = PyTuple_New(count * 2);
+ if (tuple == NULL) {
+ _PyErr_ReplaceException(err_type, err_value, err_tb);
+ return;
+ }
+
+ for (i = 0; i < count; ++i) {
+ PyWeakReference *next = current->wr_next;
+
+ if (current->ob_refcnt > 0)
+ {
+ Py_INCREF(current);
+ PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+ PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+ }
+ else {
+ Py_DECREF(current->wr_callback);
+ }
+ current->wr_callback = NULL;
+ clear_weakref(current);
+ current = next;
+ }
+ for (i = 0; i < count; ++i) {
+ PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
+
+ /* The tuple may have slots left to NULL */
+ if (callback != NULL) {
+ PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
+ handle_callback((PyWeakReference *)item, callback);
+ }
+ }
+ Py_DECREF(tuple);
+ }
+ assert(!PyErr_Occurred());
+ PyErr_Restore(err_type, err_value, err_tb);
+ }
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/README b/AppPkg/Applications/Python/Python-2.7.10/README
new file mode 100644
index 0000000000..b5e2f298c5
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-2.7.10/README
@@ -0,0 +1,1236 @@
+This is Python version 2.7.10
+=============================
+
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+2012, 2013, 2014, 2015 Python Software Foundation. All rights reserved.
+
+Copyright (c) 2000 BeOpen.com.
+All rights reserved.
+
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.
+All rights reserved.
+
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
+All rights reserved.
+
+
+License information
+-------------------
+
+See the file "LICENSE" for information on the history of this
+software, terms & conditions for usage, and a DISCLAIMER OF ALL
+WARRANTIES.
+
+This Python distribution contains no GNU General Public Licensed
+(GPLed) code so it may be used in proprietary projects just like prior
+Python distributions. There are interfaces to some GNU code but these
+are entirely optional.
+
+All trademarks referenced herein are property of their respective
+holders.
+
+
+What's new in this release?
+---------------------------
+
+See the file "Misc/NEWS".
+
+
+If you don't read instructions
+------------------------------
+
+Congratulations on getting this far. :-)
+
+To start building right away (on UNIX): type "./configure" in the
+current directory and when it finishes, type "make". This creates an
+executable "./python"; to install in /usr/local, first do "su root"
+and then "make install".
+
+The section `Build instructions' below is still recommended reading.
+
+
+What is Python anyway?
+----------------------
+
+Python is an interpreted, interactive object-oriented programming
+language suitable (amongst other uses) for distributed application
+development, scripting, numeric computing and system testing. Python
+is often compared to Tcl, Perl, Java, JavaScript, Visual Basic or
+Scheme. To find out more about what Python can do for you, point your
+browser to http://www.python.org/.
+
+
+How do I learn Python?
+----------------------
+
+The official tutorial is still a good place to start; see
+http://docs.python.org/ for online and downloadable versions, as well
+as a list of other introductions, and reference documentation.
+
+There's a quickly growing set of books on Python. See
+http://wiki.python.org/moin/PythonBooks for a list.
+
+
+Documentation
+-------------
+
+All documentation is provided online in a variety of formats. In
+order of importance for new users: Tutorial, Library Reference,
+Language Reference, Extending & Embedding, and the Python/C API. The
+Library Reference is especially of immense value since much of
+Python's power is described there, including the built-in data types
+and functions!
+
+All documentation is also available online at the Python web site
+(http://docs.python.org/, see below). It is available online for occasional
+reference, or can be downloaded in many formats for faster access. The
+documentation is downloadable in HTML, PostScript, PDF, LaTeX, and
+reStructuredText (2.6+) formats; the LaTeX and reStructuredText versions are
+primarily for documentation authors, translators, and people with special
+formatting requirements.
+
+If you would like to contribute to the development of Python, relevant
+documentation is available at:
+
+ http://docs.python.org/devguide/
+
+For information about building Python's documentation, refer to Doc/README.txt.
+
+
+Web sites
+---------
+
+New Python releases and related technologies are published at
+http://www.python.org/. Come visit us!
+
+
+Newsgroups and Mailing Lists
+----------------------------
+
+Read comp.lang.python, a high-volume discussion newsgroup about
+Python, or comp.lang.python.announce, a low-volume moderated newsgroup
+for Python-related announcements. These are also accessible as
+mailing lists: see http://www.python.org/community/lists/ for an
+overview of these and many other Python-related mailing lists.
+
+Archives are accessible via the Google Groups Usenet archive; see
+http://groups.google.com/. The mailing lists are also archived, see
+http://www.python.org/community/lists/ for details.
+
+
+Bug reports
+-----------
+
+To report or search for bugs, please use the Python Bug
+Tracker at http://bugs.python.org/.
+
+
+Patches and contributions
+-------------------------
+
+To submit a patch or other contribution, please use the Python Patch
+Manager at http://bugs.python.org/. Guidelines
+for patch submission may be found at http://www.python.org/dev/patches/.
+
+If you have a proposal to change Python, you may want to send an email to the
+comp.lang.python or python-ideas mailing lists for inital feedback. A Python
+Enhancement Proposal (PEP) may be submitted if your idea gains ground. All
+current PEPs, as well as guidelines for submitting a new PEP, are listed at
+http://www.python.org/dev/peps/.
+
+
+Questions
+---------
+
+For help, if you can't find it in the manuals or on the web site, it's
+best to post to the comp.lang.python or the Python mailing list (see
+above). If you specifically don't want to involve the newsgroup or
+mailing list, send questions to help@python.org (a group of volunteers
+who answer questions as they can). The newsgroup is the most
+efficient way to ask public questions.
+
+
+Build instructions
+==================
+
+Before you can build Python, you must first configure it.
+Fortunately, the configuration and build process has been automated
+for Unix and Linux installations, so all you usually have to do is
+type a few commands and sit back. There are some platforms where
+things are not quite as smooth; see the platform specific notes below.
+If you want to build for multiple platforms sharing the same source
+tree, see the section on VPATH below.
+
+Start by running the script "./configure", which determines your
+system configuration and creates the Makefile. (It takes a minute or
+two -- please be patient!) You may want to pass options to the
+configure script -- see the section below on configuration options and
+variables. When it's done, you are ready to run make.
+
+To build Python, you normally type "make" in the toplevel directory.
+If you have changed the configuration, the Makefile may have to be
+rebuilt. In this case, you may have to run make again to correctly
+build your desired target. The interpreter executable is built in the
+top level directory.
+
+Once you have built a Python interpreter, see the subsections below on
+testing and installation. If you run into trouble, see the next
+section.
+
+Previous versions of Python used a manual configuration process that
+involved editing the file Modules/Setup. While this file still exists
+and manual configuration is still supported, it is rarely needed any
+more: almost all modules are automatically built as appropriate under
+guidance of the setup.py script, which is run by Make after the
+interpreter has been built.
+
+
+Troubleshooting
+---------------
+
+See also the platform specific notes in the next section.
+
+If you run into other trouble, see the FAQ
+(http://www.python.org/doc/faq/) for hints on what can go wrong, and
+how to fix it.
+
+If you rerun the configure script with different options, remove all
+object files by running "make clean" before rebuilding. Believe it or
+not, "make clean" sometimes helps to clean up other inexplicable
+problems as well. Try it before sending in a bug report!
+
+If the configure script fails or doesn't seem to find things that
+should be there, inspect the config.log file.
+
+If you get a warning for every file about the -Olimit option being no
+longer supported, you can ignore it. There's no foolproof way to know
+whether this option is needed; all we can do is test whether it is
+accepted without error. On some systems, e.g. older SGI compilers, it
+is essential for performance (specifically when compiling ceval.c,
+which has more basic blocks than the default limit of 1000). If the
+warning bothers you, edit the Makefile to remove "-Olimit 1500" from
+the OPT variable.
+
+If you get failures in test_long, or sys.maxint gets set to -1, you
+are probably experiencing compiler bugs, usually related to
+optimization. This is a common problem with some versions of gcc, and
+some vendor-supplied compilers, which can sometimes be worked around
+by turning off optimization. Consider switching to stable versions
+(gcc 2.95.2, gcc 3.x, or contact your vendor.)
+
+From Python 2.0 onward, all Python C code is ANSI C. Compiling using
+old K&R-C-only compilers is no longer possible. ANSI C compilers are
+available for all modern systems, either in the form of updated
+compilers from the vendor, or one of the free compilers (gcc).
+
+If "make install" fails mysteriously during the "compiling the library"
+step, make sure that you don't have any of the PYTHONPATH or PYTHONHOME
+environment variables set, as they may interfere with the newly built
+executable which is compiling the library.
+
+Unsupported systems
+-------------------
+
+A number of systems are not supported in Python 2.7 anymore. Some
+support code is still present, but will be removed in later versions.
+If you still need to use current Python versions on these systems,
+please send a message to python-dev@python.org indicating that you
+volunteer to support this system. For a more detailed discussion
+regarding no-longer-supported and resupporting platforms, as well
+as a list of platforms that became or will be unsupported, see PEP 11.
+
+More specifically, the following systems are not supported any
+longer:
+- SunOS 4
+- DYNIX
+- dgux
+- Minix
+- NeXT
+- Irix 4 and --with-sgi-dl
+- Linux 1
+- Systems defining __d6_pthread_create (configure.ac)
+- Systems defining PY_PTHREAD_D4, PY_PTHREAD_D6,
+ or PY_PTHREAD_D7 in thread_pthread.h
+- Systems using --with-dl-dld
+- Systems using --without-universal-newlines
+- MacOS 9
+- Systems using --with-wctype-functions
+- Win9x, WinME
+
+
+Platform specific notes
+-----------------------
+
+(Some of these may no longer apply. If you find you can build Python
+on these platforms without the special directions mentioned here,
+submit a documentation bug report to SourceForge (see Bug Reports
+above) so we can remove them!)
+
+Unix platforms: If your vendor still ships (and you still use) Berkeley DB
+ 1.85 you will need to edit Modules/Setup to build the bsddb185
+ module and add a line to sitecustomize.py which makes it the
+ default. In Modules/Setup a line like
+
+ bsddb185 bsddbmodule.c
+
+ should work. (You may need to add -I, -L or -l flags to direct the
+ compiler and linker to your include files and libraries.)
+
+XXX I think this next bit is out of date:
+
+64-bit platforms: The modules audioop, and imageop don't work.
+ The setup.py script disables them on 64-bit installations.
+ Don't try to enable them in the Modules/Setup file. They
+ contain code that is quite wordsize sensitive. (If you have a
+ fix, let us know!)
+
+Solaris: When using Sun's C compiler with threads, at least on Solaris
+ 2.5.1, you need to add the "-mt" compiler option (the simplest
+ way is probably to specify the compiler with this option as
+ the "CC" environment variable when running the configure
+ script).
+
+ When using GCC on Solaris, beware of binutils 2.13 or GCC
+ versions built using it. This mistakenly enables the
+ -zcombreloc option which creates broken shared libraries on
+ Solaris. binutils 2.12 works, and the binutils maintainers
+ are aware of the problem. Binutils 2.13.1 only partially
+ fixed things. It appears that 2.13.2 solves the problem
+ completely. This problem is known to occur with Solaris 2.7
+ and 2.8, but may also affect earlier and later versions of the
+ OS.
+
+ When the dynamic loader complains about errors finding shared
+ libraries, such as
+
+ ld.so.1: ./python: fatal: libstdc++.so.5: open failed:
+ No such file or directory
+
+ you need to first make sure that the library is available on
+ your system. Then, you need to instruct the dynamic loader how
+ to find it. You can choose any of the following strategies:
+
+ 1. When compiling Python, set LD_RUN_PATH to the directories
+ containing missing libraries.
+ 2. When running Python, set LD_LIBRARY_PATH to these directories.
+ 3. Use crle(8) to extend the search path of the loader.
+ 4. Modify the installed GCC specs file, adding -R options into the
+ *link: section.
+
+ The complex object fails to compile on Solaris 10 with gcc 3.4 (at
+ least up to 3.4.3). To work around it, define Py_HUGE_VAL as
+ HUGE_VAL(), e.g.:
+
+ make CPPFLAGS='-D"Py_HUGE_VAL=HUGE_VAL()" -I. -I$(srcdir)/Include'
+ ./python setup.py CPPFLAGS='-D"Py_HUGE_VAL=HUGE_VAL()"'
+
+Linux: A problem with threads and fork() was tracked down to a bug in
+ the pthreads code in glibc version 2.0.5; glibc version 2.0.7
+ solves the problem. This causes the popen2 test to fail;
+ problem and solution reported by Pablo Bleyer.
+
+Red Hat Linux: Red Hat 9 built Python2.2 in UCS-4 mode and hacked
+ Tcl to support it. To compile Python2.3 with Tkinter, you will
+ need to pass --enable-unicode=ucs4 flag to ./configure.
+
+ There's an executable /usr/bin/python which is Python
+ 1.5.2 on most older Red Hat installations; several key Red Hat tools
+ require this version. Python 2.1.x may be installed as
+ /usr/bin/python2. The Makefile installs Python as
+ /usr/local/bin/python, which may or may not take precedence
+ over /usr/bin/python, depending on how you have set up $PATH.
+
+FreeBSD 3.x and probably platforms with NCurses that use libmytinfo or
+ similar: When using cursesmodule, the linking is not done in
+ the correct order with the defaults. Remove "-ltermcap" from
+ the readline entry in Setup, and use as curses entry: "curses
+ cursesmodule.c -lmytinfo -lncurses -ltermcap" - "mytinfo" (so
+ called on FreeBSD) should be the name of the auxiliary library
+ required on your platform. Normally, it would be linked
+ automatically, but not necessarily in the correct order.
+
+BSDI: BSDI versions before 4.1 have known problems with threads,
+ which can cause strange errors in a number of modules (for
+ instance, the 'test_signal' test script will hang forever.)
+ Turning off threads (with --with-threads=no) or upgrading to
+ BSDI 4.1 solves this problem.
+
+DEC Unix: Run configure with --with-dec-threads, or with
+ --with-threads=no if no threads are desired (threads are on by
+ default). When using GCC, it is possible to get an internal
+ compiler error if optimization is used. This was reported for
+ GCC 2.7.2.3 on selectmodule.c. Manually compile the affected
+ file without optimization to solve the problem.
+
+DEC Ultrix: compile with GCC to avoid bugs in the native compiler,
+ and pass SHELL=/bin/sh5 to Make when installing.
+
+AIX: A complete overhaul of the shared library support is now in
+ place. See Misc/AIX-NOTES for some notes on how it's done.
+ (The optimizer bug reported at this place in previous releases
+ has been worked around by a minimal code change.) If you get
+ errors about pthread_* functions, during compile or during
+ testing, try setting CC to a thread-safe (reentrant) compiler,
+ like "cc_r". For full C++ module support, set CC="xlC_r" (or
+ CC="xlC" without thread support).
+
+AIX 5.3: To build a 64-bit version with IBM's compiler, I used the
+ following:
+
+ export PATH=/usr/bin:/usr/vacpp/bin
+ ./configure --with-gcc="xlc_r -q64" --with-cxx="xlC_r -q64" \
+ --disable-ipv6 AR="ar -X64"
+ make
+
+HP-UX: When using threading, you may have to add -D_REENTRANT to the
+ OPT variable in the top-level Makefile; reported by Pat Knight,
+ this seems to make a difference (at least for HP-UX 10.20)
+ even though pyconfig.h defines it. This seems unnecessary when
+ using HP/UX 11 and later - threading seems to work "out of the
+ box".
+
+HP-UX ia64: When building on the ia64 (Itanium) platform using HP's
+ compiler, some experience has shown that the compiler's
+ optimiser produces a completely broken version of python
+ (see http://bugs.python.org/814976). To work around this,
+ edit the Makefile and remove -O from the OPT line.
+
+ To build a 64-bit executable on an Itanium 2 system using HP's
+ compiler, use these environment variables:
+
+ CC=cc
+ CXX=aCC
+ BASECFLAGS="+DD64"
+ LDFLAGS="+DD64 -lxnet"
+
+ and call configure as:
+
+ ./configure --without-gcc
+
+ then *unset* the environment variables again before running
+ make. (At least one of these flags causes the build to fail
+ if it remains set.) You still have to edit the Makefile and
+ remove -O from the OPT line.
+
+HP PA-RISC 2.0: A recent bug report (http://bugs.python.org/546117)
+ suggests that the C compiler in this 64-bit system has bugs
+ in the optimizer that break Python. Compiling without
+ optimization solves the problems.
+
+SCO: The following apply to SCO 3 only; Python builds out of the box
+ on SCO 5 (or so we've heard).
+
+ 1) Everything works much better if you add -U__STDC__ to the
+ defs. This is because all the SCO header files are broken.
+ Anything that isn't mentioned in the C standard is
+ conditionally excluded when __STDC__ is defined.
+
+ 2) Due to the U.S. export restrictions, SCO broke the crypt
+ stuff out into a separate library, libcrypt_i.a so the LIBS
+ needed be set to:
+
+ LIBS=' -lsocket -lcrypt_i'
+
+UnixWare: There are known bugs in the math library of the system, as well as
+ problems in the handling of threads (calling fork in one
+ thread may interrupt system calls in others). Therefore, test_math and
+ tests involving threads will fail until those problems are fixed.
+
+QNX: Chris Herborth (chrish@qnx.com) writes:
+ configure works best if you use GNU bash; a port is available on
+ ftp.qnx.com in /usr/free. I used the following process to build,
+ test and install Python 1.5.x under QNX:
+
+ 1) CONFIG_SHELL=/usr/local/bin/bash CC=cc RANLIB=: \
+ ./configure --verbose --without-gcc --with-libm=""
+
+ 2) edit Modules/Setup to activate everything that makes sense for
+ your system... tested here at QNX with the following modules:
+
+ array, audioop, binascii, cPickle, cStringIO, cmath,
+ crypt, curses, errno, fcntl, gdbm, grp, imageop,
+ _locale, math, md5, new, operator, parser, pcre,
+ posix, pwd, readline, regex, reop,
+ select, signal, socket, soundex, strop, struct,
+ syslog, termios, time, timing, zlib, audioop, imageop
+
+ 3) make SHELL=/usr/local/bin/bash
+
+ or, if you feel the need for speed:
+
+ make SHELL=/usr/local/bin/bash OPT="-5 -Oil+nrt"
+
+ 4) make SHELL=/usr/local/bin/bash test
+
+ Using GNU readline 2.2 seems to behave strangely, but I
+ think that's a problem with my readline 2.2 port. :-\
+
+ 5) make SHELL=/usr/local/bin/bash install
+
+ If you get SIGSEGVs while running Python (I haven't yet, but
+ I've only run small programs and the test cases), you're
+ probably running out of stack; the default 32k could be a
+ little tight. To increase the stack size, edit the Makefile
+ to read: LDFLAGS = -N 48k
+
+BeOS: See Misc/BeOS-NOTES for notes about compiling/installing
+ Python on BeOS R3 or later. Note that only the PowerPC
+ platform is supported for R3; both PowerPC and x86 are
+ supported for R4.
+
+Cray T3E: Mark Hadfield (m.hadfield@niwa.co.nz) writes:
+ Python can be built satisfactorily on a Cray T3E but based on
+ my experience with the NIWA T3E (2002-05-22, version 2.2.1)
+ there are a few bugs and gotchas. For more information see a
+ thread on comp.lang.python in May 2002 entitled "Building
+ Python on Cray T3E".
+
+ 1) Use Cray's cc and not gcc. The latter was reported not to
+ work by Konrad Hinsen. It may work now, but it may not.
+
+ 2) To set sys.platform to something sensible, pass the
+ following environment variable to the configure script:
+
+ MACHDEP=unicosmk
+
+ 2) Run configure with option "--enable-unicode=ucs4".
+
+ 3) The Cray T3E does not support dynamic linking, so extension
+ modules have to be built by adding (or uncommenting) lines
+ in Modules/Setup. The minimum set of modules is
+
+ posix, new, _sre, unicodedata
+
+ On NIWA's vanilla T3E system the following have also been
+ included successfully:
+
+ _codecs, _locale, _socket, _symtable, _testcapi, _weakref
+ array, binascii, cmath, cPickle, crypt, cStringIO, dbm
+ errno, fcntl, grp, math, md5, operator, parser, pcre, pwd
+ regex, rotor, select, struct, strop, syslog, termios
+ time, timing, xreadlines
+
+ 4) Once the python executable and library have been built, make
+ will execute setup.py, which will attempt to build remaining
+ extensions and link them dynamically. Each of these attempts
+ will fail but should not halt the make process. This is
+ normal.
+
+ 5) Running "make test" uses a lot of resources and causes
+ problems on our system. You might want to try running tests
+ singly or in small groups.
+
+SGI: SGI's standard "make" utility (/bin/make or /usr/bin/make)
+ does not check whether a command actually changed the file it
+ is supposed to build. This means that whenever you say "make"
+ it will redo the link step. The remedy is to use SGI's much
+ smarter "smake" utility (/usr/sbin/smake), or GNU make. If
+ you set the first line of the Makefile to #!/usr/sbin/smake
+ smake will be invoked by make (likewise for GNU make).
+
+ WARNING: There are bugs in the optimizer of some versions of
+ SGI's compilers that can cause bus errors or other strange
+ behavior, especially on numerical operations. To avoid this,
+ try building with "make OPT=".
+
+OS/2: If you are running Warp3 or Warp4 and have IBM's VisualAge C/C++
+ compiler installed, just change into the pc\os2vacpp directory
+ and type NMAKE. Threading and sockets are supported by default
+ in the resulting binaries of PYTHON15.DLL and PYTHON.EXE.
+
+Reliant UNIX: The thread support does not compile on Reliant UNIX, and
+ there is a (minor) problem in the configure script for that
+ platform as well. This should be resolved in time for a
+ future release.
+
+MacOSX: The tests will crash on both 10.1 and 10.2 with SEGV in
+ test_re and test_sre due to the small default stack size. If
+ you set the stack size to 2048 before doing a "make test" the
+ failure can be avoided. If you're using the tcsh or csh shells,
+ use "limit stacksize 2048" and for the bash shell (the default
+ as of OSX 10.3), use "ulimit -s 2048".
+
+ On naked Darwin you may want to add the configure option
+ "--disable-toolbox-glue" to disable the glue code for the Carbon
+ interface modules. The modules themselves are currently only built
+ if you add the --enable-framework option, see below.
+
+ On a clean OSX /usr/local does not exist. Do a
+ "sudo mkdir -m 775 /usr/local"
+ before you do a make install. It is probably not a good idea to
+ do "sudo make install" which installs everything as superuser,
+ as this may later cause problems when installing distutils-based
+ additions.
+
+ Some people have reported problems building Python after using "fink"
+ to install additional unix software. Disabling fink (remove all
+ references to /sw from your .profile or .login) should solve this.
+
+ You may want to try the configure option "--enable-framework"
+ which installs Python as a framework. The location can be set
+ as argument to the --enable-framework option (default
+ /Library/Frameworks). A framework install is probably needed if you
+ want to use any Aqua-based GUI toolkit (whether Tkinter, wxPython,
+ Carbon, Cocoa or anything else).
+
+ You may also want to try the configure option "--enable-universalsdk"
+ which builds Python as a universal binary with support for the
+ i386 and PPC architetures. This requires Xcode 2.1 or later to build.
+
+ See Mac/README for more information on framework and
+ universal builds.
+
+Cygwin: With recent (relative to the time of writing, 2001-12-19)
+ Cygwin installations, there are problems with the interaction
+ of dynamic linking and fork(). This manifests itself in build
+ failures during the execution of setup.py.
+
+ There are two workarounds that both enable Python (albeit
+ without threading support) to build and pass all tests on
+ NT/2000 (and most likely XP as well, though reports of testing
+ on XP would be appreciated).
+
+ The workarounds:
+
+ (a) the band-aid fix is to link the _socket module statically
+ rather than dynamically (which is the default).
+
+ To do this, run "./configure --with-threads=no" including any
+ other options you need (--prefix, etc.). Then in Modules/Setup
+ uncomment the lines:
+
+ #SSL=/usr/local/ssl
+ #_socket socketmodule.c \
+ # -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+ # -L$(SSL)/lib -lssl -lcrypto
+
+ and remove "local/" from the SSL variable. Finally, just run
+ "make"!
+
+ (b) The "proper" fix is to rebase the Cygwin DLLs to prevent
+ base address conflicts. Details on how to do this can be
+ found in the following mail:
+
+ http://sources.redhat.com/ml/cygwin/2001-12/msg00894.html
+
+ It is hoped that a version of this solution will be
+ incorporated into the Cygwin distribution fairly soon.
+
+ Two additional problems:
+
+ (1) Threading support should still be disabled due to a known
+ bug in Cygwin pthreads that causes test_threadedtempfile to
+ hang.
+
+ (2) The _curses module does not build. This is a known
+ Cygwin ncurses problem that should be resolved the next time
+ that this package is released.
+
+ On older versions of Cygwin, test_poll may hang and test_strftime
+ may fail.
+
+ The situation on 9X/Me is not accurately known at present.
+ Some time ago, there were reports that the following
+ regression tests failed:
+
+ test_pwd
+ test_select (hang)
+ test_socket
+
+ Due to the test_select hang on 9X/Me, one should run the
+ regression test using the following:
+
+ make TESTOPTS='-l -x test_select' test
+
+ News regarding these platforms with more recent Cygwin
+ versions would be appreciated!
+
+Windows: When executing Python scripts on the command line using file type
+ associations (i.e. starting "script.py" instead of "python script.py"),
+ redirects may not work unless you set a specific registry key. See
+ the Knowledge Base article <http://support.microsoft.com/kb/321788>.
+
+
+Configuring the bsddb and dbm modules
+-------------------------------------
+
+Beginning with Python version 2.3, the PyBsddb package
+<http://pybsddb.sf.net/> was adopted into Python as the bsddb package,
+exposing a set of package-level functions which provide
+backwards-compatible behavior. Only versions 3.3 through 4.4 of
+Sleepycat's libraries provide the necessary API, so older versions
+aren't supported through this interface. The old bsddb module has
+been retained as bsddb185, though it is not built by default. Users
+wishing to use it will have to tweak Modules/Setup to build it. The
+dbm module will still be built against the Sleepycat libraries if
+other preferred alternatives (ndbm, gdbm) are not found.
+
+Building the sqlite3 module
+---------------------------
+
+To build the sqlite3 module, you'll need the sqlite3 or libsqlite3
+packages installed, including the header files. Many modern operating
+systems distribute the headers in a separate package to the library -
+often it will be the same name as the main package, but with a -dev or
+-devel suffix.
+
+The version of pysqlite2 that's including in Python needs sqlite3 3.0.8
+or later. setup.py attempts to check that it can find a correct version.
+
+Configuring threads
+-------------------
+
+As of Python 2.0, threads are enabled by default. If you wish to
+compile without threads, or if your thread support is broken, pass the
+--with-threads=no switch to configure. Unfortunately, on some
+platforms, additional compiler and/or linker options are required for
+threads to work properly. Below is a table of those options,
+collected by Bill Janssen. We would love to automate this process
+more, but the information below is not enough to write a patch for the
+configure.ac file, so manual intervention is required. If you patch
+the configure.ac file and are confident that the patch works, please
+send in the patch. (Don't bother patching the configure script itself
+-- it is regenerated each time the configure.ac file changes.)
+
+Compiler switches for threads
+.............................
+
+The definition of _REENTRANT should be configured automatically, if
+that does not work on your system, or if _REENTRANT is defined
+incorrectly, please report that as a bug.
+
+ OS/Compiler/threads Switches for use with threads
+ (POSIX is draft 10, DCE is draft 4) compile & link
+
+ SunOS 5.{1-5}/{gcc,SunPro cc}/solaris -mt
+ SunOS 5.5/{gcc,SunPro cc}/POSIX (nothing)
+ DEC OSF/1 3.x/cc/DCE -threads
+ (butenhof@zko.dec.com)
+ Digital UNIX 4.x/cc/DCE -threads
+ (butenhof@zko.dec.com)
+ Digital UNIX 4.x/cc/POSIX -pthread
+ (butenhof@zko.dec.com)
+ AIX 4.1.4/cc_r/d7 (nothing)
+ (buhrt@iquest.net)
+ AIX 4.1.4/cc_r4/DCE (nothing)
+ (buhrt@iquest.net)
+ IRIX 6.2/cc/POSIX (nothing)
+ (robertl@cwi.nl)
+
+
+Linker (ld) libraries and flags for threads
+...........................................
+
+ OS/threads Libraries/switches for use with threads
+
+ SunOS 5.{1-5}/solaris -lthread
+ SunOS 5.5/POSIX -lpthread
+ DEC OSF/1 3.x/DCE -lpthreads -lmach -lc_r -lc
+ (butenhof@zko.dec.com)
+ Digital UNIX 4.x/DCE -lpthreads -lpthread -lmach -lexc -lc
+ (butenhof@zko.dec.com)
+ Digital UNIX 4.x/POSIX -lpthread -lmach -lexc -lc
+ (butenhof@zko.dec.com)
+ AIX 4.1.4/{draft7,DCE} (nothing)
+ (buhrt@iquest.net)
+ IRIX 6.2/POSIX -lpthread
+ (jph@emilia.engr.sgi.com)
+
+
+Building a shared libpython
+---------------------------
+
+Starting with Python 2.3, the majority of the interpreter can be built
+into a shared library, which can then be used by the interpreter
+executable, and by applications embedding Python. To enable this feature,
+configure with --enable-shared.
+
+If you enable this feature, the same object files will be used to create
+a static library. In particular, the static library will contain object
+files using position-independent code (PIC) on platforms where PIC flags
+are needed for the shared library.
+
+
+Configuring additional built-in modules
+---------------------------------------
+
+Starting with Python 2.1, the setup.py script at the top of the source
+distribution attempts to detect which modules can be built and
+automatically compiles them. Autodetection doesn't always work, so
+you can still customize the configuration by editing the Modules/Setup
+file; but this should be considered a last resort. The rest of this
+section only applies if you decide to edit the Modules/Setup file.
+You also need this to enable static linking of certain modules (which
+is needed to enable profiling on some systems).
+
+This file is initially copied from Setup.dist by the configure script;
+if it does not exist yet, create it by copying Modules/Setup.dist
+yourself (configure will never overwrite it). Never edit Setup.dist
+-- always edit Setup or Setup.local (see below). Read the comments in
+the file for information on what kind of edits are allowed. When you
+have edited Setup in the Modules directory, the interpreter will
+automatically be rebuilt the next time you run make (in the toplevel
+directory).
+
+Many useful modules can be built on any Unix system, but some optional
+modules can't be reliably autodetected. Often the quickest way to
+determine whether a particular module works or not is to see if it
+will build: enable it in Setup, then if you get compilation or link
+errors, disable it -- you're either missing support or need to adjust
+the compilation and linking parameters for that module.
+
+On SGI IRIX, there are modules that interface to many SGI specific
+system libraries, e.g. the GL library and the audio hardware. These
+modules will not be built by the setup.py script.
+
+In addition to the file Setup, you can also edit the file Setup.local.
+(the makesetup script processes both). You may find it more
+convenient to edit Setup.local and leave Setup alone. Then, when
+installing a new Python version, you can copy your old Setup.local
+file.
+
+
+Setting the optimization/debugging options
+------------------------------------------
+
+If you want or need to change the optimization/debugging options for
+the C compiler, assign to the OPT variable on the toplevel make
+command; e.g. "make OPT=-g" will build a debugging version of Python
+on most platforms. The default is OPT=-O; a value for OPT in the
+environment when the configure script is run overrides this default
+(likewise for CC; and the initial value for LIBS is used as the base
+set of libraries to link with).
+
+When compiling with GCC, the default value of OPT will also include
+the -Wall and -Wstrict-prototypes options.
+
+Additional debugging code to help debug memory management problems can
+be enabled by using the --with-pydebug option to the configure script.
+
+For flags that change binary compatibility, use the EXTRA_CFLAGS
+variable.
+
+
+Profiling
+---------
+
+If you want C profiling turned on, the easiest way is to run configure
+with the CC environment variable to the necessary compiler
+invocation. For example, on Linux, this works for profiling using
+gprof(1):
+
+ CC="gcc -pg" ./configure
+
+Note that on Linux, gprof apparently does not work for shared
+libraries. The Makefile/Setup mechanism can be used to compile and
+link most extension modules statically.
+
+
+Coverage checking
+-----------------
+
+For C coverage checking using gcov, run "make coverage". This will
+build a Python binary with profiling activated, and a ".gcno" and
+".gcda" file for every source file compiled with that option. With
+the built binary, now run the code whose coverage you want to check.
+Then, you can see coverage statistics for each individual source file
+by running gcov, e.g.
+
+ gcov -o Modules zlibmodule
+
+This will create a "zlibmodule.c.gcov" file in the current directory
+containing coverage info for that source file.
+
+This works only for source files statically compiled into the
+executable; use the Makefile/Setup mechanism to compile and link
+extension modules you want to coverage-check statically.
+
+
+Testing
+-------
+
+To test the interpreter, type "make test" in the top-level directory.
+This runs the test set twice (once with no compiled files, once with
+the compiled files left by the previous test run). The test set
+produces some output. You can generally ignore the messages about
+skipped tests due to optional features which can't be imported.
+If a message is printed about a failed test or a traceback or core
+dump is produced, something is wrong. On some Linux systems (those
+that are not yet using glibc 6), test_strftime fails due to a
+non-standard implementation of strftime() in the C library. Please
+ignore this, or upgrade to glibc version 6.
+
+By default, tests are prevented from overusing resources like disk space and
+memory. To enable these tests, run "make testall".
+
+IMPORTANT: If the tests fail and you decide to mail a bug report,
+*don't* include the output of "make test". It is useless. Run the
+failing test manually, as follows:
+
+ ./python Lib/test/regrtest.py -v test_whatever
+
+(substituting the top of the source tree for '.' if you built in a
+different directory). This runs the test in verbose mode.
+
+
+Installing
+----------
+
+To install the Python binary, library modules, shared library modules
+(see below), include files, configuration files, and the manual page,
+just type
+
+ make install
+
+This will install all platform-independent files in subdirectories of
+the directory given with the --prefix option to configure or to the
+`prefix' Make variable (default /usr/local). All binary and other
+platform-specific files will be installed in subdirectories if the
+directory given by --exec-prefix or the `exec_prefix' Make variable
+(defaults to the --prefix directory) is given.
+
+If DESTDIR is set, it will be taken as the root directory of the
+installation, and files will be installed into $(DESTDIR)$(prefix),
+$(DESTDIR)$(exec_prefix), etc.
+
+All subdirectories created will have Python's version number in their
+name, e.g. the library modules are installed in
+"/usr/local/lib/python<version>/" by default, where <version> is the
+<major>.<minor> release number (e.g. "2.1"). The Python binary is
+installed as "python<version>" and a hard link named "python" is
+created. The only file not installed with a version number in its
+name is the manual page, installed as "/usr/local/man/man1/python.1"
+by default.
+
+If you want to install multiple versions of Python see the section below
+entitled "Installing multiple versions".
+
+The only thing you may have to install manually is the Python mode for
+Emacs found in Misc/python-mode.el. (But then again, more recent
+versions of Emacs may already have it.) Follow the instructions that
+came with Emacs for installation of site-specific files.
+
+On Mac OS X, if you have configured Python with --enable-framework, you
+should use "make frameworkinstall" to do the installation. Note that this
+installs the Python executable in a place that is not normally on your
+PATH, you may want to set up a symlink in /usr/local/bin.
+
+
+Installing multiple versions
+----------------------------
+
+On Unix and Mac systems if you intend to install multiple versions of Python
+using the same installation prefix (--prefix argument to the configure
+script) you must take care that your primary python executable is not
+overwritten by the installation of a different version. All files and
+directories installed using "make altinstall" contain the major and minor
+version and can thus live side-by-side. "make install" also creates
+${prefix}/bin/python which refers to ${prefix}/bin/pythonX.Y. If you intend
+to install multiple versions using the same prefix you must decide which
+version (if any) is your "primary" version. Install that version using
+"make install". Install all other versions using "make altinstall".
+
+For example, if you want to install Python 2.5, 2.6 and 3.0 with 2.6 being
+the primary version, you would execute "make install" in your 2.6 build
+directory and "make altinstall" in the others.
+
+
+Configuration options and variables
+-----------------------------------
+
+Some special cases are handled by passing options to the configure
+script.
+
+WARNING: if you rerun the configure script with different options, you
+must run "make clean" before rebuilding. Exceptions to this rule:
+after changing --prefix or --exec-prefix, all you need to do is remove
+Modules/getpath.o.
+
+--with(out)-gcc: The configure script uses gcc (the GNU C compiler) if
+ it finds it. If you don't want this, or if this compiler is
+ installed but broken on your platform, pass the option
+ --without-gcc. You can also pass "CC=cc" (or whatever the
+ name of the proper C compiler is) in the environment, but the
+ advantage of using --without-gcc is that this option is
+ remembered by the config.status script for its --recheck
+ option.
+
+--prefix, --exec-prefix: If you want to install the binaries and the
+ Python library somewhere else than in /usr/local/{bin,lib},
+ you can pass the option --prefix=DIRECTORY; the interpreter
+ binary will be installed as DIRECTORY/bin/python and the
+ library files as DIRECTORY/lib/python/*. If you pass
+ --exec-prefix=DIRECTORY (as well) this overrides the
+ installation prefix for architecture-dependent files (like the
+ interpreter binary). Note that --prefix=DIRECTORY also
+ affects the default module search path (sys.path), when
+ Modules/config.c is compiled. Passing make the option
+ prefix=DIRECTORY (and/or exec_prefix=DIRECTORY) overrides the
+ prefix set at configuration time; this may be more convenient
+ than re-running the configure script if you change your mind
+ about the install prefix.
+
+--with-readline: This option is no longer supported. GNU
+ readline is automatically enabled by setup.py when present.
+
+--with-threads: On most Unix systems, you can now use multiple
+ threads, and support for this is enabled by default. To
+ disable this, pass --with-threads=no. If the library required
+ for threads lives in a peculiar place, you can use
+ --with-thread=DIRECTORY. IMPORTANT: run "make clean" after
+ changing (either enabling or disabling) this option, or you
+ will get link errors! Note: for DEC Unix use
+ --with-dec-threads instead.
+
+--with-sgi-dl: On SGI IRIX 4, dynamic loading of extension modules is
+ supported by the "dl" library by Jack Jansen, which is
+ ftp'able from ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z.
+ This is enabled (after you've ftp'ed and compiled the dl
+ library) by passing --with-sgi-dl=DIRECTORY where DIRECTORY
+ is the absolute pathname of the dl library. (Don't bother on
+ IRIX 5, it already has dynamic linking using SunOS style
+ shared libraries.) THIS OPTION IS UNSUPPORTED.
+
+--with-dl-dld: Dynamic loading of modules is rumored to be supported
+ on some other systems: VAX (Ultrix), Sun3 (SunOS 3.4), Sequent
+ Symmetry (Dynix), and Atari ST. This is done using a
+ combination of the GNU dynamic loading package
+ (ftp://ftp.cwi.nl/pub/dynload/dl-dld-1.1.tar.Z) and an
+ emulation of the SGI dl library mentioned above (the emulation
+ can be found at
+ ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z). To
+ enable this, ftp and compile both libraries, then call
+ configure, passing it the option
+ --with-dl-dld=DL_DIRECTORY,DLD_DIRECTORY where DL_DIRECTORY is
+ the absolute pathname of the dl emulation library and
+ DLD_DIRECTORY is the absolute pathname of the GNU dld library.
+ (Don't bother on SunOS 4 or 5, they already have dynamic
+ linking using shared libraries.) THIS OPTION IS UNSUPPORTED.
+
+--with-libm, --with-libc: It is possible to specify alternative
+ versions for the Math library (default -lm) and the C library
+ (default the empty string) using the options
+ --with-libm=STRING and --with-libc=STRING, respectively. For
+ example, if your system requires that you pass -lc_s to the C
+ compiler to use the shared C library, you can pass
+ --with-libc=-lc_s. These libraries are passed after all other
+ libraries, the C library last.
+
+--with-libs='libs': Add 'libs' to the LIBS that the python interpreter
+ is linked against.
+
+--with-cxx-main=<compiler>: If you plan to use C++ extension modules,
+ then -- on some platforms -- you need to compile python's main()
+ function with the C++ compiler. With this option, make will use
+ <compiler> to compile main() *and* to link the python executable.
+ It is likely that the resulting executable depends on the C++
+ runtime library of <compiler>. (The default is --without-cxx-main.)
+
+ There are platforms that do not require you to build Python
+ with a C++ compiler in order to use C++ extension modules.
+ E.g., x86 Linux with ELF shared binaries and GCC 3.x, 4.x is such
+ a platform. We recommend that you configure Python
+ --without-cxx-main on those platforms because a mismatch
+ between the C++ compiler version used to build Python and to
+ build a C++ extension module is likely to cause a crash at
+ runtime.
+
+ The Python installation also stores the variable CXX that
+ determines, e.g., the C++ compiler distutils calls by default
+ to build C++ extensions. If you set CXX on the configure command
+ line to any string of non-zero length, then configure won't
+ change CXX. If you do not preset CXX but pass
+ --with-cxx-main=<compiler>, then configure sets CXX=<compiler>.
+ In all other cases, configure looks for a C++ compiler by
+ some common names (c++, g++, gcc, CC, cxx, cc++, cl) and sets
+ CXX to the first compiler it finds. If it does not find any
+ C++ compiler, then it sets CXX="".
+
+ Similarly, if you want to change the command used to link the
+ python executable, then set LINKCC on the configure command line.
+
+
+--with-pydebug: Enable additional debugging code to help track down
+ memory management problems. This allows printing a list of all
+ live objects when the interpreter terminates.
+
+--with(out)-universal-newlines: enable reading of text files with
+ foreign newline convention (default: enabled). In other words,
+ any of \r, \n or \r\n is acceptable as end-of-line character.
+ If enabled import and execfile will automatically accept any newline
+ in files. Python code can open a file with open(file, 'U') to
+ read it in universal newline mode. THIS OPTION IS UNSUPPORTED.
+
+--with-tsc: Profile using the Pentium timestamping counter (TSC).
+
+--with-system-ffi: Build the _ctypes extension module using an ffi
+ library installed on the system.
+
+--with-dbmliborder=db1:db2:...: Specify the order that backends for the
+ dbm extension are checked. Valid value is a colon separated string
+ with the backend names `ndbm', `gdbm' and `bdb'.
+
+Building for multiple architectures (using the VPATH feature)
+-------------------------------------------------------------
+
+If your file system is shared between multiple architectures, it
+usually is not necessary to make copies of the sources for each
+architecture you want to support. If the make program supports the
+VPATH feature, you can create an empty build directory for each
+architecture, and in each directory run the configure script (on the
+appropriate machine with the appropriate options). This creates the
+necessary subdirectories and the Makefiles therein. The Makefiles
+contain a line VPATH=... which points to a directory containing the
+actual sources. (On SGI systems, use "smake -J1" instead of "make" if
+you use VPATH -- don't try gnumake.)
+
+For example, the following is all you need to build a minimal Python
+in /usr/tmp/python (assuming ~guido/src/python is the toplevel
+directory and you want to build in /usr/tmp/python):
+
+ $ mkdir /usr/tmp/python
+ $ cd /usr/tmp/python
+ $ ~guido/src/python/configure
+ [...]
+ $ make
+ [...]
+ $
+
+Note that configure copies the original Setup file to the build
+directory if it finds no Setup file there. This means that you can
+edit the Setup file for each architecture independently. For this
+reason, subsequent changes to the original Setup file are not tracked
+automatically, as they might overwrite local changes. To force a copy
+of a changed original Setup file, delete the target Setup file. (The
+makesetup script supports multiple input files, so if you want to be
+fancy you can change the rules to create an empty Setup.local if it
+doesn't exist and run it with arguments $(srcdir)/Setup Setup.local;
+however this assumes that you only need to add modules.)
+
+Also note that you can't use a workspace for VPATH and non VPATH builds. The
+object files left behind by one version confuses the other.
+
+
+Building on non-UNIX systems
+----------------------------
+
+For Windows (2000/NT/ME/98/95), assuming you have MS VC++ 7.1, the
+project files are in PCbuild, the workspace is pcbuild.dsw. See
+PCbuild\readme.txt for detailed instructions.
+
+For other non-Unix Windows compilers, in particular MS VC++ 6.0 and
+for OS/2, enter the directory "PC" and read the file "readme.txt".
+
+For the Mac, a separate source distribution will be made available,
+for use with the CodeWarrior compiler. If you are interested in Mac
+development, join the PythonMac Special Interest Group
+(http://www.python.org/sigs/pythonmac-sig/, or send email to
+pythonmac-sig-request@python.org).
+
+Of course, there are also binary distributions available for these
+platforms -- see http://www.python.org/.
+
+To port Python to a new non-UNIX system, you will have to fake the
+effect of running the configure script manually (for Mac and PC, this
+has already been done for you). A good start is to copy the file
+pyconfig.h.in to pyconfig.h and edit the latter to reflect the actual
+configuration of your system. Most symbols must simply be defined as
+1 only if the corresponding feature is present and can be left alone
+otherwise; however the *_t type symbols must be defined as some
+variant of int if they need to be defined at all.
+
+For all platforms, it's important that the build arrange to define the
+preprocessor symbol NDEBUG on the compiler command line in a release
+build of Python (else assert() calls remain in the code, hurting
+release-build performance). The Unix, Windows and Mac builds already
+do this.
+
+
+Miscellaneous issues
+====================
+
+Emacs mode
+----------
+
+There's an excellent Emacs editing mode for Python code; see the file
+Misc/python-mode.el. Originally written by the famous Tim Peters, it is now
+maintained by the equally famous Barry Warsaw. The latest version, along with
+various other contributed Python-related Emacs goodies, is online at
+http://launchpad.net/python-mode/.
+
+
+Tkinter
+-------
+
+The setup.py script automatically configures this when it detects a
+usable Tcl/Tk installation. This requires Tcl/Tk version 8.0 or
+higher.
+
+For more Tkinter information, see the Tkinter Resource page:
+http://www.python.org/topics/tkinter/
+
+There are demos in the Demo/tkinter directory.
+
+Note that there's a Python module called "Tkinter" (capital T) which
+lives in Lib/lib-tk/Tkinter.py, and a C module called "_tkinter"
+(lower case t and leading underscore) which lives in
+Modules/_tkinter.c. Demos and normal Tk applications import only the
+Python Tkinter module -- only the latter imports the C _tkinter
+module. In order to find the C _tkinter module, it must be compiled
+and linked into the Python interpreter -- the setup.py script does
+this. In order to find the Python Tkinter module, sys.path must be
+set correctly -- normal installation takes care of this.
+
+
+Distribution structure
+----------------------
+
+Most subdirectories have their own README files. Most files have
+comments.
+
+Demo/ Demonstration scripts, modules and programs
+Doc/ Documentation sources (reStructuredText)
+Grammar/ Input for the parser generator
+Include/ Public header files
+LICENSE Licensing information
+Lib/ Python library modules
+Mac/ Macintosh specific resources
+Makefile.pre.in Source from which config.status creates the Makefile.pre
+Misc/ Miscellaneous useful files
+Modules/ Implementation of most built-in modules
+Objects/ Implementation of most built-in object types
+PC/ Files specific to PC ports (DOS, Windows, OS/2)
+PCbuild/ Build directory for Microsoft Visual C++
+Parser/ The parser and tokenizer and their input handling
+Python/ The byte-compiler and interpreter
+README The file you're reading now
+RISCOS/ Files specific to RISC OS port
+Tools/ Some useful programs written in Python
+pyconfig.h.in Source from which pyconfig.h is created (GNU autoheader output)
+configure Configuration shell script (GNU autoconf output)
+configure.ac Configuration specification (input for GNU autoconf)
+install-sh Shell script used to install files
+setup.py Python script used to build extension modules
+
+The following files will (may) be created in the toplevel directory by
+the configuration and build processes:
+
+Makefile Build rules
+Makefile.pre Build rules before running Modules/makesetup
+buildno Keeps track of the build number
+config.cache Cache of configuration variables
+pyconfig.h Configuration header
+config.log Log from last configure run
+config.status Status from last run of the configure script
+getbuildinfo.o Object file from Modules/getbuildinfo.c
+libpython<version>.a The library archive
+python The executable interpreter
+reflog.txt Output from running the regression suite with the -R flag
+tags, TAGS Tags files for vi and Emacs
+
+
+That's all, folks!
+------------------
+
+
+--Guido van Rossum (home page: http://www.python.org/~guido/)