From baee16f3ee466806c204f73158428741ad8eb4a7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 28 Jun 2009 16:23:55 +0000 Subject: fix useless comparison #6355 --- Objects/capsule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/capsule.c b/Objects/capsule.c index 5304ce11f1..3d2d626ade 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -33,7 +33,7 @@ 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 name2 == name2; + return name1 == name2; } return !strcmp(name1, name2); } -- cgit v1.2.1 From 4506d5bfb7ba4ce67acadb33e5b3ea4f18937be6 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 28 Jun 2009 17:22:03 +0000 Subject: Merged revisions 73004,73439,73496,73509,73529,73564,73576-73577,73595-73596,73605 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73004 | jeffrey.yasskin | 2009-05-28 22:44:31 -0500 (Thu, 28 May 2009) | 5 lines Fix nearly all compilation warnings under Apple gcc-4.0. Tested with OPT="-g -Wall -Wstrict-prototypes -Werror" in both --with-pydebug mode and --without. There's still a batch of non-prototype warnings in Xlib.h that I don't know how to fix. ........ r73439 | benjamin.peterson | 2009-06-15 19:29:31 -0500 (Mon, 15 Jun 2009) | 1 line don't mask encoding errors when decoding a string #6289 ........ r73496 | vinay.sajip | 2009-06-21 12:37:27 -0500 (Sun, 21 Jun 2009) | 1 line Issue #6314: logging.basicConfig() performs extra checks on the "level" argument. ........ r73509 | amaury.forgeotdarc | 2009-06-22 14:33:48 -0500 (Mon, 22 Jun 2009) | 2 lines #4490 Fix sample code run by "python -m xml.sax.xmlreader" ........ r73529 | r.david.murray | 2009-06-23 13:02:46 -0500 (Tue, 23 Jun 2009) | 4 lines Fix issue 5230 by having pydoc's safeimport check to see if the import error was thrown from itself in order to decide if the module can't be found. Thanks to Lucas Prado Melo for collaborating on the fix and tests. ........ r73564 | amaury.forgeotdarc | 2009-06-25 17:29:29 -0500 (Thu, 25 Jun 2009) | 6 lines #2016 Fix a crash in function call when the **kwargs dictionary is mutated during the function call setup. This even gives a slight speedup, probably because tuple allocation is faster than PyMem_NEW. ........ r73576 | benjamin.peterson | 2009-06-26 18:37:06 -0500 (Fri, 26 Jun 2009) | 1 line document is_declared_global() ........ r73577 | benjamin.peterson | 2009-06-27 09:16:23 -0500 (Sat, 27 Jun 2009) | 1 line link to extensive generator docs in the reference manual ........ r73595 | ezio.melotti | 2009-06-27 18:45:39 -0500 (Sat, 27 Jun 2009) | 1 line stmt and setup can contain multiple statements, see #5896 ........ r73596 | ezio.melotti | 2009-06-27 19:07:45 -0500 (Sat, 27 Jun 2009) | 1 line Fixed a wrong apostrophe ........ r73605 | georg.brandl | 2009-06-28 07:10:18 -0500 (Sun, 28 Jun 2009) | 1 line Remove stray pychecker directive. ........ --- Objects/funcobject.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/funcobject.c b/Objects/funcobject.c index acd662cb32..1456810057 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -593,13 +593,14 @@ 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_Size(argdefs); + nd = PyTuple_GET_SIZE(argdefs); } else { d = NULL; @@ -609,16 +610,17 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw) if (kw != NULL && PyDict_Check(kw)) { Py_ssize_t pos, i; nk = PyDict_Size(kw); - k = PyMem_NEW(PyObject *, 2*nk); - if (k == NULL) { - PyErr_NoMemory(); + 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])) + while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); i += 2; + } nk = i/2; - /* XXX This is broken if the caller deletes dict items! */ } else { k = NULL; @@ -628,13 +630,12 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw) result = PyEval_EvalCodeEx( (PyCodeObject *)PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), (PyObject *)NULL, - &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), + &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg), k, nk, d, nd, PyFunction_GET_KW_DEFAULTS(func), PyFunction_GET_CLOSURE(func)); - if (k != NULL) - PyMem_DEL(k); + Py_XDECREF(kwtuple); return result; } -- cgit v1.2.1 From fdeceae09c9611b47d4b7b031b6b602c38913e88 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 28 Jun 2009 19:19:51 +0000 Subject: Merged revisions 73376,73393,73398,73400,73404-73405,73409,73419-73421,73432,73457,73460,73485-73486,73488-73489,73501-73502,73513-73514 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73376 | benjamin.peterson | 2009-06-11 17:29:23 -0500 (Thu, 11 Jun 2009) | 1 line remove check for case handled in sub-function ........ r73393 | alexandre.vassalotti | 2009-06-12 13:56:57 -0500 (Fri, 12 Jun 2009) | 2 lines Clear reference to the static PyExc_RecursionErrorInst in _PyExc_Fini. ........ r73398 | alexandre.vassalotti | 2009-06-12 15:57:12 -0500 (Fri, 12 Jun 2009) | 3 lines Add const qualifier to PyErr_SetFromErrnoWithFilename and to PyErr_SetFromErrnoWithUnicodeFilename. ........ r73400 | alexandre.vassalotti | 2009-06-12 16:43:47 -0500 (Fri, 12 Jun 2009) | 2 lines Delete outdated make file for building the parser with MSVC 6. ........ r73404 | benjamin.peterson | 2009-06-12 20:40:00 -0500 (Fri, 12 Jun 2009) | 1 line keep the slice.step field as NULL if no step expression is given ........ r73405 | benjamin.peterson | 2009-06-12 22:46:30 -0500 (Fri, 12 Jun 2009) | 1 line prevent import statements from assigning to None ........ r73409 | benjamin.peterson | 2009-06-13 08:06:21 -0500 (Sat, 13 Jun 2009) | 1 line allow importing from a module named None if it has an 'as' clause ........ r73419 | benjamin.peterson | 2009-06-13 11:19:19 -0500 (Sat, 13 Jun 2009) | 1 line set Print.values to NULL if there are no values ........ r73420 | benjamin.peterson | 2009-06-13 12:08:53 -0500 (Sat, 13 Jun 2009) | 1 line give a better error message when deleting () ........ r73421 | benjamin.peterson | 2009-06-13 15:23:33 -0500 (Sat, 13 Jun 2009) | 1 line when no module is given in a 'from' relative import, make ImportFrom.module NULL ........ r73432 | amaury.forgeotdarc | 2009-06-14 16:20:40 -0500 (Sun, 14 Jun 2009) | 3 lines #6227: Because of a wrong indentation, the test was not testing what it should. Ensure that the snippet in doctest_aliases actually contains aliases. ........ r73457 | benjamin.peterson | 2009-06-16 18:13:09 -0500 (Tue, 16 Jun 2009) | 1 line add underscores ........ r73460 | benjamin.peterson | 2009-06-16 22:23:04 -0500 (Tue, 16 Jun 2009) | 1 line remove unused 'encoding' member from the compiler struct ........ r73485 | benjamin.peterson | 2009-06-19 17:07:47 -0500 (Fri, 19 Jun 2009) | 1 line remove duplicate test ........ r73486 | benjamin.peterson | 2009-06-19 17:09:17 -0500 (Fri, 19 Jun 2009) | 1 line add missing assertion #6313 ........ r73488 | benjamin.peterson | 2009-06-19 17:16:28 -0500 (Fri, 19 Jun 2009) | 1 line show that this one isn't used ........ r73489 | benjamin.peterson | 2009-06-19 17:21:12 -0500 (Fri, 19 Jun 2009) | 1 line use closures ........ r73501 | benjamin.peterson | 2009-06-21 18:01:07 -0500 (Sun, 21 Jun 2009) | 1 line don't need to add the name 'lambda' as assigned ........ r73502 | benjamin.peterson | 2009-06-21 18:03:36 -0500 (Sun, 21 Jun 2009) | 1 line remove tmpname support since it's no longer used ........ r73513 | benjamin.peterson | 2009-06-22 20:18:57 -0500 (Mon, 22 Jun 2009) | 1 line fix grammar ........ r73514 | benjamin.peterson | 2009-06-22 22:01:56 -0500 (Mon, 22 Jun 2009) | 1 line remove some unused symtable constants ........ --- Objects/exceptions.c | 4 ++-- Objects/floatobject.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index adaece1ef5..0e28f0fb70 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1979,6 +1979,6 @@ _PyExc_Init(void) void _PyExc_Fini(void) { - Py_XDECREF(PyExc_MemoryErrorInst); - PyExc_MemoryErrorInst = NULL; + Py_CLEAR(PyExc_MemoryErrorInst); + Py_CLEAR(PyExc_RecursionErrorInst); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 341072eaab..20fe956f5e 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -73,7 +73,7 @@ PyFloat_GetMin(void) static PyTypeObject FloatInfoType; PyDoc_STRVAR(floatinfo__doc__, -"sys.floatinfo\n\ +"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\ @@ -100,7 +100,7 @@ static PyStructSequence_Field floatinfo_fields[] = { }; static PyStructSequence_Desc floatinfo_desc = { - "sys.floatinfo", /* name */ + "sys.float_info", /* name */ floatinfo__doc__, /* doc */ floatinfo_fields, /* fields */ 11 -- cgit v1.2.1 From 3a7e5ca839d816aa041f3ac04eb0216e9fa4bf89 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 28 Jun 2009 22:08:40 +0000 Subject: Fix description of range_length_obj --- Objects/rangeobject.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 77e1954639..6d3e8b0c93 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -126,10 +126,9 @@ range_dealloc(rangeobject *r) PyObject_Del(r); } -/* Return number of items in range (lo, hi, step), when arguments are PyLong - * objects. Return a value < 0 if & only if the true value is too large to - * fit in a signed long. Arguments MUST return 1 with PyLong_Check(). Return - * -1 when there is an error. +/* Return number of items in range (lo, hi, step) as a PyLong object, + * when arguments are PyLong objects. Arguments MUST return 1 with + * PyLong_Check(). Return NULL when there is an error. */ static PyObject* range_length_obj(rangeobject *r) -- cgit v1.2.1 From 4753a4482d69b85e0d27714f0aeeac1076c49d08 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Mon, 29 Jun 2009 22:36:49 +0000 Subject: #6373: SystemError in str.encode('latin1', 'surrogateescape') if the string contains unpaired surrogates. (In debug build, crash in assert()) This can happen with normal processing, if python starts with utf-8, then calls sys.setfilesystemencoding('latin-1') --- Objects/unicodeobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0d4a3ddd80..305289bc78 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -4201,10 +4201,12 @@ static PyObject *unicode_encode_ucs1(const Py_UNICODE *p, repsize = PyBytes_Size(repunicode); if (repsize > 1) { /* Make room for all additional bytes. */ + respos = str - PyBytes_AS_STRING(res); if (_PyBytes_Resize(&res, ressize+repsize-1)) { Py_DECREF(repunicode); goto onError; } + str = PyBytes_AS_STRING(res) + respos; ressize += repsize-1; } memcpy(str, PyBytes_AsString(repunicode), repsize); -- cgit v1.2.1 From a01f8d41c40bfba19343ce11eb9abc83cec12796 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 1 Jul 2009 01:28:55 +0000 Subject: remove PyCObject --- Objects/cobject.c | 169 ------------------------------------------------------ 1 file changed, 169 deletions(-) delete mode 100644 Objects/cobject.c (limited to 'Objects') diff --git a/Objects/cobject.c b/Objects/cobject.c deleted file mode 100644 index a69215021d..0000000000 --- a/Objects/cobject.c +++ /dev/null @@ -1,169 +0,0 @@ - -/* 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 deprecation_exception(void) -{ - return PyErr_WarnEx(PyExc_PendingDeprecationWarning, - "The CObject API is deprecated as of Python 3.1. " - "Please convert to using the Capsule API.", 1); -} - -PyObject * -PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *)) -{ - PyCObject *self; - - if (deprecation_exception()) { - 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 (deprecation_exception()) { - 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 (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_reserved*/ - 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*/ -}; -- cgit v1.2.1 From 48d54c530d19d87954cb5d70ec673e43e7410469 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 1 Jul 2009 01:31:12 +0000 Subject: remove reference to PyCObject --- Objects/object.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index a29c31a43d..6845201c23 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1720,9 +1720,6 @@ _Py_GetObjects(PyObject *self, PyObject *args) #endif -/* Hack to force loading of cobject.o */ -PyTypeObject *_Py_cobject_hack = &PyCObject_Type; - /* Hack to force loading of pycapsule.o */ PyTypeObject *_PyCapsule_hack = &PyCapsule_Type; -- cgit v1.2.1 From 1af3ca8eeb22bdbbde2cdcf6066ed80d54d6e031 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Tue, 7 Jul 2009 00:43:08 +0000 Subject: #6428: py3k requires that __bool__ return a bool (and not an int) Fix the error message and the documentation. --- Objects/typeobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 0e7954206b..60483e718c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4807,10 +4807,8 @@ slot_nb_bool(PyObject *self) } else { PyErr_Format(PyExc_TypeError, - "%s should return " - "bool or int, returned %s", - (using_len ? "__len__" - : "__bool__"), + "__bool__ should return " + "bool, returned %s", Py_TYPE(temp)->tp_name); result = -1; } -- cgit v1.2.1 From 5bd1abcc4c584a8c90c248fd591e9a13990c2071 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 18 Jul 2009 09:07:48 +0000 Subject: #6502: add missing comma in docstring. --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 65868e450d..832b4e90e3 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -179,7 +179,7 @@ validate_and_copy_tuple(PyObject *tup) } PyDoc_STRVAR(code_doc, -"code(argcount, kwonlyargcount nlocals, stacksize, flags, codestring,\n\ +"code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\ constants, names, varnames, filename, name, firstlineno,\n\ lnotab[, freevars[, cellvars]])\n\ \n\ -- cgit v1.2.1 From 32306f2c493628ed3a3b85457228909defdeb97d Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Tue, 21 Jul 2009 00:39:03 +0000 Subject: Merged revisions 73871 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r73871 | alexandre.vassalotti | 2009-07-06 22:17:30 -0400 (Mon, 06 Jul 2009) | 7 lines Grow the allocated buffer in PyUnicode_EncodeUTF7 to avoid buffer overrun. Without this change, test_unicode.UnicodeTest.test_codecs_utf7 crashes in debug mode. What happens is the unicode string u'\U000abcde' with a length of 1 encodes to the string '+2m/c3g-' of length 8. Since only 5 bytes is reserved in the buffer, a buffer overrun occurs. ........ --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 305289bc78..758d05489e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2044,7 +2044,7 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s, { PyObject *v; /* It might be possible to tighten this worst case */ - Py_ssize_t allocated = 5 * size; + Py_ssize_t allocated = 8 * size; int inShift = 0; Py_ssize_t i = 0; unsigned int base64bits = 0; @@ -2055,7 +2055,7 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s, if (size == 0) return PyBytes_FromStringAndSize(NULL, 0); - if (allocated / 5 != size) + if (allocated / 8 != size) return PyErr_NoMemory(); v = PyBytes_FromStringAndSize(NULL, allocated); -- cgit v1.2.1 From db593b8be650afd6104f8fe478e8573ee6c6264d Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Tue, 21 Jul 2009 04:30:03 +0000 Subject: Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........ --- Objects/codeobject.c | 189 ++++++++++++++--------------------------------- Objects/frameobject.c | 26 +++---- Objects/lnotab_notes.txt | 124 +++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 146 deletions(-) create mode 100644 Objects/lnotab_notes.txt (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 832b4e90e3..a772c56a5b 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -54,7 +54,7 @@ PyCode_New(int argcount, int kwonlyargcount, Py_ssize_t i; /* Check argument types */ - if (argcount < 0 || nlocals < 0 || + if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || code == NULL || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || @@ -112,6 +112,53 @@ PyCode_New(int argcount, int kwonlyargcount, 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 = PyBytes_FromString(""); + if (emptystring == NULL) + goto failed; + } + if (nulltuple == NULL) { + nulltuple = PyTuple_New(0); + if (nulltuple == NULL) + goto failed; + } + funcname_ob = PyUnicode_FromString(funcname); + if (funcname_ob == NULL) + goto failed; + filename_ob = PyUnicode_DecodeFSDefault(filename); + if (filename_ob == NULL) + goto failed; + + result = PyCode_New(0, /* argcount */ + 0, /* kwonlyargcount */ + 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) @@ -431,48 +478,8 @@ PyTypeObject PyCode_Type = { code_new, /* tp_new */ }; -/* All about c_lnotab. - -c_lnotab is an array of unsigned bytes disguised as a Python string. In -O -mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped -to source code line #s (when needed for tracebacks) via c_lnotab instead. -The array is conceptually a 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 - -The first trick is that these numbers aren't stored, only the increments -from one row to the next (this doesn't really work, but it's a start): - - 0, 1, 6, 1, 44, 5, 300, 300, 11, 1 - -The second trick is that an unsigned byte can't hold negative values, or -values larger than 255, so (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 c_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 c_lnotab: - addr += addr_incr - if addr > A: - return lineno - lineno += line_incr - -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, com_set_lineno 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. +/* 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 @@ -491,85 +498,10 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) return line; } -/* - Check whether the current instruction is at the start of a line. - - */ - - /* The theory of SET_LINENO-less tracing. - - In a nutshell, we use the co_lnotab field of the code object - to tell when execution has moved onto a different line. - - As mentioned above, the basic idea is so set things up so - that - - *instr_lb <= frame->f_lasti < *instr_ub - - is true so long as execution does not change lines. - - This is all fairly simple. Digging the information out of - co_lnotab takes some work, but is conceptually clear. - - Somewhat harder to explain is why we don't *always* call the - line trace function when the above test fails. - - Consider this code: - - 1: def f(a): - 2: if a: - 3: print 1 - 4: else: - 5: print 2 - - which compiles to this: - - 2 0 LOAD_FAST 0 (a) - 3 JUMP_IF_FALSE 9 (to 15) - 6 POP_TOP - - 3 7 LOAD_CONST 1 (1) - 10 PRINT_ITEM - 11 PRINT_NEWLINE - 12 JUMP_FORWARD 6 (to 21) - >> 15 POP_TOP - - 5 16 LOAD_CONST 2 (2) - 19 PRINT_ITEM - 20 PRINT_NEWLINE - >> 21 LOAD_CONST 0 (None) - 24 RETURN_VALUE - - If 'a' is false, execution will jump to instruction at offset - 15 and the co_lnotab will claim that execution has moved to - line 3. This is at best misleading. In this case we could - associate the POP_TOP with line 4, but that doesn't make - sense in all cases (I think). - - What we do is only call the line trace function 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. - - This also takes care of the situation where 'a' is true. - Execution will jump from instruction offset 12 to offset 21. - Then the co_lnotab would imply that execution has moved to line - 5, which is again misleading. - - Why do we set f_lineno when tracing? 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 and 3, then a "return" type event -- but - you would be shown line 5 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. - */ - - -int -PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) +/* 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; @@ -586,11 +518,9 @@ PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) instr_lb -- if we stored the matching value of p somwhere we could skip the first while loop. */ - /* see comments in compile.c for the description of + /* See lnotab_notes.txt for the description of co_lnotab. A point to remember: increments to p - should come in pairs -- although we don't care about - the line increments here, treating them as byte - increments gets confusing, to say the least. */ + come in (addr, line) pairs. */ bounds->ap_lower = 0; while (size > 0) { @@ -603,13 +533,6 @@ PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) --size; } - /* If lasti and addr don't match exactly, we don't want to - change the lineno slot on the frame or execute a trace - function. Return -1 instead. - */ - if (addr != lasti) - line = -1; - if (size > 0) { while (--size >= 0) { addr += *p++; diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 664dc2b1cd..26abd5f6ca 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -31,17 +31,19 @@ frame_getlocals(PyFrameObject *f, void *closure) return f->f_locals; } -static PyObject * -frame_getlineno(PyFrameObject *f, void *closure) +int +PyFrame_GetLineNumber(PyFrameObject *f) { - int lineno; - if (f->f_trace) - lineno = f->f_lineno; + return f->f_lineno; else - lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); + return PyCode_Addr2Line(f->f_code, f->f_lasti); +} - return PyLong_FromLong(lineno); +static PyObject * +frame_getlineno(PyFrameObject *f, void *closure) +{ + return PyLong_FromLong(PyFrame_GetLineNumber(f)); } /* Setter for f_lineno - you can set f_lineno from within a trace function in @@ -345,16 +347,14 @@ frame_gettrace(PyFrameObject *f, void *closure) static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { - /* We rely on f_lineno being accurate when f_trace is set. */ + PyObject* old_value; - PyObject* old_value = f->f_trace; + /* 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; - - if (v != NULL) - f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); - Py_XDECREF(old_value); return 0; diff --git a/Objects/lnotab_notes.txt b/Objects/lnotab_notes.txt new file mode 100644 index 0000000000..d247eddd6f --- /dev/null +++ b/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. -- cgit v1.2.1 From 091689727f507c3b2ef647bae29ff6101d64cb76 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 21 Jul 2009 14:11:27 +0000 Subject: Merged revisions 74139 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74139 | benjamin.peterson | 2009-07-21 09:08:40 -0500 (Tue, 21 Jul 2009) | 1 line must use _PyThreadState_Current so it isn't checked for NULL #6530 ........ --- Objects/dictobject.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index ce6760fdbd..907ccf2420 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -714,10 +714,12 @@ PyDict_GetItem(PyObject *op, PyObject *key) } } - /* 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... */ - tstate = PyThreadState_GET(); + /* 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, it 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; -- cgit v1.2.1 From 2bd4ba044fdba129742d6998fd818a39e09a5b8f Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Wed, 22 Jul 2009 03:56:36 +0000 Subject: Issue #6151: Make PyDescr_COMMON conform to standard C. --- Objects/descrobject.c | 30 +++++++++++++++--------------- Objects/typeobject.c | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index d6581511b9..a254339e48 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -92,7 +92,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) "descriptor '%V' for type '%s' " "needs either an object or a type", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } } @@ -101,16 +101,16 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) "descriptor '%V' for type '%s' " "needs a type, not a '%s' as arg 2", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, type->ob_type->tp_name); return NULL; } - if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { + if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for type '%s' " "doesn't apply to type '%s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, ((PyTypeObject *)type)->tp_name); return NULL; } @@ -149,7 +149,7 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } @@ -204,7 +204,7 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return -1; } @@ -222,17 +222,17 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) "descriptor '%V' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { + if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); return NULL; } @@ -257,7 +257,7 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, { PyObject *func, *result; - func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type); + func = PyCFunction_New(descr->d_method, (PyObject *)PyDescr_TYPE(descr)); if (func == NULL) return NULL; @@ -280,17 +280,17 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) "descriptor '%V' of '%.100s' " "object needs an argument", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name); + PyDescr_TYPE(descr)->tp_name); return NULL; } self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { + if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' " "requires a '%.100s' object " "but received a '%.100s'", descr_name((PyDescrObject *)descr), "?", - descr->d_type->tp_name, + PyDescr_TYPE(descr)->tp_name, self->ob_type->tp_name); return NULL; } @@ -949,7 +949,7 @@ static PyMemberDef wrapper_members[] = { static PyObject * wrapper_objclass(wrapperobject *wp) { - PyObject *c = (PyObject *)wp->descr->d_type; + PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); Py_INCREF(c); return c; @@ -1059,7 +1059,7 @@ PyWrapper_New(PyObject *d, PyObject *self) assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); descr = (PyWrapperDescrObject *)d; - assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); + assert(PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))); wp = PyObject_GC_New(wrapperobject, &wrappertype); if (wp != NULL) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 60483e718c..24866ff465 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5648,7 +5648,7 @@ update_one_slot(PyTypeObject *type, slotdef *p) generic = p->function; d = (PyWrapperDescrObject *)descr; if (d->d_base->wrapper == p->wrapper && - PyType_IsSubtype(type, d->d_type)) + PyType_IsSubtype(type, PyDescr_TYPE(d))) { if (specific == NULL || specific == d->d_wrapped) -- cgit v1.2.1 From a9804912fc6ab79083b66d20e7e6404fcccdaed8 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 22 Jul 2009 12:03:59 +0000 Subject: Merged revisions 74167 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74167 | georg.brandl | 2009-07-22 13:57:15 +0200 (Mi, 22 Jul 2009) | 1 line Issue #6540: Fixed crash for bytearray.translate() with invalid parameters. ........ --- Objects/bytearrayobject.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 165fd10477..f3d569712f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1389,15 +1389,17 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) if (vtable.len != 256) { PyErr_SetString(PyExc_ValueError, "translation table must be 256 characters long"); - goto done; + PyBuffer_Release(&vtable); + return NULL; } table = (const char*)vtable.buf; } if (delobj != NULL) { if (_getbuffer(delobj, &vdel) < 0) { - delobj = NULL; /* don't try to release vdel buffer on exit */ - goto done; + if (tableobj != NULL) + PyBuffer_Release(&vtable); + return NULL; } } else { -- cgit v1.2.1 From 3775fc57e5187f5cee0e8dc865c32b6efadada52 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 27 Jul 2009 02:10:42 +0000 Subject: Sync trunk and py3k versions of string formatting. Manual merge of r74219. --- Objects/stringlib/formatter.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index ea15c7bca8..5cead660c4 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -920,6 +920,13 @@ format_float_internal(PyObject *value, format the result. We take care of that later. */ type = 'g'; +#if PY_VERSION_HEX < 0x0301000 + /* 'F' is the same as 'f', per the PEP */ + /* This is no longer the case in 3.x */ + if (type == 'F') + type = 'f'; +#endif + val = PyFloat_AsDouble(value); if (val == -1.0 && PyErr_Occurred()) goto done; @@ -935,15 +942,8 @@ format_float_internal(PyObject *value, #if PY_VERSION_HEX < 0x03010000 /* 3.1 no longer converts large 'f' to 'g'. */ - if (fabs(val) >= 1e50) - switch (type) { - case 'f': - type = 'g'; - break; - case 'F': - type = 'G'; - break; - } + if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) + type = 'g'; #endif /* Cast "type", because if we're in unicode we need to pass a @@ -1117,6 +1117,13 @@ format_complex_internal(PyObject *value, format the result. We take care of that later. */ type = 'g'; +#if PY_VERSION_HEX < 0x03010000 + /* This is no longer the case in 3.x */ + /* 'F' is the same as 'f', per the PEP */ + if (type == 'F') + type = 'f'; +#endif + if (precision < 0) precision = default_precision; -- cgit v1.2.1 From b90e2c242137ff374fd32599965be5a01ac88fc7 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 27 Jul 2009 20:16:37 +0000 Subject: Issue 6573: Fix set.union() for cases where self is in the argument chain. --- Objects/setobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 8ecc405bc5..b296f9f329 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1187,7 +1187,7 @@ set_union(PySetObject *so, PyObject *args) for (i=0 ; i Date: Wed, 29 Jul 2009 20:12:15 +0000 Subject: Merged revisions 74075,74187,74197,74201,74216,74225 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74075 | georg.brandl | 2009-07-18 05:06:31 -0400 (Sat, 18 Jul 2009) | 1 line #6505: fix typos. ........ r74187 | benjamin.peterson | 2009-07-23 10:19:08 -0400 (Thu, 23 Jul 2009) | 1 line use bools for autoraise ........ r74197 | benjamin.peterson | 2009-07-24 22:03:48 -0400 (Fri, 24 Jul 2009) | 1 line clarify ........ r74201 | amaury.forgeotdarc | 2009-07-25 12:22:06 -0400 (Sat, 25 Jul 2009) | 2 lines Better name a variable: 'buf' seems to imply a mutable buffer. ........ r74216 | michael.foord | 2009-07-26 17:12:14 -0400 (Sun, 26 Jul 2009) | 1 line Issue 6581. Michael Foord ........ r74225 | kurt.kaiser | 2009-07-27 12:09:28 -0400 (Mon, 27 Jul 2009) | 5 lines 1. Clean workspace more thoughly before build. 2. Add url of branch we are building to 'results' webpage. (url is now available in $repo_path, could be added to failure email.) 3. Adjust permissions to improve upload reliability. ........ --- Objects/dictobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 907ccf2420..03f2010ed5 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -718,7 +718,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) 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, it complains if tstate is NULL. */ + mode, the latter complains if tstate is NULL. */ tstate = _PyThreadState_Current; if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ -- cgit v1.2.1 From 80539a5b717653fb262c39fc78d99d7dfab2b022 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 30 Jul 2009 13:43:08 +0000 Subject: Merged revisions 74269 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74269 | eric.smith | 2009-07-30 09:39:44 -0400 (Thu, 30 Jul 2009) | 1 line Issue 6330: Fix --enable-unicode=ucs4. ........ --- Objects/stringlib/formatter.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 5cead660c4..c722460472 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -32,7 +32,7 @@ unknown_presentation_type(STRINGLIB_CHAR presentation_type, PyErr_Format(PyExc_ValueError, "Unknown format code '%c' " "for object of type '%.200s'", - presentation_type, + (char)presentation_type, type_name); #if STRINGLIB_IS_UNICODE else @@ -44,6 +44,24 @@ unknown_presentation_type(STRINGLIB_CHAR presentation_type, #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 @@ -253,8 +271,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, /* These are allowed. See PEP 378.*/ break; default: - PyErr_Format(PyExc_ValueError, - "Cannot specify ',' with '%c'.", format->type); + invalid_comma_type(format->type); return 0; } } -- cgit v1.2.1 From a13daff3d4ef3b20526fc576e9a893b68f3ee348 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 4 Aug 2009 20:29:27 +0000 Subject: Slightly improve buffer-related error message. --- Objects/abstract.c | 2 +- Objects/memoryobject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 3b2de9d6c1..5247824770 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -331,7 +331,7 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { if (!PyObject_CheckBuffer(obj)) { PyErr_Format(PyExc_TypeError, - "'%100s' does not have the buffer interface", + "'%100s' does not support the buffer interface", Py_TYPE(obj)->tp_name); return -1; } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 2990c25638..7acd569d73 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -255,7 +255,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) if (!PyObject_CheckBuffer(obj)) { PyErr_SetString(PyExc_TypeError, - "object does not have the buffer interface"); + "object does not support the buffer interface"); return NULL; } -- cgit v1.2.1 From 0adb1dc01f26fe833f977458d3c8eed01e174ac7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 15 Aug 2009 13:23:05 +0000 Subject: Merged revisions 74457 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74457 | benjamin.peterson | 2009-08-15 08:16:38 -0500 (Sat, 15 Aug 2009) | 1 line #6707 fix a crash with dir() on an uninitialized module ........ --- Objects/object.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 6845201c23..e8ac8a2e46 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1265,9 +1265,11 @@ _specialized_dir_module(PyObject *obj) if (PyDict_Check(dict)) result = PyDict_Keys(dict); else { - PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ is not a dictionary", - PyModule_GetName(obj)); + const char *name = PyModule_GetName(obj); + if (name) + PyErr_Format(PyExc_TypeError, + "%.200s.__dict__ is not a dictionary", + name); } } -- cgit v1.2.1 From a68d96f71a091275206fdd9d996b050b7a601ee9 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 1 Sep 2009 07:34:27 +0000 Subject: #6814: remove traces of xrange(). --- Objects/listsort.txt | 2 +- Objects/rangeobject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 31a5445c0e..47fec1d0a1 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -606,7 +606,7 @@ from time import clock as now def fill(n): from random import random - return [random() for i in xrange(n)] + return [random() for i in range(n)] def mycmp(x, y): global ncmp diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 6d3e8b0c93..88ca698348 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -431,7 +431,7 @@ PyTypeObject PyRangeIter_Type = { rangeiter_new, /* tp_new */ }; -/* Return number of items in range/xrange (lo, hi, step). step > 0 +/* Return number of items in range (lo, hi, step). step > 0 * required. Return a value < 0 if & only if the true value is too * large to fit in a signed long. */ -- cgit v1.2.1 From 09443e6ffc7f45c819fcfbffa213b39f9131a6dc Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 6 Sep 2009 10:19:23 +0000 Subject: Merged revisions 74673 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r74673 | mark.dickinson | 2009-09-06 11:03:31 +0100 (Sun, 06 Sep 2009) | 3 lines Issue #6846: bytearray.pop was returning ints in the range [-128, 128) instead of [0, 256). Thanks Hagen Fürstenau for the report and fix. ........ --- Objects/bytearrayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index f3d569712f..f8f9469f5f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2705,7 +2705,7 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args) if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; - return PyLong_FromLong(value); + return PyLong_FromLong((unsigned char)value); } PyDoc_STRVAR(remove__doc__, -- cgit v1.2.1 From 04952954182a0299de87f3eb8d66c283c50bcde9 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 6 Sep 2009 10:34:47 +0000 Subject: Merged revisions 74677 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r74677 | mark.dickinson | 2009-09-06 11:32:21 +0100 (Sun, 06 Sep 2009) | 1 line Issue #6847: s/bytes/bytearray/ in some bytearray error messages. Thanks Hagen Fürstenau. ........ --- Objects/bytearrayobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index f8f9469f5f..835244abe7 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2552,7 +2552,7 @@ bytearray_insert(PyByteArrayObject *self, PyObject *args) if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to bytes"); + "cannot add more objects to bytearray"); return NULL; } if (!_getbytevalue(value, &ival)) @@ -2587,7 +2587,7 @@ bytearray_append(PyByteArrayObject *self, PyObject *arg) return NULL; if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, - "cannot add more objects to bytes"); + "cannot add more objects to bytearray"); return NULL; } if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) @@ -2688,7 +2688,7 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args) if (n == 0) { PyErr_SetString(PyExc_OverflowError, - "cannot pop an empty bytes"); + "cannot pop an empty bytearray"); return NULL; } if (where < 0) @@ -2726,7 +2726,7 @@ bytearray_remove(PyByteArrayObject *self, PyObject *arg) break; } if (where == n) { - PyErr_SetString(PyExc_ValueError, "value not found in bytes"); + PyErr_SetString(PyExc_ValueError, "value not found in bytearray"); return NULL; } if (!_canresize(self)) -- cgit v1.2.1 From 49b9161c77e52834f2b1951634099ffeb504a794 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 6 Sep 2009 20:53:58 +0000 Subject: Merged revisions 74689 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74689 | mark.dickinson | 2009-09-06 21:51:37 +0100 (Sun, 06 Sep 2009) | 1 line Remove redundant assignment ........ --- Objects/longobject.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index b83cdc8ed6..34850f1b5c 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1862,7 +1862,6 @@ long_from_binary_base(char **str, int base) for (bits_per_char = -1; n; ++bits_per_char) n >>= 1; /* n <- total # of bits needed, while setting p to end-of-string */ - n = 0; while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) ++p; *str = p; -- cgit v1.2.1 From 338dbacb603cb409fbd22bc0d2c6783a705422de Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 11 Sep 2009 22:24:02 +0000 Subject: Merged revisions 74277,74321,74323,74326,74355,74465,74467,74488,74492,74513,74531,74549,74553,74625,74632,74643-74644,74647,74652,74666,74671,74727,74739 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74277 | sean.reifschneider | 2009-08-01 18:54:55 -0500 (Sat, 01 Aug 2009) | 3 lines - Issue #6624: yArg_ParseTuple with "s" format when parsing argument with NUL: Bogus TypeError detail string. ........ r74321 | guilherme.polo | 2009-08-05 11:51:41 -0500 (Wed, 05 Aug 2009) | 1 line Easier reference to find (at least while svn continues being used). ........ r74323 | guilherme.polo | 2009-08-05 18:48:26 -0500 (Wed, 05 Aug 2009) | 1 line Typo. ........ r74326 | jesse.noller | 2009-08-05 21:05:56 -0500 (Wed, 05 Aug 2009) | 1 line Fix issue 4660: spurious task_done errors in multiprocessing, remove doc note for from_address ........ r74355 | gregory.p.smith | 2009-08-12 12:02:37 -0500 (Wed, 12 Aug 2009) | 2 lines comment typo fix ........ r74465 | vinay.sajip | 2009-08-15 18:23:12 -0500 (Sat, 15 Aug 2009) | 1 line Added section on logging to one file from multiple processes. ........ r74467 | vinay.sajip | 2009-08-15 18:34:47 -0500 (Sat, 15 Aug 2009) | 1 line Refined section on logging to one file from multiple processes. ........ r74488 | vinay.sajip | 2009-08-17 08:14:37 -0500 (Mon, 17 Aug 2009) | 1 line Further refined section on logging to one file from multiple processes. ........ r74492 | r.david.murray | 2009-08-17 14:26:49 -0500 (Mon, 17 Aug 2009) | 2 lines Issue 6685: 'toupper' -> 'upper' in cgi doc example explanation. ........ r74513 | skip.montanaro | 2009-08-18 09:37:52 -0500 (Tue, 18 Aug 2009) | 1 line missing module ref (issue6723) ........ r74531 | vinay.sajip | 2009-08-20 17:04:32 -0500 (Thu, 20 Aug 2009) | 1 line Added section on exceptions raised during logging. ........ r74549 | benjamin.peterson | 2009-08-24 12:42:36 -0500 (Mon, 24 Aug 2009) | 1 line fix pdf building by teaching latex the right encoding package ........ r74553 | r.david.murray | 2009-08-26 20:04:59 -0500 (Wed, 26 Aug 2009) | 2 lines Remove leftover text from end of sentence. ........ r74625 | benjamin.peterson | 2009-09-01 17:27:57 -0500 (Tue, 01 Sep 2009) | 1 line remove the check that classmethod's argument is a callable ........ r74632 | georg.brandl | 2009-09-03 02:27:26 -0500 (Thu, 03 Sep 2009) | 1 line #6828: fix wrongly highlighted blocks. ........ r74643 | georg.brandl | 2009-09-04 01:59:20 -0500 (Fri, 04 Sep 2009) | 2 lines Issue #2666: Handle BROWSER environment variable properly for unknown browser names in the webbrowser module. ........ r74644 | georg.brandl | 2009-09-04 02:55:14 -0500 (Fri, 04 Sep 2009) | 1 line #5047: remove Monterey support from configure. ........ r74647 | georg.brandl | 2009-09-04 03:17:04 -0500 (Fri, 04 Sep 2009) | 2 lines Issue #5275: In Cookie's Cookie.load(), properly handle non-string arguments as documented. ........ r74652 | georg.brandl | 2009-09-04 06:25:37 -0500 (Fri, 04 Sep 2009) | 1 line #6756: add some info about the "acct" parameter. ........ r74666 | georg.brandl | 2009-09-05 04:04:09 -0500 (Sat, 05 Sep 2009) | 1 line #6841: remove duplicated word. ........ r74671 | georg.brandl | 2009-09-05 11:47:17 -0500 (Sat, 05 Sep 2009) | 1 line #6843: add link from filterwarnings to where the meaning of the arguments is covered. ........ r74727 | benjamin.peterson | 2009-09-08 18:04:22 -0500 (Tue, 08 Sep 2009) | 1 line #6865 fix ref counting in initialization of pwd module ........ r74739 | georg.brandl | 2009-09-11 02:55:20 -0500 (Fri, 11 Sep 2009) | 1 line Move function back to its section. ........ --- Objects/classobject.c | 4 ---- Objects/funcobject.c | 6 ------ 2 files changed, 10 deletions(-) (limited to 'Objects') diff --git a/Objects/classobject.c b/Objects/classobject.c index d10ab298be..cb78d159e6 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -43,10 +43,6 @@ PyObject * PyMethod_New(PyObject *func, PyObject *self) { register PyMethodObject *im; - if (!PyCallable_Check(func)) { - PyErr_BadInternalCall(); - return NULL; - } if (self == NULL) { PyErr_BadInternalCall(); return NULL; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 1456810057..16851a942d 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -765,12 +765,6 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!_PyArg_NoKeywords("classmethod", kwds)) return -1; - if (!PyCallable_Check(callable)) { - PyErr_Format(PyExc_TypeError, "'%s' object is not callable", - callable->ob_type->tp_name); - return -1; - } - Py_INCREF(callable); cm->cm_callable = callable; return 0; -- cgit v1.2.1 From b05f266ecf6c6058f105a1fe318ef619d5c09653 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 13 Sep 2009 12:06:08 +0000 Subject: Merged revisions 74769 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74769 | mark.dickinson | 2009-09-13 12:56:13 +0100 (Sun, 13 Sep 2009) | 3 lines Fix potential signed-overflow bug in _PyLong_Format; also fix a couple of whitespace issues. ........ --- Objects/longobject.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 34850f1b5c..f84b54e8d5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1659,7 +1659,7 @@ _PyLong_Format(PyObject *aa, int base) { register PyLongObject *a = (PyLongObject *)aa; PyObject *str; - Py_ssize_t i, j, sz; + Py_ssize_t i, sz; Py_ssize_t size_a; Py_UNICODE *p; int bits; @@ -1680,13 +1680,14 @@ _PyLong_Format(PyObject *aa, int base) i >>= 1; } i = 5; - j = size_a*PyLong_SHIFT + bits-1; - sz = i + j / bits; - if (j / PyLong_SHIFT < size_a || sz < i) { + /* ensure we don't get signed overflow in sz calculation */ + if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, "int is too large to format"); return NULL; } + sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits; + assert(sz >= 0); str = PyUnicode_FromUnicode(NULL, sz); if (str == NULL) return NULL; @@ -1719,7 +1720,7 @@ _PyLong_Format(PyObject *aa, int base) accumbits -= basebits; accum >>= basebits; } while (i < size_a-1 ? accumbits >= basebits : - accum > 0); + accum > 0); } } else { @@ -1734,7 +1735,8 @@ _PyLong_Format(PyObject *aa, int base) int power = 1; for (;;) { twodigits newpow = powbase * (twodigits)base; - if (newpow >> PyLong_SHIFT) /* doesn't fit in a digit */ + if (newpow >> PyLong_SHIFT) + /* doesn't fit in a digit */ break; powbase = (digit)newpow; ++power; @@ -1805,7 +1807,8 @@ _PyLong_Format(PyObject *aa, int base) do { } while ((*q++ = *p++) != '\0'); q--; - if (PyUnicode_Resize(&str, (Py_ssize_t) (q - PyUnicode_AS_UNICODE(str)))) { + if (PyUnicode_Resize(&str,(Py_ssize_t) (q - + PyUnicode_AS_UNICODE(str)))) { Py_DECREF(str); return NULL; } -- cgit v1.2.1 From 185a67895b317e9428d27277c466eab1548c46c1 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 16 Sep 2009 21:23:34 +0000 Subject: Issue #6713: Improve performance of str(n) and repr(n) for integers n (up to 3.1 times faster in tests), by special-casing base 10 in _PyLong_Format. --- Objects/longobject.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index f84b54e8d5..3e7ae04a48 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1650,6 +1650,119 @@ divrem1(PyLongObject *a, digit n, digit *prem) return long_normalize(z); } +/* Convert a long integer to a base 10 string. Returns a new non-shared + string. (Return value is non-shared so that callers can modify the + returned value if necessary.) */ + +static PyObject * +long_to_decimal_string(PyObject *aa) +{ + PyLongObject *scratch, *a; + PyObject *str; + Py_ssize_t size, strlen, size_a, i, j; + digit *pout, *pin, rem, tenpow; + Py_UNICODE *p; + int negative; + + a = (PyLongObject *)aa; + if (a == NULL || !PyLong_Check(a)) { + PyErr_BadInternalCall(); + return NULL; + } + size_a = ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; + + /* quick and dirty upper bound for the number of digits + required to express a in base _PyLong_DECIMAL_BASE: + + #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE)) + + But log2(a) < size_a * PyLong_SHIFT, and + log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT + > 3 * _PyLong_DECIMAL_SHIFT + */ + if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { + PyErr_SetString(PyExc_OverflowError, + "long is too large to format"); + return NULL; + } + /* the expression size_a * PyLong_SHIFT is now safe from overflow */ + size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT); + scratch = _PyLong_New(size); + if (scratch == NULL) + return NULL; + + /* convert array of base _PyLong_BASE digits in pin to an array of + base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, + Volume 2 (3rd edn), section 4.4, Method 1b). */ + pin = a->ob_digit; + pout = scratch->ob_digit; + size = 0; + for (i = size_a; --i >= 0; ) { + digit hi = pin[i]; + for (j = 0; j < size; j++) { + twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; + hi = z / _PyLong_DECIMAL_BASE; + pout[j] = z - (twodigits)hi * _PyLong_DECIMAL_BASE; + } + while (hi) { + pout[size++] = hi % _PyLong_DECIMAL_BASE; + hi /= _PyLong_DECIMAL_BASE; + } + /* check for keyboard interrupt */ + SIGCHECK({ + Py_DECREF(scratch); + return NULL; + }) + } + /* pout should have at least one digit, so that the case when a = 0 + works correctly */ + if (size == 0) + pout[size++] = 0; + + /* calculate exact length of output string, and allocate */ + strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT; + tenpow = 10; + rem = pout[size-1]; + while (rem >= tenpow) { + tenpow *= 10; + strlen++; + } + str = PyUnicode_FromUnicode(NULL, strlen); + if (str == NULL) { + Py_DECREF(scratch); + return NULL; + } + + /* fill the string right-to-left */ + p = PyUnicode_AS_UNICODE(str) + strlen; + *p = '\0'; + /* pout[0] through pout[size-2] contribute exactly + _PyLong_DECIMAL_SHIFT digits each */ + for (i=0; i < size - 1; i++) { + rem = pout[i]; + for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { + *--p = '0' + rem % 10; + rem /= 10; + } + } + /* pout[size-1]: always produce at least one decimal digit */ + rem = pout[i]; + do { + *--p = '0' + rem % 10; + rem /= 10; + } while (rem != 0); + + /* and sign */ + if (negative) + *--p = '-'; + + /* check we've counted correctly */ + assert(p == PyUnicode_AS_UNICODE(str)); + Py_DECREF(scratch); + return (PyObject *)str; +} + /* Convert a long int object to a string, using a given conversion base. Return a string object. If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */ @@ -1665,6 +1778,9 @@ _PyLong_Format(PyObject *aa, int base) int bits; char sign = '\0'; + if (base == 10) + return long_to_decimal_string((PyObject *)a); + if (a == NULL || !PyLong_Check(a)) { PyErr_BadInternalCall(); return NULL; -- cgit v1.2.1 From 97dde027e497a48cd6edc973e0aea64f2239c983 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 17 Sep 2009 00:17:48 +0000 Subject: Bypass long_repr and _PyLong_Format for str(n), repr(n) --- Objects/longobject.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 3e7ae04a48..9f414ca8a9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2515,12 +2515,6 @@ long_dealloc(PyObject *v) Py_TYPE(v)->tp_free(v); } -static PyObject * -long_repr(PyObject *v) -{ - return _PyLong_Format(v, 10); -} - static int long_compare(PyLongObject *a, PyLongObject *b) { @@ -4289,13 +4283,13 @@ PyTypeObject PyLong_Type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - long_repr, /* tp_repr */ + long_to_decimal_string, /* tp_repr */ &long_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)long_hash, /* tp_hash */ 0, /* tp_call */ - long_repr, /* tp_str */ + long_to_decimal_string, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ -- cgit v1.2.1 From f4e482607d26de04ceb4059f7b4e11333607ee04 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 17 Sep 2009 19:37:28 +0000 Subject: Add some more module maintainers. --- Objects/longobject.c | 148 +++++++++++++++------------------------------------ 1 file changed, 44 insertions(+), 104 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 9f414ca8a9..814ef642b4 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1775,9 +1775,9 @@ _PyLong_Format(PyObject *aa, int base) Py_ssize_t i, sz; Py_ssize_t size_a; Py_UNICODE *p; - int bits; - char sign = '\0'; + int bits, negative; + assert(base == 2 || base == 8 || base == 10 || base == 16); if (base == 10) return long_to_decimal_string((PyObject *)a); @@ -1785,23 +1785,34 @@ _PyLong_Format(PyObject *aa, int base) PyErr_BadInternalCall(); return NULL; } - assert(base >= 2 && base <= 36); size_a = ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; /* Compute a rough upper bound for the length of the string */ - i = base; - bits = 0; - while (i > 1) { - ++bits; - i >>= 1; + switch (base) { + case 2: + bits = 1; + break; + case 8: + bits = 3; + break; + case 16: + bits = 4; + break; + default: + assert(0); /* never get here */ } + + /* length of string required: +1 for negative sign, +2 for prefix */ i = 5; /* ensure we don't get signed overflow in sz calculation */ - if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) { + if (size_a > (PY_SSIZE_T_MAX - 4) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, "int is too large to format"); return NULL; } + sz = 3 + negative + (size_a * PyLong_SHIFT - 1) / bits; + sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits; assert(sz >= 0); str = PyUnicode_FromUnicode(NULL, sz); @@ -1809,112 +1820,41 @@ _PyLong_Format(PyObject *aa, int base) return NULL; p = PyUnicode_AS_UNICODE(str) + sz; *p = '\0'; - if (Py_SIZE(a) < 0) - sign = '-'; if (Py_SIZE(a) == 0) { *--p = '0'; } - else if ((base & (base - 1)) == 0) { - /* JRH: special case for power-of-2 bases */ - twodigits accum = 0; - int accumbits = 0; /* # of bits in accum */ - int basebits = 1; /* # of bits in base-1 */ - i = base; - while ((i >>= 1) > 1) - ++basebits; - - for (i = 0; i < size_a; ++i) { - accum |= (twodigits)a->ob_digit[i] << accumbits; - accumbits += PyLong_SHIFT; - assert(accumbits >= basebits); - do { - char cdigit = (char)(accum & (base - 1)); - cdigit += (cdigit < 10) ? '0' : 'a'-10; - assert(p > PyUnicode_AS_UNICODE(str)); - *--p = cdigit; - accumbits -= basebits; - accum >>= basebits; - } while (i < size_a-1 ? accumbits >= basebits : - accum > 0); - } - } - else { - /* Not 0, and base not a power of 2. Divide repeatedly by - base, but for speed use the highest power of base that - fits in a digit. */ - Py_ssize_t size = size_a; - digit *pin = a->ob_digit; - PyLongObject *scratch; - /* powbasw <- largest power of base that fits in a digit. */ - digit powbase = base; /* powbase == base ** power */ - int power = 1; - for (;;) { - twodigits newpow = powbase * (twodigits)base; - if (newpow >> PyLong_SHIFT) - /* doesn't fit in a digit */ - break; - powbase = (digit)newpow; - ++power; - } - - /* Get a scratch area for repeated division. */ - scratch = _PyLong_New(size); - if (scratch == NULL) { - Py_DECREF(str); - return NULL; - } + assert((base & (base-1)) = 0); + /* JRH: special case for power-of-2 bases */ + twodigits accum = 0; + int accumbits = 0; /* # of bits in accum */ + int basebits = 1; /* # of bits in base-1 */ + i = base; + while ((i >>= 1) > 1) + ++basebits; - /* Repeatedly divide by powbase. */ + for (i = 0; i < size_a; ++i) { + accum |= (twodigits)a->ob_digit[i] << accumbits; + accumbits += PyLong_SHIFT; + assert(accumbits >= basebits); do { - int ntostore = power; - digit rem = inplace_divrem1(scratch->ob_digit, - pin, size, powbase); - pin = scratch->ob_digit; /* no need to use a again */ - if (pin[size - 1] == 0) - --size; - SIGCHECK({ - Py_DECREF(scratch); - Py_DECREF(str); - return NULL; - }) - - /* Break rem into digits. */ - assert(ntostore > 0); - do { - digit nextrem = (digit)(rem / base); - char c = (char)(rem - nextrem * base); - assert(p > PyUnicode_AS_UNICODE(str)); - c += (c < 10) ? '0' : 'a'-10; - *--p = c; - rem = nextrem; - --ntostore; - /* Termination is a bit delicate: must not - store leading zeroes, so must get out if - remaining quotient and rem are both 0. */ - } while (ntostore && (size || rem)); - } while (size != 0); - Py_DECREF(scratch); + char cdigit = (char)(accum & (base - 1)); + cdigit += (cdigit < 10) ? '0' : 'a'-10; + assert(p > PyUnicode_AS_UNICODE(str)); + *--p = cdigit; + accumbits -= basebits; + accum >>= basebits; + } while (i < size_a-1 ? accumbits >= basebits : + accum > 0); } - if (base == 16) { + if (base == 16) *--p = 'x'; - *--p = '0'; - } - else if (base == 8) { + else if (base == 8) *--p = 'o'; - *--p = '0'; - } - else if (base == 2) { + else /* base == 2 */ *--p = 'b'; - *--p = '0'; - } - else if (base != 10) { - *--p = '#'; - *--p = '0' + base%10; - if (base > 10) - *--p = '0' + base/10; - } + *--p = '0'; if (sign) *--p = sign; if (p != PyUnicode_AS_UNICODE(str)) { -- cgit v1.2.1 From f2a052b64257d3952e41d8375fef701a85a1693f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 17 Sep 2009 19:39:12 +0000 Subject: Revert accidental changes to Objects/longobject.c --- Objects/longobject.c | 148 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 44 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 814ef642b4..9f414ca8a9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1775,9 +1775,9 @@ _PyLong_Format(PyObject *aa, int base) Py_ssize_t i, sz; Py_ssize_t size_a; Py_UNICODE *p; - int bits, negative; + int bits; + char sign = '\0'; - assert(base == 2 || base == 8 || base == 10 || base == 16); if (base == 10) return long_to_decimal_string((PyObject *)a); @@ -1785,34 +1785,23 @@ _PyLong_Format(PyObject *aa, int base) PyErr_BadInternalCall(); return NULL; } + assert(base >= 2 && base <= 36); size_a = ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; /* Compute a rough upper bound for the length of the string */ - switch (base) { - case 2: - bits = 1; - break; - case 8: - bits = 3; - break; - case 16: - bits = 4; - break; - default: - assert(0); /* never get here */ + i = base; + bits = 0; + while (i > 1) { + ++bits; + i >>= 1; } - - /* length of string required: +1 for negative sign, +2 for prefix */ i = 5; /* ensure we don't get signed overflow in sz calculation */ - if (size_a > (PY_SSIZE_T_MAX - 4) / PyLong_SHIFT) { + if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, "int is too large to format"); return NULL; } - sz = 3 + negative + (size_a * PyLong_SHIFT - 1) / bits; - sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits; assert(sz >= 0); str = PyUnicode_FromUnicode(NULL, sz); @@ -1820,41 +1809,112 @@ _PyLong_Format(PyObject *aa, int base) return NULL; p = PyUnicode_AS_UNICODE(str) + sz; *p = '\0'; + if (Py_SIZE(a) < 0) + sign = '-'; if (Py_SIZE(a) == 0) { *--p = '0'; } - assert((base & (base-1)) = 0); - /* JRH: special case for power-of-2 bases */ - twodigits accum = 0; - int accumbits = 0; /* # of bits in accum */ - int basebits = 1; /* # of bits in base-1 */ - i = base; - while ((i >>= 1) > 1) - ++basebits; + else if ((base & (base - 1)) == 0) { + /* JRH: special case for power-of-2 bases */ + twodigits accum = 0; + int accumbits = 0; /* # of bits in accum */ + int basebits = 1; /* # of bits in base-1 */ + i = base; + while ((i >>= 1) > 1) + ++basebits; + + for (i = 0; i < size_a; ++i) { + accum |= (twodigits)a->ob_digit[i] << accumbits; + accumbits += PyLong_SHIFT; + assert(accumbits >= basebits); + do { + char cdigit = (char)(accum & (base - 1)); + cdigit += (cdigit < 10) ? '0' : 'a'-10; + assert(p > PyUnicode_AS_UNICODE(str)); + *--p = cdigit; + accumbits -= basebits; + accum >>= basebits; + } while (i < size_a-1 ? accumbits >= basebits : + accum > 0); + } + } + else { + /* Not 0, and base not a power of 2. Divide repeatedly by + base, but for speed use the highest power of base that + fits in a digit. */ + Py_ssize_t size = size_a; + digit *pin = a->ob_digit; + PyLongObject *scratch; + /* powbasw <- largest power of base that fits in a digit. */ + digit powbase = base; /* powbase == base ** power */ + int power = 1; + for (;;) { + twodigits newpow = powbase * (twodigits)base; + if (newpow >> PyLong_SHIFT) + /* doesn't fit in a digit */ + break; + powbase = (digit)newpow; + ++power; + } + + /* Get a scratch area for repeated division. */ + scratch = _PyLong_New(size); + if (scratch == NULL) { + Py_DECREF(str); + return NULL; + } - for (i = 0; i < size_a; ++i) { - accum |= (twodigits)a->ob_digit[i] << accumbits; - accumbits += PyLong_SHIFT; - assert(accumbits >= basebits); + /* Repeatedly divide by powbase. */ do { - char cdigit = (char)(accum & (base - 1)); - cdigit += (cdigit < 10) ? '0' : 'a'-10; - assert(p > PyUnicode_AS_UNICODE(str)); - *--p = cdigit; - accumbits -= basebits; - accum >>= basebits; - } while (i < size_a-1 ? accumbits >= basebits : - accum > 0); + int ntostore = power; + digit rem = inplace_divrem1(scratch->ob_digit, + pin, size, powbase); + pin = scratch->ob_digit; /* no need to use a again */ + if (pin[size - 1] == 0) + --size; + SIGCHECK({ + Py_DECREF(scratch); + Py_DECREF(str); + return NULL; + }) + + /* Break rem into digits. */ + assert(ntostore > 0); + do { + digit nextrem = (digit)(rem / base); + char c = (char)(rem - nextrem * base); + assert(p > PyUnicode_AS_UNICODE(str)); + c += (c < 10) ? '0' : 'a'-10; + *--p = c; + rem = nextrem; + --ntostore; + /* Termination is a bit delicate: must not + store leading zeroes, so must get out if + remaining quotient and rem are both 0. */ + } while (ntostore && (size || rem)); + } while (size != 0); + Py_DECREF(scratch); } - if (base == 16) + if (base == 16) { *--p = 'x'; - else if (base == 8) + *--p = '0'; + } + else if (base == 8) { *--p = 'o'; - else /* base == 2 */ + *--p = '0'; + } + else if (base == 2) { *--p = 'b'; - *--p = '0'; + *--p = '0'; + } + else if (base != 10) { + *--p = '#'; + *--p = '0' + base%10; + if (base > 10) + *--p = '0' + base/10; + } if (sign) *--p = sign; if (p != PyUnicode_AS_UNICODE(str)) { -- cgit v1.2.1 From 430d288645d7d2c1431e0b9fa07c0db628aed0e5 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 18 Sep 2009 14:53:08 +0000 Subject: Issue #6713 (continued): remove unused arbitrary-base conversion code from _PyLong_Format. --- Objects/longobject.c | 133 +++++++++++++-------------------------------------- 1 file changed, 34 insertions(+), 99 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 9f414ca8a9..e56602e947 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1763,8 +1763,8 @@ long_to_decimal_string(PyObject *aa) return (PyObject *)str; } -/* Convert a long int object to a string, using a given conversion base. - Return a string object. +/* Convert a long int object to a string, using a given conversion base, + which should be one of 2, 8, 10 or 16. Return a string object. If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */ PyObject * @@ -1774,10 +1774,10 @@ _PyLong_Format(PyObject *aa, int base) PyObject *str; Py_ssize_t i, sz; Py_ssize_t size_a; - Py_UNICODE *p; + Py_UNICODE *p, sign = '\0'; int bits; - char sign = '\0'; + assert(base == 2 || base == 8 || base == 10 || base == 16); if (base == 10) return long_to_decimal_string((PyObject *)a); @@ -1785,24 +1785,33 @@ _PyLong_Format(PyObject *aa, int base) PyErr_BadInternalCall(); return NULL; } - assert(base >= 2 && base <= 36); size_a = ABS(Py_SIZE(a)); /* Compute a rough upper bound for the length of the string */ - i = base; - bits = 0; - while (i > 1) { - ++bits; - i >>= 1; - } - i = 5; - /* ensure we don't get signed overflow in sz calculation */ - if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) { + switch (base) { + case 16: + bits = 4; + break; + case 8: + bits = 3; + break; + case 2: + bits = 1; + break; + default: + assert(0); /* shouldn't ever get here */ + bits = 0; /* to silence gcc warning */ + } + /* compute length of output string: allow 2 characters for prefix and + 1 for possible '-' sign. */ + if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, "int is too large to format"); return NULL; } - sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits; + /* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below + is safe from overflow */ + sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits; assert(sz >= 0); str = PyUnicode_FromUnicode(NULL, sz); if (str == NULL) @@ -1815,106 +1824,32 @@ _PyLong_Format(PyObject *aa, int base) if (Py_SIZE(a) == 0) { *--p = '0'; } - else if ((base & (base - 1)) == 0) { + else { /* JRH: special case for power-of-2 bases */ twodigits accum = 0; int accumbits = 0; /* # of bits in accum */ - int basebits = 1; /* # of bits in base-1 */ - i = base; - while ((i >>= 1) > 1) - ++basebits; - for (i = 0; i < size_a; ++i) { accum |= (twodigits)a->ob_digit[i] << accumbits; accumbits += PyLong_SHIFT; - assert(accumbits >= basebits); + assert(accumbits >= bits); do { - char cdigit = (char)(accum & (base - 1)); + Py_UNICODE cdigit = accum & (base - 1); cdigit += (cdigit < 10) ? '0' : 'a'-10; assert(p > PyUnicode_AS_UNICODE(str)); *--p = cdigit; - accumbits -= basebits; - accum >>= basebits; - } while (i < size_a-1 ? accumbits >= basebits : - accum > 0); - } - } - else { - /* Not 0, and base not a power of 2. Divide repeatedly by - base, but for speed use the highest power of base that - fits in a digit. */ - Py_ssize_t size = size_a; - digit *pin = a->ob_digit; - PyLongObject *scratch; - /* powbasw <- largest power of base that fits in a digit. */ - digit powbase = base; /* powbase == base ** power */ - int power = 1; - for (;;) { - twodigits newpow = powbase * (twodigits)base; - if (newpow >> PyLong_SHIFT) - /* doesn't fit in a digit */ - break; - powbase = (digit)newpow; - ++power; - } - - /* Get a scratch area for repeated division. */ - scratch = _PyLong_New(size); - if (scratch == NULL) { - Py_DECREF(str); - return NULL; + accumbits -= bits; + accum >>= bits; + } while (i < size_a-1 ? accumbits >= bits : accum > 0); } - - /* Repeatedly divide by powbase. */ - do { - int ntostore = power; - digit rem = inplace_divrem1(scratch->ob_digit, - pin, size, powbase); - pin = scratch->ob_digit; /* no need to use a again */ - if (pin[size - 1] == 0) - --size; - SIGCHECK({ - Py_DECREF(scratch); - Py_DECREF(str); - return NULL; - }) - - /* Break rem into digits. */ - assert(ntostore > 0); - do { - digit nextrem = (digit)(rem / base); - char c = (char)(rem - nextrem * base); - assert(p > PyUnicode_AS_UNICODE(str)); - c += (c < 10) ? '0' : 'a'-10; - *--p = c; - rem = nextrem; - --ntostore; - /* Termination is a bit delicate: must not - store leading zeroes, so must get out if - remaining quotient and rem are both 0. */ - } while (ntostore && (size || rem)); - } while (size != 0); - Py_DECREF(scratch); } - if (base == 16) { + if (base == 16) *--p = 'x'; - *--p = '0'; - } - else if (base == 8) { + else if (base == 8) *--p = 'o'; - *--p = '0'; - } - else if (base == 2) { + else /* (base == 2) */ *--p = 'b'; - *--p = '0'; - } - else if (base != 10) { - *--p = '#'; - *--p = '0' + base%10; - if (base > 10) - *--p = '0' + base/10; - } + *--p = '0'; if (sign) *--p = sign; if (p != PyUnicode_AS_UNICODE(str)) { -- cgit v1.2.1 From 15353151849ff5a24919d80eae1636f950346b05 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 18 Sep 2009 21:42:35 +0000 Subject: Merged revisions 74929 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r74929 | benjamin.peterson | 2009-09-18 16:14:55 -0500 (Fri, 18 Sep 2009) | 1 line add keyword arguments support to str/unicode encode and decode #6300 ........ --- Objects/bytearrayobject.c | 7 ++++--- Objects/bytesobject.c | 7 ++++--- Objects/unicodeobject.c | 9 ++++++--- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 835244abe7..c09ccde743 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2877,12 +2877,13 @@ 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) +bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) { const char *encoding = NULL; const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; - if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) return NULL; if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); @@ -3112,7 +3113,7 @@ bytearray_methods[] = { _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, decode_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__}, diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fb4a845b40..27d4f95f06 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2725,12 +2725,13 @@ as well as any other name registerd with codecs.register_error that is\n\ able to handle UnicodeDecodeErrors."); static PyObject * -bytes_decode(PyObject *self, PyObject *args) +bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) { const char *encoding = NULL; const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; - if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) return NULL; if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); @@ -2831,7 +2832,7 @@ bytes_methods[] = { _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode__doc__}, + {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 758d05489e..78ef7e1c6e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7141,13 +7141,15 @@ a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\ codecs.register_error that can handle UnicodeEncodeErrors."); static PyObject * -unicode_encode(PyUnicodeObject *self, PyObject *args) +unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode", + kwlist, &encoding, &errors)) return NULL; v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); if (v == NULL) @@ -8804,7 +8806,7 @@ static PyMethodDef unicode_methods[] = { /* Order is according to common usage: often used methods should appear first, since lookup is done sequentially. */ - {"encode", (PyCFunction) unicode_encode, METH_VARARGS, encode__doc__}, + {"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__}, @@ -8820,6 +8822,7 @@ static PyMethodDef unicode_methods[] = { {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__}, {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__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__}, -- cgit v1.2.1 From fe74d32519eba07600174bdcdcc55c5d66317323 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 18 Sep 2009 21:49:06 +0000 Subject: kill merged line --- Objects/unicodeobject.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 78ef7e1c6e..767bed0776 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8822,7 +8822,6 @@ static PyMethodDef unicode_methods[] = { {"ljust", (PyCFunction) unicode_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction) unicode_lower, METH_NOARGS, lower__doc__}, {"lstrip", (PyCFunction) unicode_lstrip, METH_VARARGS, lstrip__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__}, -- cgit v1.2.1 From bfa214ae5944ab111158b18f3ab81e66cca7bc69 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 21 Sep 2009 16:18:27 +0000 Subject: Merged revisions 75003 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75003 | mark.dickinson | 2009-09-21 17:16:44 +0100 (Mon, 21 Sep 2009) | 1 line Silence MSVC compiler warnings. ........ --- Objects/longobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index e56602e947..f7df699c9f 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1702,8 +1702,9 @@ long_to_decimal_string(PyObject *aa) digit hi = pin[i]; for (j = 0; j < size; j++) { twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; - hi = z / _PyLong_DECIMAL_BASE; - pout[j] = z - (twodigits)hi * _PyLong_DECIMAL_BASE; + hi = (digit)(z / _PyLong_DECIMAL_BASE); + pout[j] = (digit)(z - (twodigits)hi * + _PyLong_DECIMAL_BASE); } while (hi) { pout[size++] = hi % _PyLong_DECIMAL_BASE; -- cgit v1.2.1 From b093c33681b06530581adf64ee5904caac73b215 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 22 Sep 2009 21:47:24 +0000 Subject: Issue #1766304: Optimize membership testing for ranges: 'n in range(...)' does an O(1) check, if n is an integer. Non-integers aren't affected. Thanks Robert Lehmann. --- Objects/rangeobject.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 88ca698348..213f3dd382 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -273,12 +273,69 @@ range_reduce(rangeobject *r, PyObject *args) r->start, r->stop, r->step); } +static int +range_contains(rangeobject *r, PyObject *ob) { + if (PyLong_Check(ob)) { + int cmp1, cmp2, cmp3; + PyObject *tmp1 = NULL; + PyObject *tmp2 = NULL; + PyObject *zero = NULL; + int result = -1; + + zero = PyLong_FromLong(0); + if (zero == NULL) /* MemoryError in int(0) */ + goto end; + + /* Check if the value can possibly be in the range. */ + + cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT); + if (cmp1 == -1) + goto end; + if (cmp1 == 1) { /* positive steps: start <= ob < stop */ + cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE); + cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT); + } + else { /* negative steps: stop < ob <= start */ + cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE); + cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT); + } + + if (cmp2 == -1 || cmp3 == -1) /* TypeError */ + goto end; + if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */ + result = 0; + goto end; + } + + /* Check that the stride does not invalidate ob's membership. */ + tmp1 = PyNumber_Subtract(ob, r->start); + if (tmp1 == NULL) + goto end; + tmp2 = PyNumber_Remainder(tmp1, r->step); + if (tmp2 == NULL) + goto end; + /* result = (int(ob) - start % step) == 0 */ + result = PyObject_RichCompareBool(tmp2, zero, Py_EQ); + end: + Py_XDECREF(tmp1); + Py_XDECREF(tmp2); + Py_XDECREF(zero); + return result; + } + /* Fall back to iterative search. */ + return (int)_PySequence_IterSearch((PyObject*)r, ob, + PY_ITERSEARCH_CONTAINS); +} + static PySequenceMethods range_as_sequence = { (lenfunc)range_length, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ (ssizeargfunc)range_item, /* sq_item */ 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)range_contains, /* sq_contains */ }; static PyObject * range_iter(PyObject *seq); -- cgit v1.2.1 From cccfacce15cb7c2119289bc0a4fdb2d239e800a2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 24 Sep 2009 18:31:17 +0000 Subject: Silence compiler warning --- Objects/longobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index f7df699c9f..abddbc43f2 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1834,7 +1834,8 @@ _PyLong_Format(PyObject *aa, int base) accumbits += PyLong_SHIFT; assert(accumbits >= bits); do { - Py_UNICODE cdigit = accum & (base - 1); + Py_UNICODE cdigit; + cdigit = (Py_UNICODE)(accum & (base - 1)); cdigit += (cdigit < 10) ? '0' : 'a'-10; assert(p > PyUnicode_AS_UNICODE(str)); *--p = cdigit; -- cgit v1.2.1 From fcb5484facf913e9033f40b89396f53b6823adb2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 24 Sep 2009 20:04:23 +0000 Subject: Issue #1766304: The range.__contains__ optimization should only be applied to ints, not to instances of subclasses of int. --- Objects/rangeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 213f3dd382..beff030eba 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -275,7 +275,7 @@ range_reduce(rangeobject *r, PyObject *args) static int range_contains(rangeobject *r, PyObject *ob) { - if (PyLong_Check(ob)) { + if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { int cmp1, cmp2, cmp3; PyObject *tmp1 = NULL; PyObject *tmp2 = NULL; -- cgit v1.2.1 From effdcf1c548f18b743c18bb51652f068a8d4ab58 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Fri, 25 Sep 2009 16:12:33 +0000 Subject: Merged revisions 75055 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75055 | ezio.melotti | 2009-09-25 19:07:55 +0300 (Fri, 25 Sep 2009) | 1 line #6994: fix typo in enumerate docstring ........ --- Objects/enumobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 62e55bb88a..3d9bfada9e 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -161,7 +161,7 @@ enum_next(enumobject *en) PyDoc_STRVAR(enum_doc, "enumerate(iterable) -> iterator for index, value of iterable\n" "\n" -"Return an enumerate object. iterable must be an other object that supports\n" +"Return an enumerate object. iterable must be another object that supports\n" "iteration. The enumerate object yields pairs containing a count (from\n" "zero) and a value yielded by the iterable argument. enumerate is useful\n" "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."); -- cgit v1.2.1 From 6d9f6affb6f42a1962c806f314bdb656f0f61d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Mon, 28 Sep 2009 13:45:02 +0000 Subject: http://bugs.python.org/issue6836 Merging revisions 75103,75104 from trunk to py3k --- Objects/obmalloc.c | 104 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 17 deletions(-) (limited to 'Objects') diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index d1586c29f8..b2c053f2f4 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1241,6 +1241,10 @@ PyObject_Free(void *p) #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 @@ -1331,8 +1335,49 @@ p[2*S+n+S: 2*S+n+2*S] 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(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 */ @@ -1348,12 +1393,15 @@ _PyObject_DebugMalloc(size_t nbytes) if (p == NULL) return NULL; + /* at p, write size (SST bytes), id (1 byte), pad (SST-1 bytes) */ write_size_t(p, nbytes); - memset(p + SST, FORBIDDENBYTE, SST); + 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); @@ -1362,27 +1410,28 @@ _PyObject_DebugMalloc(size_t nbytes) } /* The debug free first checks the 2*SST bytes on each end for sanity (in - particular, that the FORBIDDENBYTEs are still intact). + 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_DebugFree(void *p) +_PyObject_DebugFreeApi(char api, void *p) { uchar *q = (uchar *)p - 2*SST; /* address returned from malloc */ size_t nbytes; if (p == NULL) return; - _PyObject_DebugCheckAddress(p); + _PyObject_DebugCheckAddressApi(api, p); nbytes = read_size_t(q); + nbytes += 4*SST; if (nbytes > 0) memset(q, DEADBYTE, nbytes); PyObject_Free(q); } void * -_PyObject_DebugRealloc(void *p, size_t nbytes) +_PyObject_DebugReallocApi(char api, void *p, size_t nbytes) { uchar *q = (uchar *)p; uchar *tail; @@ -1391,9 +1440,9 @@ _PyObject_DebugRealloc(void *p, size_t nbytes) int i; if (p == NULL) - return _PyObject_DebugMalloc(nbytes); + return _PyObject_DebugMallocApi(api, nbytes); - _PyObject_DebugCheckAddress(p); + _PyObject_DebugCheckAddressApi(api, p); bumpserialno(); original_nbytes = read_size_t(q - 2*SST); total = nbytes + 4*SST; @@ -1403,16 +1452,20 @@ _PyObject_DebugRealloc(void *p, size_t nbytes) if (nbytes < original_nbytes) { /* shrinking: mark old extra memory dead */ - memset(q + nbytes, DEADBYTE, original_nbytes - nbytes); + memset(q + nbytes, DEADBYTE, original_nbytes - nbytes + 2*SST); } - /* Resize and add decorations. */ + /* 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); - for (i = 0; i < SST; ++i) + assert(q[SST] == (uchar)api); + for (i = 1; i < SST; ++i) assert(q[SST + i] == FORBIDDENBYTE); q += 2*SST; tail = q + nbytes; @@ -1431,26 +1484,38 @@ _PyObject_DebugRealloc(void *p, size_t nbytes) /* 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_DebugCheckAddress(const void *p) +_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; i >= 1; --i) { + for (i = SST-1; i >= 1; --i) { if (*(q-i) != FORBIDDENBYTE) { msg = "bad leading pad byte"; goto error; @@ -1482,19 +1547,24 @@ _PyObject_DebugDumpAddress(const void *p) size_t nbytes, serial; int i; int ok; + char id; - fprintf(stderr, "Debug memory block at address p=%p:\n", p); - if (p == NULL) + 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, SST); + fprintf(stderr, " The %d pad bytes at p-%d are ", SST-1, SST-1); ok = 1; - for (i = 1; i <= SST; ++i) { + for (i = 1; i <= SST-1; ++i) { if (*(q-i) != FORBIDDENBYTE) { ok = 0; break; @@ -1505,7 +1575,7 @@ _PyObject_DebugDumpAddress(const void *p) else { fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", FORBIDDENBYTE); - for (i = SST; i >= 1; --i) { + for (i = SST-1; i >= 1; --i) { const uchar byte = *(q-i); fprintf(stderr, " at p-%d: 0x%02x", i, byte); if (byte != FORBIDDENBYTE) -- cgit v1.2.1 From 473713eba946dab7c383ddd29cfd43eb79c25d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Mon, 28 Sep 2009 15:57:53 +0000 Subject: merging revision 75106 from trunk: http://bugs.python.org/issue6836 A missing 'const' wasn't detected by Visual Studio. --- Objects/obmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index b2c053f2f4..9cf90c418e 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1369,7 +1369,7 @@ _PyObject_DebugFree(void *p) _PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p); } void -_PyObject_DebugCheckAddress(void *p) +_PyObject_DebugCheckAddress(const void *p) { _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p); } -- cgit v1.2.1 From 0da72b9a81d7e1abf1e8ada1461017c764d491f6 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 28 Sep 2009 17:54:52 +0000 Subject: Merged revisions 75110 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75110 | mark.dickinson | 2009-09-28 17:52:40 +0100 (Mon, 28 Sep 2009) | 9 lines Style/consistency/nano-optimization nit: replace occurrences of (high_bits << PyLong_SHIFT) + low_bits with (high_bits << PyLong_SHIFT) | low_bits in Objects/longobject.c. Motivation: - shouldn't unnecessarily mix bit ops with arithmetic ops (style) - this pattern should be spelt the same way thoughout (consistency) - it's very very very slightly faster: no need to worry about carries to the high digit (nano-optimization). ........ --- Objects/longobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index abddbc43f2..ade812ab0e 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -389,7 +389,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = Py_SIZE(v) > 0 ? 1 : -1; goto exit; @@ -459,7 +459,7 @@ PyLong_AsSsize_t(PyObject *vv) { } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) goto overflow; } @@ -508,7 +508,7 @@ PyLong_AsUnsignedLong(PyObject *vv) } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "python int too large to convert to C unsigned long"); @@ -546,7 +546,7 @@ PyLong_AsSize_t(PyObject *vv) } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C size_t"); @@ -584,7 +584,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) i = -i; } while (--i >= 0) { - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; } return x * sign; } @@ -1451,7 +1451,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) i = -i; } while (--i >= 0) { - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; } return x * sign; } @@ -1625,7 +1625,7 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) pout += size; while (--size >= 0) { digit hi; - rem = (rem << PyLong_SHIFT) + *--pin; + rem = (rem << PyLong_SHIFT) | *--pin; *--pout = hi = (digit)(rem / n); rem -= (twodigits)hi * n; } -- cgit v1.2.1 From d8fae2b929430d03f9f8b6afb712ea4d7144b05a Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 3 Oct 2009 20:13:37 +0000 Subject: Use size_t instead of int for a PyMem_MALLOC argument; silences a gcc 'comparison always false' warning. --- Objects/capsule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/capsule.c b/Objects/capsule.c index 3d2d626ade..e25af6c2aa 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -197,7 +197,7 @@ PyCapsule_Import(const char *name, int no_block) PyObject *object = NULL; void *return_value = NULL; char *trace; - int name_length = (strlen(name) + 1) * sizeof(char); + size_t name_length = (strlen(name) + 1) * sizeof(char); char *name_dup = (char *)PyMem_MALLOC(name_length); if (!name_dup) { -- cgit v1.2.1 From 5b318d5bd4221966c613b3cb1b6ec71977c46c02 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Tue, 6 Oct 2009 21:03:20 +0000 Subject: Merged revisions 75272-75273 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75272 | amaury.forgeotdarc | 2009-10-06 21:56:32 +0200 (mar., 06 oct. 2009) | 5 lines #1571184: makeunicodedata.py now generates the functions _PyUnicode_ToNumeric, _PyUnicode_IsLinebreak and _PyUnicode_IsWhitespace. It now also parses the Unihan.txt for numeric values. ........ r75273 | amaury.forgeotdarc | 2009-10-06 22:02:09 +0200 (mar., 06 oct. 2009) | 2 lines Add Anders Chrigstrom to Misc/ACKS for his work on unicodedata. ........ --- Objects/unicodectype.c | 585 +------ Objects/unicodetype_db.h | 4131 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 2918 insertions(+), 1798 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index 8c710e05b7..1849831e84 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -23,6 +23,7 @@ #define XID_CONTINUE_MASK 0x200 #define PRINTABLE_MASK 0x400 #define NODELTA_MASK 0x800 +#define NUMERIC_MASK 0x1000 typedef struct { const Py_UNICODE upper; @@ -53,26 +54,6 @@ gettyperecord(Py_UNICODE code) return &_PyUnicode_TypeRecords[index]; } -/* Returns 1 for Unicode characters having the category 'Zl', 'Zp' or - type 'B', 0 otherwise. */ - -int _PyUnicode_IsLinebreak(register const Py_UNICODE ch) -{ - switch (ch) { - case 0x000A: /* LINE FEED */ - case 0x000D: /* CARRIAGE RETURN */ - case 0x001C: /* FILE SEPARATOR */ - case 0x001D: /* GROUP SEPARATOR */ - case 0x001E: /* RECORD SEPARATOR */ - case 0x0085: /* NEXT LINE */ - case 0x2028: /* LINE SEPARATOR */ - case 0x2029: /* PARAGRAPH SEPARATOR */ - return 1; - default: - return 0; - } -} - /* Returns the titlecase Unicode characters corresponding to ch or just ch if no titlecase mapping is known. */ @@ -157,522 +138,11 @@ int _PyUnicode_IsDigit(Py_UNICODE ch) /* Returns the numeric value as double for Unicode characters having this property, -1.0 otherwise. */ -/* TODO: replace with unicodetype_db.h table */ - -double _PyUnicode_ToNumeric(Py_UNICODE ch) -{ - switch (ch) { - case 0x0F33: - return (double) -1 / 2; - case 0x17F0: - case 0x3007: -#ifdef Py_UNICODE_WIDE - case 0x1018A: -#endif - return (double) 0; - case 0x09F4: - case 0x17F1: - case 0x215F: - case 0x2160: - case 0x2170: - case 0x3021: - case 0x3192: - case 0x3220: - case 0x3280: -#ifdef Py_UNICODE_WIDE - case 0x10107: - case 0x10142: - case 0x10158: - case 0x10159: - case 0x1015A: - case 0x10320: - case 0x103D1: -#endif - return (double) 1; - case 0x00BD: - case 0x0F2A: - case 0x2CFD: -#ifdef Py_UNICODE_WIDE - case 0x10141: - case 0x10175: - case 0x10176: -#endif - return (double) 1 / 2; - case 0x2153: - return (double) 1 / 3; - case 0x00BC: -#ifdef Py_UNICODE_WIDE - case 0x10140: -#endif - return (double) 1 / 4; - case 0x2155: - return (double) 1 / 5; - case 0x2159: - return (double) 1 / 6; - case 0x215B: - return (double) 1 / 8; - case 0x0BF0: - 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: -#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 0x10A44: -#endif - return (double) 10; - case 0x0BF1: - case 0x137B: - case 0x216D: - case 0x217D: -#ifdef Py_UNICODE_WIDE - case 0x10119: - case 0x1014B: - case 0x10152: - case 0x1016A: - case 0x103D5: - case 0x10A46: -#endif - return (double) 100; - case 0x0BF2: - case 0x216F: - case 0x217F: - case 0x2180: -#ifdef Py_UNICODE_WIDE - case 0x10122: - case 0x1014D: - case 0x10154: - case 0x10171: - case 0x10A47: -#endif - return (double) 1000; - case 0x137C: - case 0x2182: -#ifdef Py_UNICODE_WIDE - case 0x1012B: - case 0x10155: -#endif - return (double) 10000; - case 0x216A: - case 0x217A: - case 0x246A: - case 0x247E: - case 0x2492: - case 0x24EB: - return (double) 11; - case 0x0F2F: - return (double) 11 / 2; - case 0x216B: - case 0x217B: - case 0x246B: - case 0x247F: - case 0x2493: - case 0x24EC: - return (double) 12; - case 0x246C: - case 0x2480: - case 0x2494: - case 0x24ED: - return (double) 13; - case 0x0F30: - return (double) 13 / 2; - case 0x246D: - case 0x2481: - case 0x2495: - case 0x24EE: - return (double) 14; - case 0x246E: - case 0x2482: - case 0x2496: - case 0x24EF: - return (double) 15; - case 0x0F31: - return (double) 15 / 2; - case 0x09F9: - case 0x246F: - case 0x2483: - case 0x2497: - case 0x24F0: - return (double) 16; - case 0x16EE: - case 0x2470: - case 0x2484: - case 0x2498: - case 0x24F1: - return (double) 17; - case 0x0F32: - return (double) 17 / 2; - case 0x16EF: - case 0x2471: - case 0x2485: - case 0x2499: - case 0x24F2: - return (double) 18; - case 0x16F0: - case 0x2472: - case 0x2486: - case 0x249A: - case 0x24F3: - return (double) 19; - case 0x09F5: - case 0x17F2: - case 0x2161: - case 0x2171: - case 0x3022: - case 0x3193: - case 0x3221: - case 0x3281: -#ifdef Py_UNICODE_WIDE - case 0x10108: - case 0x1015B: - case 0x1015C: - case 0x1015D: - case 0x1015E: - case 0x103D2: -#endif - return (double) 2; - case 0x2154: -#ifdef Py_UNICODE_WIDE - case 0x10177: -#endif - return (double) 2 / 3; - case 0x2156: - return (double) 2 / 5; - case 0x1373: - case 0x2473: - case 0x2487: - case 0x249B: - case 0x24F4: - case 0x3039: -#ifdef Py_UNICODE_WIDE - case 0x10111: - case 0x103D4: - case 0x10A45: -#endif - return (double) 20; -#ifdef Py_UNICODE_WIDE - case 0x1011A: - return (double) 200; - case 0x10123: - return (double) 2000; - case 0x1012C: - return (double) 20000; -#endif - case 0x3251: - return (double) 21; - case 0x3252: - return (double) 22; - case 0x3253: - return (double) 23; - case 0x3254: - return (double) 24; - case 0x3255: - return (double) 25; - case 0x3256: - return (double) 26; - case 0x3257: - return (double) 27; - case 0x3258: - return (double) 28; - case 0x3259: - return (double) 29; - case 0x09F6: - case 0x17F3: - case 0x2162: - case 0x2172: - case 0x3023: - case 0x3194: - case 0x3222: - case 0x3282: -#ifdef Py_UNICODE_WIDE - case 0x10109: -#endif - return (double) 3; - case 0x0F2B: - return (double) 3 / 2; - case 0x00BE: -#ifdef Py_UNICODE_WIDE - case 0x10178: -#endif - return (double) 3 / 4; - case 0x2157: - return (double) 3 / 5; - case 0x215C: - return (double) 3 / 8; - case 0x1374: - case 0x303A: - case 0x325A: -#ifdef Py_UNICODE_WIDE - case 0x10112: - case 0x10165: -#endif - return (double) 30; -#ifdef Py_UNICODE_WIDE - case 0x1011B: - case 0x1016B: - return (double) 300; - case 0x10124: - return (double) 3000; - case 0x1012D: - return (double) 30000; -#endif - case 0x325B: - return (double) 31; - case 0x325C: - return (double) 32; - case 0x325D: - return (double) 33; - case 0x325E: - return (double) 34; - case 0x325F: - return (double) 35; - case 0x32B1: - return (double) 36; - case 0x32B2: - return (double) 37; - case 0x32B3: - return (double) 38; - case 0x32B4: - return (double) 39; - case 0x09F7: - case 0x17F4: - case 0x2163: - case 0x2173: - case 0x3024: - case 0x3195: - case 0x3223: - case 0x3283: -#ifdef Py_UNICODE_WIDE - case 0x1010A: -#endif - return (double) 4; - case 0x2158: - return (double) 4 / 5; - case 0x1375: - case 0x32B5: -#ifdef Py_UNICODE_WIDE - case 0x10113: -#endif - return (double) 40; -#ifdef Py_UNICODE_WIDE - case 0x1011C: - return (double) 400; - case 0x10125: - return (double) 4000; - case 0x1012E: - return (double) 40000; -#endif - case 0x32B6: - return (double) 41; - case 0x32B7: - return (double) 42; - case 0x32B8: - return (double) 43; - case 0x32B9: - return (double) 44; - case 0x32BA: - return (double) 45; - case 0x32BB: - return (double) 46; - case 0x32BC: - return (double) 47; - case 0x32BD: - return (double) 48; - case 0x32BE: - return (double) 49; - case 0x17F5: - case 0x2164: - case 0x2174: - case 0x3025: - case 0x3224: - case 0x3284: -#ifdef Py_UNICODE_WIDE - case 0x1010B: - case 0x10143: - case 0x10148: - case 0x1014F: - case 0x1015F: - case 0x10173: - case 0x10321: -#endif - return (double) 5; - case 0x0F2C: - return (double) 5 / 2; - case 0x215A: - return (double) 5 / 6; - case 0x215D: - return (double) 5 / 8; - case 0x1376: - case 0x216C: - case 0x217C: - 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: -#endif - return (double) 50; - 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: -#endif - return (double) 500; - case 0x2181: -#ifdef Py_UNICODE_WIDE - case 0x10126: - case 0x10146: - case 0x1014E: - case 0x10172: -#endif - return (double) 5000; -#ifdef Py_UNICODE_WIDE - case 0x1012F: - case 0x10147: - case 0x10156: - return (double) 50000; -#endif - case 0x17F6: - case 0x2165: - case 0x2175: - case 0x3026: - case 0x3225: - case 0x3285: -#ifdef Py_UNICODE_WIDE - case 0x1010C: -#endif - return (double) 6; - case 0x1377: -#ifdef Py_UNICODE_WIDE - case 0x10115: -#endif - return (double) 60; -#ifdef Py_UNICODE_WIDE - case 0x1011E: - return (double) 600; - case 0x10127: - return (double) 6000; - case 0x10130: - return (double) 60000; -#endif - case 0x17F7: - case 0x2166: - case 0x2176: - case 0x3027: - case 0x3226: - case 0x3286: -#ifdef Py_UNICODE_WIDE - case 0x1010D: -#endif - return (double) 7; - case 0x0F2D: - return (double) 7 / 2; - case 0x215E: - return (double) 7 / 8; - case 0x1378: -#ifdef Py_UNICODE_WIDE - case 0x10116: -#endif - return (double) 70; -#ifdef Py_UNICODE_WIDE - case 0x1011F: - return (double) 700; - case 0x10128: - return (double) 7000; - case 0x10131: - return (double) 70000; -#endif - case 0x17F8: - case 0x2167: - case 0x2177: - case 0x3028: - case 0x3227: - case 0x3287: -#ifdef Py_UNICODE_WIDE - case 0x1010E: -#endif - return (double) 8; - case 0x1379: -#ifdef Py_UNICODE_WIDE - case 0x10117: -#endif - return (double) 80; -#ifdef Py_UNICODE_WIDE - case 0x10120: - return (double) 800; - case 0x10129: - return (double) 8000; - case 0x10132: - return (double) 80000; -#endif - case 0x17F9: - case 0x2168: - case 0x2178: - case 0x3029: - case 0x3228: - case 0x3288: -#ifdef Py_UNICODE_WIDE - case 0x1010F: -#endif - return (double) 9; - case 0x0F2E: - return (double) 9 / 2; - case 0x137A: -#ifdef Py_UNICODE_WIDE - case 0x10118: -#endif - return (double) 90; -#ifdef Py_UNICODE_WIDE - case 0x10121: - case 0x1034A: - return (double) 900; - case 0x1012A: - return (double) 9000; - case 0x10133: - return (double) 90000; -#endif - default: - return (double) _PyUnicode_ToDigit(ch); - } -} - int _PyUnicode_IsNumeric(Py_UNICODE ch) { - return _PyUnicode_ToNumeric(ch) != -1.0; + const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); + + return (ctype->flags & NUMERIC_MASK) != 0; } /* Returns 1 for Unicode characters to be hex-escaped when repr()ed, @@ -697,48 +167,6 @@ int _PyUnicode_IsPrintable(Py_UNICODE ch) #ifndef WANT_WCTYPE_FUNCTIONS -/* 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) -{ - switch (ch) { - case 0x0009: /* HORIZONTAL TABULATION */ - case 0x000A: /* LINE FEED */ - case 0x000B: /* VERTICAL TABULATION */ - case 0x000C: /* FORM FEED */ - case 0x000D: /* CARRIAGE RETURN */ - case 0x001C: /* FILE SEPARATOR */ - case 0x001D: /* GROUP SEPARATOR */ - case 0x001E: /* RECORD SEPARATOR */ - case 0x001F: /* UNIT SEPARATOR */ - case 0x0020: /* SPACE */ - case 0x0085: /* NEXT LINE */ - case 0x00A0: /* NO-BREAK SPACE */ - case 0x1680: /* OGHAM SPACE MARK */ - case 0x2000: /* EN QUAD */ - case 0x2001: /* EM QUAD */ - case 0x2002: /* EN SPACE */ - case 0x2003: /* EM SPACE */ - case 0x2004: /* THREE-PER-EM SPACE */ - case 0x2005: /* FOUR-PER-EM SPACE */ - case 0x2006: /* SIX-PER-EM SPACE */ - case 0x2007: /* FIGURE SPACE */ - case 0x2008: /* PUNCTUATION SPACE */ - case 0x2009: /* THIN SPACE */ - case 0x200A: /* HAIR SPACE */ - case 0x200B: /* ZERO WIDTH SPACE */ - case 0x2028: /* LINE SEPARATOR */ - case 0x2029: /* PARAGRAPH SEPARATOR */ - case 0x202F: /* NARROW NO-BREAK SPACE */ - case 0x205F: /* MEDIUM MATHEMATICAL SPACE */ - case 0x3000: /* IDEOGRAPHIC SPACE */ - return 1; - default: - return 0; - } -} - /* Returns 1 for Unicode characters having the category 'Ll', 0 otherwise. */ @@ -802,11 +230,6 @@ int _PyUnicode_IsAlpha(Py_UNICODE ch) /* Export the interfaces using the wchar_t type for portability reasons: */ -int _PyUnicode_IsWhitespace(Py_UNICODE ch) -{ - return iswspace(ch); -} - int _PyUnicode_IsLowercase(Py_UNICODE ch) { return iswlower(ch); diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index f46f1fb647..e2c68e736f 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -8,24 +8,25 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 0, 0, 0, 0, 48}, {0, 0, 0, 0, 0, 1056}, {0, 0, 0, 0, 0, 1024}, - {0, 0, 0, 0, 0, 1542}, - {0, 0, 0, 1, 1, 1542}, - {0, 0, 0, 2, 2, 1542}, - {0, 0, 0, 3, 3, 1542}, - {0, 0, 0, 4, 4, 1542}, - {0, 0, 0, 5, 5, 1542}, - {0, 0, 0, 6, 6, 1542}, - {0, 0, 0, 7, 7, 1542}, - {0, 0, 0, 8, 8, 1542}, - {0, 0, 0, 9, 9, 1542}, + {0, 0, 0, 0, 0, 5638}, + {0, 0, 0, 1, 1, 5638}, + {0, 0, 0, 2, 2, 5638}, + {0, 0, 0, 3, 3, 5638}, + {0, 0, 0, 4, 4, 5638}, + {0, 0, 0, 5, 5, 5638}, + {0, 0, 0, 6, 6, 5638}, + {0, 0, 0, 7, 7, 5638}, + {0, 0, 0, 8, 8, 5638}, + {0, 0, 0, 9, 9, 5638}, {0, 32, 0, 0, 0, 1921}, {0, 0, 0, 0, 0, 1536}, {65504, 0, 65504, 0, 0, 1801}, {0, 0, 0, 0, 0, 1801}, - {0, 0, 0, 0, 2, 1028}, - {0, 0, 0, 0, 3, 1028}, + {0, 0, 0, 0, 2, 5124}, + {0, 0, 0, 0, 3, 5124}, {743, 0, 743, 0, 0, 1801}, - {0, 0, 0, 0, 1, 1028}, + {0, 0, 0, 0, 1, 5124}, + {0, 0, 0, 0, 0, 5120}, {121, 0, 121, 0, 0, 1801}, {0, 1, 0, 0, 0, 1921}, {65535, 0, 65535, 0, 0, 1801}, @@ -117,16 +118,16 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {65488, 0, 65488, 0, 0, 1801}, {0, 0, 0, 0, 0, 1537}, {0, 7264, 0, 0, 0, 1921}, - {0, 0, 0, 0, 1, 1540}, - {0, 0, 0, 0, 2, 1540}, - {0, 0, 0, 0, 3, 1540}, - {0, 0, 0, 0, 4, 1540}, - {0, 0, 0, 0, 5, 1540}, - {0, 0, 0, 0, 6, 1540}, - {0, 0, 0, 0, 7, 1540}, - {0, 0, 0, 0, 8, 1540}, - {0, 0, 0, 0, 9, 1540}, - {0, 0, 0, 0, 0, 1792}, + {0, 0, 0, 0, 1, 5636}, + {0, 0, 0, 0, 2, 5636}, + {0, 0, 0, 0, 3, 5636}, + {0, 0, 0, 0, 4, 5636}, + {0, 0, 0, 0, 5, 5636}, + {0, 0, 0, 0, 6, 5636}, + {0, 0, 0, 0, 7, 5636}, + {0, 0, 0, 0, 8, 5636}, + {0, 0, 0, 0, 9, 5636}, + {0, 0, 0, 0, 0, 5888}, {42877, 7545, 42877, 0, 0, 3849}, {3814, 0, 3814, 0, 0, 1801}, {65477, 0, 65477, 0, 0, 1801}, @@ -149,20 +150,21 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 65424, 0, 0, 0, 1921}, {0, 65408, 0, 0, 0, 1921}, {0, 65410, 0, 0, 0, 1921}, - {0, 0, 0, 0, 0, 1028}, - {0, 0, 0, 0, 4, 1028}, - {0, 0, 0, 0, 5, 1028}, - {0, 0, 0, 0, 6, 1028}, - {0, 0, 0, 0, 7, 1028}, - {0, 0, 0, 0, 8, 1028}, - {0, 0, 0, 0, 9, 1028}, + {0, 0, 0, 0, 0, 5124}, + {0, 0, 0, 0, 4, 5124}, + {0, 0, 0, 0, 5, 5124}, + {0, 0, 0, 0, 6, 5124}, + {0, 0, 0, 0, 7, 5124}, + {0, 0, 0, 0, 8, 5124}, + {0, 0, 0, 0, 9, 5124}, + {0, 0, 0, 0, 0, 1792}, {0, 58019, 0, 0, 0, 1921}, {0, 57153, 0, 0, 0, 1921}, {0, 57274, 0, 0, 0, 1921}, {0, 28, 0, 0, 0, 1921}, {65508, 0, 65508, 0, 0, 1801}, - {0, 16, 0, 0, 0, 1792}, - {65520, 0, 65520, 0, 0, 1792}, + {0, 16, 0, 0, 0, 5888}, + {65520, 0, 65520, 0, 0, 5888}, {0, 26, 0, 0, 0, 1024}, {65510, 0, 65510, 0, 0, 1024}, {0, 54793, 0, 0, 0, 1921}, @@ -174,209 +176,517 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, + {0, 0, 0, 0, 0, 5889}, {42877, 7545, 42877, 0, 0, 3969}, {0, 40, 0, 0, 0, 1921}, {65496, 0, 65496, 0, 0, 1801}, }; /* type indexes */ -#define SHIFT 8 +#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, 35, 36, 34, 37, - 38, 34, 34, 34, 39, 40, 41, 42, 43, 44, 45, 46, 34, 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, 47, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 48, 21, 21, 21, 21, 49, - 21, 50, 51, 52, 53, 54, 8, 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, 55, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 21, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 8, 8, 8, 68, 69, 70, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 71, 72, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 73, 74, - 75, 76, 77, 78, 79, 80, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 81, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 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, 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, 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, 82, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 83, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 84, 85, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 86, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 86, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, + 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 63, 64, 65, 66, 63, + 63, 63, 67, 68, 69, 63, 63, 63, 63, 63, 63, 70, 16, 71, 72, 73, 74, 75, + 76, 63, 77, 78, 79, 80, 81, 82, 83, 63, 63, 84, 85, 40, 40, 40, 40, 40, + 40, 86, 40, 40, 40, 40, 40, 87, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 88, 89, 90, 91, 40, 40, 40, 92, 40, 40, + 40, 93, 94, 40, 40, 40, 40, 40, 95, 40, 40, 40, 96, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 97, 98, 99, 40, 40, 40, 40, 40, 40, 100, 101, 40, 40, + 40, 40, 40, 40, 40, 40, 102, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 40, 40, 104, 40, 40, 40, 40, + 100, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 105, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 106, 107, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 109, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 110, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 111, 40, 40, 112, 113, 114, 115, 116, 117, 118, 16, 119, 16, + 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 120, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 123, 124, 125, + 126, 127, 128, 40, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 16, + 139, 140, 141, 142, 143, 16, 16, 16, 16, 16, 16, 144, 16, 145, 16, 146, + 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, 40, 40, 40, 40, 40, 40, 147, 16, 148, 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, 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, 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, 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, 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, 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, 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, + 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, 63, + 149, 150, 151, 152, 16, 153, 16, 154, 155, 156, 157, 158, 159, 160, 161, + 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, 16, 16, 16, 16, 162, 163, 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, 164, 165, 166, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 86, 167, 40, 168, 169, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 170, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 171, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 172, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 173, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 174, 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, 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, + 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, 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, 40, 170, 40, 40, 175, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 176, 16, + 177, 178, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 179, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 179, }; static unsigned char index2[] = { @@ -388,455 +698,415 @@ static unsigned char index2[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5, 5, 5, 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 19, 5, 5, - 1, 5, 5, 5, 5, 20, 21, 5, 22, 5, 17, 5, 23, 19, 5, 5, 5, 5, 5, 16, 16, + 1, 5, 5, 5, 5, 20, 21, 5, 22, 5, 17, 5, 23, 19, 5, 24, 24, 24, 5, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 5, 16, 16, 16, 16, 16, 16, 16, 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, - 18, 18, 18, 18, 18, 18, 18, 24, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 27, 28, 25, 26, 25, 26, 25, 26, 19, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 29, 25, 26, 25, 26, 25, 26, 30, 31, 32, 25, 26, 25, 26, 33, 25, - 26, 34, 34, 25, 26, 19, 35, 36, 37, 25, 26, 34, 38, 39, 40, 41, 25, 26, - 42, 19, 40, 43, 44, 45, 25, 26, 25, 26, 25, 26, 46, 25, 26, 46, 19, 19, - 25, 26, 46, 25, 26, 47, 47, 25, 26, 25, 26, 48, 25, 26, 19, 49, 25, 26, - 19, 50, 49, 49, 49, 49, 51, 52, 53, 51, 52, 53, 51, 52, 53, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 54, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 51, 52, 53, - 25, 26, 55, 56, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 57, 19, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 19, 19, 19, 19, 19, 58, 25, - 26, 59, 60, 19, 19, 25, 26, 61, 62, 63, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 64, 65, 19, 66, 67, 19, 68, 68, 19, 69, 19, 70, 19, 19, 19, 19, - 68, 19, 19, 71, 19, 19, 19, 19, 72, 73, 19, 74, 19, 19, 19, 73, 19, 75, - 76, 19, 19, 77, 19, 19, 19, 19, 19, 19, 19, 78, 19, 19, 79, 19, 19, 79, - 19, 19, 19, 19, 79, 80, 81, 81, 82, 19, 19, 19, 19, 19, 83, 19, 49, 19, + 18, 18, 18, 18, 18, 18, 18, 25, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 28, 29, 26, 27, 26, 27, 26, 27, 19, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 30, 26, 27, 26, 27, 26, 27, 31, 32, 33, 26, 27, 26, 27, 34, 26, + 27, 35, 35, 26, 27, 19, 36, 37, 38, 26, 27, 35, 39, 40, 41, 42, 26, 27, + 43, 19, 41, 44, 45, 46, 26, 27, 26, 27, 26, 27, 47, 26, 27, 47, 19, 19, + 26, 27, 47, 26, 27, 48, 48, 26, 27, 26, 27, 49, 26, 27, 19, 50, 26, 27, + 19, 51, 50, 50, 50, 50, 52, 53, 54, 52, 53, 54, 52, 53, 54, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 55, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 52, 53, 54, + 26, 27, 56, 57, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 58, 19, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26, + 27, 60, 61, 19, 19, 26, 27, 62, 63, 64, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 65, 66, 19, 67, 68, 19, 69, 69, 19, 70, 19, 71, 19, 19, 19, 19, + 69, 19, 19, 72, 19, 19, 19, 19, 73, 74, 19, 75, 19, 19, 19, 74, 19, 76, + 77, 19, 19, 78, 19, 19, 19, 19, 19, 19, 19, 79, 19, 19, 80, 19, 19, 80, + 19, 19, 19, 19, 80, 81, 82, 82, 83, 19, 19, 19, 19, 19, 84, 19, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, - 49, 49, 5, 5, 5, 5, 5, 5, 5, 49, 5, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, + 50, 50, 5, 5, 5, 5, 5, 5, 5, 50, 5, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 84, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 85, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 25, 26, 25, 26, 49, 5, 25, 26, 0, 0, 85, - 44, 44, 44, 5, 0, 0, 0, 0, 0, 5, 5, 86, 17, 87, 87, 87, 0, 88, 0, 89, 89, + 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 86, + 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 87, 17, 88, 88, 88, 0, 89, 0, 90, 90, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 90, 91, 91, 91, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 92, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 93, 94, 94, 95, 96, 97, 98, 98, 98, 99, 100, 101, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 102, 103, 104, 19, 105, 106, 5, 25, 26, 107, 25, - 26, 19, 57, 57, 57, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 91, 92, 92, 92, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 93, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 94, 95, 95, 96, 97, 98, 99, 99, 99, 100, 101, + 102, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 103, 104, 105, 19, 106, 107, 5, 26, 27, 108, + 26, 27, 19, 58, 58, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 5, - 17, 17, 17, 17, 17, 5, 5, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 109, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 110, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 49, 5, 5, 5, 5, 5, 5, 0, 112, 112, 112, 112, 112, 112, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 5, + 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 110, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 111, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 112, 112, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 112, 112, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0, - 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 5, 5, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 0, 0, 5, 5, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, - 5, 5, 5, 49, 49, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 49, 17, 17, - 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 49, 49, 17, 17, 5, 17, - 17, 17, 17, 49, 49, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 5, 5, - 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 49, 17, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 5, 5, 5, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 17, 17, + 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 50, 50, 17, 17, 5, 17, + 17, 17, 17, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 5, 5, + 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 50, 17, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 49, 49, 5, 5, 5, 5, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 49, 17, 17, 17, 17, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 5, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 0, - 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 0, 0, 0, 49, 49, 49, - 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, - 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 49, 49, 0, 49, 49, 49, - 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 0, - 0, 0, 0, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, - 49, 49, 0, 49, 49, 0, 49, 49, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, - 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 49, 49, - 49, 49, 0, 49, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 17, 17, 49, 49, 49, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, - 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 49, 49, 49, 49, 49, 0, 0, 17, - 49, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 0, 0, - 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, - 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 49, 49, - 49, 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, - 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 49, 49, 0, 49, - 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 49, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 49, 0, 49, 49, 49, 49, 49, 49, - 0, 0, 0, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 0, 49, 49, 0, 49, 0, 49, - 49, 0, 0, 0, 49, 49, 0, 0, 0, 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 17, 17, 17, 17, 17, 0, 0, 0, 17, - 17, 17, 0, 17, 17, 17, 17, 0, 0, 49, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, 0, 0, 49, 17, 17, 17, - 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 0, 49, 49, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, - 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, - 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 49, 0, 49, - 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 17, 17, 17, 17, 17, - 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, - 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 49, 49, 49, 49, 49, 49, 0, 0, 17, - 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 17, 0, 0, 0, 0, - 17, 17, 17, 17, 17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, - 49, 113, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 49, 49, 49, 49, 49, - 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 0, 49, 0, 0, - 49, 49, 0, 49, 0, 0, 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 0, 49, 49, 49, - 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 0, 49, 0, 0, 49, 49, 0, 49, 49, 49, - 49, 17, 49, 113, 17, 17, 17, 17, 17, 17, 0, 17, 17, 49, 0, 0, 49, 49, 49, - 49, 49, 0, 49, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, - 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 17, 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, - 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 5, 17, 17, 49, 49, 49, 49, 0, 0, 0, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 50, 17, 17, 17, 17, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, + 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 5, 24, 5, 0, 0, 0, + 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, + 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, + 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, + 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, + 50, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 50, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, + 0, 50, 50, 50, 50, 0, 0, 0, 50, 50, 0, 50, 0, 50, 50, 0, 0, 0, 50, 50, 0, + 0, 0, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 0, 0, 0, 0, 17, 17, 17, 17, 17, 0, 0, 0, 17, 17, 17, 0, 17, 17, 17, + 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, + 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, + 0, 0, 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 5, 0, 0, 17, 17, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, + 17, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, + 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 50, 17, 17, 0, + 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, + 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 0, 0, 0, 0, 17, 17, + 17, 17, 17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 114, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, + 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, + 50, 50, 0, 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, + 50, 114, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, + 0, 50, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 17, 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 50, 50, 50, 50, 50, 50, 50, + 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 50, 50, 50, 50, 0, 0, 0, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, - 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, - 49, 49, 49, 49, 17, 17, 17, 49, 17, 17, 17, 49, 49, 17, 17, 17, 17, 17, - 17, 17, 49, 49, 49, 17, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 5, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, - 49, 49, 49, 49, 0, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, - 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 0, - 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 49, 49, 49, 49, 49, 49, 49, 49, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0, 0, - 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 5, 5, 5, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, - 49, 49, 49, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, + 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, + 17, 17, 17, 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, + 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 116, 117, 118, 119, 120, 121, 122, 123, 124, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 5, 5, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 5, 5, 5, 49, 5, 5, 5, 5, 49, 17, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 49, 49, 49, - 49, 49, 49, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, - 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 49, 49, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 0, 0, 0, 49, 49, 49, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 125, - 19, 19, 19, 126, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, + 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, + 0, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 50, 126, 19, 19, 19, 127, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 19, 19, 19, 19, 19, 127, 19, 19, 128, 19, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130, - 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, 0, 0, 130, - 130, 130, 130, 130, 130, 0, 0, 129, 129, 129, 129, 129, 129, 129, 129, - 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, - 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, - 129, 129, 0, 0, 130, 130, 130, 130, 130, 130, 0, 0, 19, 129, 19, 129, 19, - 129, 19, 129, 0, 130, 0, 130, 0, 130, 0, 130, 129, 129, 129, 129, 129, - 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 132, - 132, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 0, 0, 129, 129, - 129, 129, 129, 129, 129, 129, 137, 137, 137, 137, 137, 137, 137, 137, - 129, 129, 129, 129, 129, 129, 129, 129, 137, 137, 137, 137, 137, 137, - 137, 137, 129, 129, 129, 129, 129, 129, 129, 129, 137, 137, 137, 137, - 137, 137, 137, 137, 129, 129, 19, 138, 19, 0, 19, 19, 130, 130, 139, 139, - 140, 5, 141, 5, 5, 5, 19, 138, 19, 0, 19, 19, 142, 142, 142, 142, 140, 5, - 5, 5, 129, 129, 19, 19, 0, 0, 19, 19, 130, 130, 143, 143, 0, 5, 5, 5, - 129, 129, 19, 19, 19, 104, 19, 19, 130, 130, 144, 144, 107, 5, 5, 5, 0, - 0, 19, 138, 19, 0, 19, 19, 145, 145, 146, 146, 140, 5, 5, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 147, 19, 0, 0, 148, 149, 150, 151, - 152, 153, 5, 5, 5, 5, 5, 19, 147, 23, 20, 21, 148, 149, 150, 151, 152, - 153, 5, 5, 5, 5, 5, 0, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5, - 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 98, 5, 5, 5, 5, 98, 5, 5, 19, 98, 98, - 98, 19, 19, 98, 98, 98, 19, 5, 98, 5, 5, 124, 98, 98, 98, 98, 98, 5, 5, - 5, 5, 5, 5, 98, 5, 154, 5, 98, 5, 155, 156, 98, 98, 124, 19, 98, 98, 157, - 98, 19, 49, 49, 49, 49, 19, 5, 5, 19, 19, 98, 98, 5, 5, 5, 5, 5, 98, 19, - 19, 19, 19, 5, 5, 5, 5, 158, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, - 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 160, 160, 124, 124, 124, 25, 26, 124, 124, 124, 124, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 19, 19, 19, 19, 19, 128, 19, 19, 129, 19, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 130, 130, + 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, + 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, + 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, + 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, + 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, + 131, 131, 131, 0, 0, 19, 130, 19, 130, 19, 130, 19, 130, 0, 131, 0, 131, + 0, 131, 0, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, + 131, 131, 131, 131, 131, 132, 132, 133, 133, 133, 133, 134, 134, 135, + 135, 136, 136, 137, 137, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, + 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, 130, 130, + 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, + 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 19, + 139, 19, 0, 19, 19, 131, 131, 140, 140, 141, 5, 142, 5, 5, 5, 19, 139, + 19, 0, 19, 19, 143, 143, 143, 143, 141, 5, 5, 5, 130, 130, 19, 19, 0, 0, + 19, 19, 131, 131, 144, 144, 0, 5, 5, 5, 130, 130, 19, 19, 19, 105, 19, + 19, 131, 131, 145, 145, 108, 5, 5, 5, 0, 0, 19, 139, 19, 0, 19, 19, 146, + 146, 147, 147, 141, 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 148, 19, 0, 0, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 19, + 148, 23, 20, 21, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 0, 50, 50, + 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 99, 5, 5, 5, 5, 99, 5, 5, 19, 99, 99, 99, 19, 19, 99, 99, 99, 19, 5, + 99, 5, 5, 155, 99, 99, 99, 99, 99, 5, 5, 5, 5, 5, 5, 99, 5, 156, 5, 99, + 5, 157, 158, 99, 99, 155, 19, 99, 99, 159, 99, 19, 50, 50, 50, 50, 19, 5, + 5, 19, 19, 99, 99, 5, 5, 5, 5, 5, 99, 19, 19, 19, 19, 5, 5, 5, 5, 160, 5, + 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 125, 125, 125, 26, 27, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -851,614 +1121,747 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 147, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150, - 151, 152, 153, 5, 147, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, + 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, + 151, 152, 153, 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 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, 148, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 148, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 20, - 21, 148, 149, 150, 151, 152, 153, 5, 23, 20, 21, 148, 149, 150, 151, 152, - 153, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, + 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, 149, 150, 151, 152, 153, + 154, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 25, 26, 163, 164, 165, 166, - 167, 25, 26, 25, 26, 25, 26, 168, 169, 170, 0, 19, 25, 26, 19, 25, 26, - 19, 19, 19, 19, 19, 19, 49, 0, 0, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, - 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, - 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, - 49, 49, 49, 49, 49, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 26, 27, 165, 166, 167, + 168, 169, 26, 27, 26, 27, 26, 27, 170, 171, 172, 0, 19, 26, 27, 19, 26, + 27, 19, 19, 19, 19, 19, 19, 50, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, + 5, 5, 24, 5, 5, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, + 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 85, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 86, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 49, 49, 124, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, 17, 5, 49, 49, 49, - 49, 49, 5, 5, 124, 124, 124, 49, 49, 5, 5, 5, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 17, 17, 5, 5, 49, 49, 49, 5, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, - 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 125, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, + 125, 125, 125, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, + 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, + 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 49, 17, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 17, 17, 5, 49, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, - 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 19, 19, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 49, - 19, 19, 19, 19, 19, 19, 19, 19, 25, 26, 25, 26, 172, 25, 26, 25, 26, 25, - 26, 25, 26, 25, 26, 49, 5, 5, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 49, 49, 49, 49, 49, 49, 17, 49, 49, 49, 17, 49, 49, 49, 49, 17, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, - 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 17, 49, 49, 49, 49, 49, 49, - 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 174, + 50, 50, 174, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 174, 50, 174, 174, 174, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 174, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 174, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, + 26, 27, 175, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 17, + 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, + 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, + 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 49, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, - 49, 0, 49, 49, 0, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 85, 85, 85, 85, 85, 85, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 85, 85, 5, 5, 0, 0, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 85, 49, 85, 49, 85, 0, - 85, 49, 85, 49, 85, 49, 85, 49, 85, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 1, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, - 5, 5, 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, 5, 5, 5, 5, 17, 5, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 113, 113, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 49, - 49, 49, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 5, 5, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, - 0, 0, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 124, 49, 49, 49, 49, 49, 49, 49, 49, 124, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 5, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, - 49, 49, 49, 49, 49, 49, 49, 49, 5, 124, 124, 124, 124, 124, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, - 49, 0, 0, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 0, 0, 49, - 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, - 17, 17, 17, 17, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 148, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, + 86, 86, 86, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 86, 5, 5, + 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, + 0, 0, 86, 50, 86, 50, 86, 0, 86, 50, 86, 50, 86, 50, 86, 50, 86, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 1, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 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, 5, 5, 5, + 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 114, 114, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, + 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 5, 5, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 125, 50, 50, 50, 50, 50, 50, 50, 50, 125, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, + 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, 50, 0, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, + 24, 24, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, + 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, + 23, 20, 21, 149, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 155, 155, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 155, 155, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 5, 5, 5, 17, 17, 17, 17, - 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 17, - 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 5, 5, 5, 17, 17, 17, + 17, 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, - 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, + 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 0, 99, + 99, 0, 0, 99, 0, 0, 99, 99, 0, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, + 99, 99, 99, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 98, 0, 98, 98, 0, 0, 98, 0, 0, 98, 98, 0, 0, 98, 98, 98, - 98, 0, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 0, 19, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 0, - 98, 98, 98, 98, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 0, 98, 98, 98, 98, - 98, 98, 98, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 0, 98, 98, 98, - 98, 0, 98, 98, 98, 98, 98, 0, 98, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 0, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 0, 99, 99, + 99, 99, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, + 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 0, 99, + 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, - 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 5, 19, 19, 19, + 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, - 19, 98, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 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, + 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 19, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1471,18 +1874,1312 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 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, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 1, 1, 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, 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/2; + 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 0x1B50: + case 0x1BB0: + case 0x1C40: + case 0x1C50: + case 0x2070: + case 0x2080: + case 0x24EA: + case 0x24FF: + case 0x3007: + case 0x96F6: + case 0xA620: + case 0xA8D0: + case 0xA900: + case 0xAA50: + case 0xF9B2: + case 0xFF10: +#ifdef Py_UNICODE_WIDE + case 0x1018A: + case 0x104A0: + case 0x1D7CE: + case 0x1D7D8: + case 0x1D7E2: + case 0x1D7EC: + case 0x1D7F6: +#endif + return (double) 0; + case 0x0031: + case 0x00B9: + case 0x0661: + case 0x06F1: + case 0x07C1: + case 0x0967: + case 0x09E7: + case 0x09F4: + 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 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 0xA8D1: + case 0xA901: + case 0xAA51: + case 0xFF11: +#ifdef Py_UNICODE_WIDE + case 0x10107: + case 0x10142: + case 0x10158: + case 0x10159: + case 0x1015A: + case 0x10320: + case 0x103D1: + case 0x104A1: + case 0x10916: + case 0x10A40: + 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 0x2092A: +#endif + return (double) 1; + case 0x00BD: + case 0x0D74: + case 0x0F2A: + case 0x2CFD: +#ifdef Py_UNICODE_WIDE + case 0x10141: + case 0x10175: + case 0x10176: +#endif + return (double) 1/2; + case 0x2153: +#ifdef Py_UNICODE_WIDE + case 0x1245A: + case 0x1245D: +#endif + return (double) 1/3; + case 0x00BC: + case 0x0D73: +#ifdef Py_UNICODE_WIDE + case 0x10140: + case 0x12460: + case 0x12462: +#endif + return (double) 1/4; + case 0x2155: + return (double) 1/5; + case 0x2159: +#ifdef Py_UNICODE_WIDE + case 0x12461: +#endif + return (double) 1/6; + case 0x215B: +#ifdef Py_UNICODE_WIDE + case 0x1245F: +#endif + return (double) 1/8; + 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 0x10917: + case 0x10A44: + case 0x1D369: +#endif + return (double) 10; + 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 0x10919: + case 0x10A46: +#endif + return (double) 100; + 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 0x10A47: +#endif + return (double) 1000; + case 0x137C: + case 0x2182: + case 0x4E07: + case 0x842C: +#ifdef Py_UNICODE_WIDE + case 0x1012B: + case 0x10155: +#endif + return (double) 10000; + case 0x2188: + return (double) 100000; + case 0x4EBF: + case 0x5104: + return (double) 100000000; + case 0x5146: + return (double) 1000000000000; + case 0x216A: + case 0x217A: + case 0x246A: + case 0x247E: + case 0x2492: + case 0x24EB: + return (double) 11; + case 0x0F2F: + return (double) 11/2; + case 0x216B: + case 0x217B: + case 0x246B: + case 0x247F: + case 0x2493: + case 0x24EC: + return (double) 12; + case 0x246C: + case 0x2480: + case 0x2494: + case 0x24ED: + return (double) 13; + case 0x0F30: + return (double) 13/2; + case 0x246D: + case 0x2481: + case 0x2495: + case 0x24EE: + return (double) 14; + case 0x246E: + case 0x2482: + case 0x2496: + case 0x24EF: + return (double) 15; + case 0x0F31: + return (double) 15/2; + case 0x09F9: + case 0x246F: + case 0x2483: + case 0x2497: + case 0x24F0: + return (double) 16; + case 0x16EE: + case 0x2470: + case 0x2484: + case 0x2498: + case 0x24F1: + return (double) 17; + case 0x0F32: + return (double) 17/2; + case 0x16EF: + case 0x2471: + case 0x2485: + case 0x2499: + case 0x24F2: + return (double) 18; + case 0x16F0: + case 0x2472: + case 0x2486: + case 0x249A: + case 0x24F3: + return (double) 19; + case 0x0032: + case 0x00B2: + case 0x0662: + case 0x06F2: + case 0x07C2: + case 0x0968: + case 0x09E8: + case 0x09F5: + 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 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 0xA8D2: + case 0xA902: + case 0xAA52: + case 0xF978: + case 0xFF12: +#ifdef Py_UNICODE_WIDE + case 0x10108: + case 0x1015B: + case 0x1015C: + case 0x1015D: + case 0x1015E: + case 0x103D2: + case 0x104A2: + case 0x10A41: + 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 0x22390: +#endif + return (double) 2; + case 0x2154: +#ifdef Py_UNICODE_WIDE + case 0x10177: + case 0x1245B: + case 0x1245E: +#endif + return (double) 2/3; + case 0x2156: + return (double) 2/5; + 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 0x10918: + case 0x10A45: + case 0x1D36A: +#endif + return (double) 20; +#ifdef Py_UNICODE_WIDE + case 0x1011A: + return (double) 200; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10123: + return (double) 2000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x1012C: + return (double) 20000; +#endif + case 0x3251: + return (double) 21; + case 0x3252: + return (double) 22; + case 0x3253: + return (double) 23; + case 0x3254: + return (double) 24; + case 0x3255: + return (double) 25; + case 0x3256: + return (double) 26; + case 0x3257: + return (double) 27; + case 0x3258: + return (double) 28; + case 0x3259: + return (double) 29; + case 0x0033: + case 0x00B3: + case 0x0663: + case 0x06F3: + case 0x07C3: + case 0x0969: + case 0x09E9: + case 0x09F6: + 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 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 0xA8D3: + case 0xA903: + case 0xAA53: + case 0xF96B: + case 0xFF13: +#ifdef Py_UNICODE_WIDE + case 0x10109: + case 0x104A3: + case 0x10A42: + 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 0x20AFD: + case 0x20B19: + case 0x22998: + case 0x23B1B: +#endif + return (double) 3; + case 0x0F2B: + return (double) 3/2; + case 0x00BE: + case 0x0D75: +#ifdef Py_UNICODE_WIDE + case 0x10178: +#endif + return (double) 3/4; + case 0x2157: + return (double) 3/5; + case 0x215C: + return (double) 3/8; + case 0x1374: + case 0x303A: + case 0x325A: + case 0x5345: +#ifdef Py_UNICODE_WIDE + case 0x10112: + case 0x10165: + case 0x1D36B: + case 0x20983: +#endif + return (double) 30; +#ifdef Py_UNICODE_WIDE + case 0x1011B: + case 0x1016B: + return (double) 300; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10124: + return (double) 3000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x1012D: + return (double) 30000; +#endif + case 0x325B: + return (double) 31; + case 0x325C: + return (double) 32; + case 0x325D: + return (double) 33; + case 0x325E: + return (double) 34; + case 0x325F: + return (double) 35; + case 0x32B1: + return (double) 36; + case 0x32B2: + return (double) 37; + case 0x32B3: + return (double) 38; + case 0x32B4: + return (double) 39; + case 0x0034: + case 0x0664: + case 0x06F4: + case 0x07C4: + case 0x096A: + case 0x09EA: + case 0x09F7: + 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 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 0xA8D4: + case 0xA904: + case 0xAA54: + case 0xFF14: +#ifdef Py_UNICODE_WIDE + case 0x1010A: + case 0x104A4: + case 0x10A43: + 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 0x20064: + case 0x200E2: + case 0x2626D: +#endif + return (double) 4; + case 0x2158: + return (double) 4/5; + case 0x1375: + case 0x32B5: + case 0x534C: +#ifdef Py_UNICODE_WIDE + case 0x10113: + case 0x1D36C: + case 0x2098C: + case 0x2099C: +#endif + return (double) 40; +#ifdef Py_UNICODE_WIDE + case 0x1011C: + return (double) 400; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10125: + return (double) 4000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x1012E: + return (double) 40000; +#endif + case 0x32B6: + return (double) 41; + case 0x32B7: + return (double) 42; + case 0x32B8: + return (double) 43; + case 0x32B9: + return (double) 44; + case 0x32BA: + return (double) 45; + case 0x32BB: + return (double) 46; + case 0x32BC: + return (double) 47; + case 0x32BD: + return (double) 48; + case 0x32BE: + return (double) 49; + 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 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 0xA8D5: + case 0xA905: + case 0xAA55: + case 0xFF15: +#ifdef Py_UNICODE_WIDE + case 0x1010B: + case 0x10143: + case 0x10148: + case 0x1014F: + case 0x1015F: + case 0x10173: + case 0x10321: + case 0x104A5: + 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 0x20121: +#endif + return (double) 5; + case 0x0F2C: + return (double) 5/2; + case 0x215A: +#ifdef Py_UNICODE_WIDE + case 0x1245C: +#endif + return (double) 5/6; + case 0x215D: + return (double) 5/8; + 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 0x1D36D: +#endif + return (double) 50; + 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: +#endif + return (double) 500; + case 0x2181: +#ifdef Py_UNICODE_WIDE + case 0x10126: + case 0x10146: + case 0x1014E: + case 0x10172: +#endif + return (double) 5000; + case 0x2187: +#ifdef Py_UNICODE_WIDE + case 0x1012F: + case 0x10147: + case 0x10156: +#endif + return (double) 50000; + 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 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 0xA8D6: + case 0xA906: + case 0xAA56: + case 0xF9D1: + case 0xF9D3: + case 0xFF16: +#ifdef Py_UNICODE_WIDE + case 0x1010C: + case 0x104A6: + 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 0x20AEA: +#endif + return (double) 6; + case 0x1377: +#ifdef Py_UNICODE_WIDE + case 0x10115: + case 0x1D36E: +#endif + return (double) 60; +#ifdef Py_UNICODE_WIDE + case 0x1011E: + return (double) 600; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10127: + return (double) 6000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10130: + return (double) 60000; +#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 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 0xA8D7: + case 0xA907: + case 0xAA57: + case 0xFF17: +#ifdef Py_UNICODE_WIDE + case 0x1010D: + case 0x104A7: + 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 0x20001: +#endif + return (double) 7; + case 0x0F2D: + return (double) 7/2; + case 0x215E: + return (double) 7/8; + case 0x1378: +#ifdef Py_UNICODE_WIDE + case 0x10116: + case 0x1D36F: +#endif + return (double) 70; +#ifdef Py_UNICODE_WIDE + case 0x1011F: + return (double) 700; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10128: + return (double) 7000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10131: + return (double) 70000; +#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 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 0xA8D8: + case 0xA908: + case 0xAA58: + case 0xFF18: +#ifdef Py_UNICODE_WIDE + case 0x1010E: + case 0x104A8: + 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: +#endif + return (double) 8; + case 0x1379: +#ifdef Py_UNICODE_WIDE + case 0x10117: + case 0x1D370: +#endif + return (double) 80; +#ifdef Py_UNICODE_WIDE + case 0x10120: + return (double) 800; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10129: + return (double) 8000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10132: + return (double) 80000; +#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 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 0xA8D9: + case 0xA909: + case 0xAA59: + case 0xFF19: +#ifdef Py_UNICODE_WIDE + case 0x1010F: + case 0x104A9: + 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 0x2F890: +#endif + return (double) 9; + case 0x0F2E: + return (double) 9/2; + case 0x137A: +#ifdef Py_UNICODE_WIDE + case 0x10118: + case 0x10341: + case 0x1D371: +#endif + return (double) 90; +#ifdef Py_UNICODE_WIDE + case 0x10121: + case 0x1034A: + return (double) 900; +#endif +#ifdef Py_UNICODE_WIDE + case 0x1012A: + return (double) 9000; +#endif +#ifdef Py_UNICODE_WIDE + case 0x10133: + return (double) 90000; +#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 category 'Zl', + * 'Zp' or type 'B', 0 otherwise. + */ +int _PyUnicode_IsLinebreak(register const Py_UNICODE ch) +{ + switch (ch) { + case 0x000A: + case 0x000D: + case 0x001C: + case 0x001D: + case 0x001E: + case 0x0085: + case 0x2028: + case 0x2029: + return 1; + } + return 0; +} + -- cgit v1.2.1 From 276357adf883fb5beaf3a2ab7576b735405e2097 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Tue, 13 Oct 2009 23:18:53 +0000 Subject: Merged revisions 75396 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75396 | amaury.forgeotdarc | 2009-10-13 23:29:34 +0200 (mar., 13 oct. 2009) | 3 lines #7112: Fix compilation warning in unicodetype_db.h makeunicodedata now generates double literals ........ --- Objects/unicodetype_db.h | 218 +++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 109 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index e2c68e736f..00a43e8014 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -1890,7 +1890,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) { switch (ch) { case 0x0F33: - return (double) -1/2; + return (double) -1.0/2.0; case 0x0030: case 0x0660: case 0x06F0: @@ -1940,7 +1940,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7EC: case 0x1D7F6: #endif - return (double) 0; + return (double) 0.0; case 0x0031: case 0x00B9: case 0x0661: @@ -2023,7 +2023,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7F7: case 0x2092A: #endif - return (double) 1; + return (double) 1.0; case 0x00BD: case 0x0D74: case 0x0F2A: @@ -2033,13 +2033,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10175: case 0x10176: #endif - return (double) 1/2; + return (double) 1.0/2.0; case 0x2153: #ifdef Py_UNICODE_WIDE case 0x1245A: case 0x1245D: #endif - return (double) 1/3; + return (double) 1.0/3.0; case 0x00BC: case 0x0D73: #ifdef Py_UNICODE_WIDE @@ -2047,19 +2047,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x12460: case 0x12462: #endif - return (double) 1/4; + return (double) 1.0/4.0; case 0x2155: - return (double) 1/5; + return (double) 1.0/5.0; case 0x2159: #ifdef Py_UNICODE_WIDE case 0x12461: #endif - return (double) 1/6; + return (double) 1.0/6.0; case 0x215B: #ifdef Py_UNICODE_WIDE case 0x1245F: #endif - return (double) 1/8; + return (double) 1.0/8.0; case 0x0BF0: case 0x0D70: case 0x1372: @@ -2096,7 +2096,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10A44: case 0x1D369: #endif - return (double) 10; + return (double) 10.0; case 0x0BF1: case 0x0D71: case 0x137B: @@ -2114,7 +2114,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10919: case 0x10A46: #endif - return (double) 100; + return (double) 100.0; case 0x0BF2: case 0x0D72: case 0x216F: @@ -2130,7 +2130,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10171: case 0x10A47: #endif - return (double) 1000; + return (double) 1000.0; case 0x137C: case 0x2182: case 0x4E07: @@ -2139,75 +2139,75 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1012B: case 0x10155: #endif - return (double) 10000; + return (double) 10000.0; case 0x2188: - return (double) 100000; + return (double) 100000.0; case 0x4EBF: case 0x5104: - return (double) 100000000; + return (double) 100000000.0; case 0x5146: - return (double) 1000000000000; + return (double) 1000000000000.0; case 0x216A: case 0x217A: case 0x246A: case 0x247E: case 0x2492: case 0x24EB: - return (double) 11; + return (double) 11.0; case 0x0F2F: - return (double) 11/2; + return (double) 11.0/2.0; case 0x216B: case 0x217B: case 0x246B: case 0x247F: case 0x2493: case 0x24EC: - return (double) 12; + return (double) 12.0; case 0x246C: case 0x2480: case 0x2494: case 0x24ED: - return (double) 13; + return (double) 13.0; case 0x0F30: - return (double) 13/2; + return (double) 13.0/2.0; case 0x246D: case 0x2481: case 0x2495: case 0x24EE: - return (double) 14; + return (double) 14.0; case 0x246E: case 0x2482: case 0x2496: case 0x24EF: - return (double) 15; + return (double) 15.0; case 0x0F31: - return (double) 15/2; + return (double) 15.0/2.0; case 0x09F9: case 0x246F: case 0x2483: case 0x2497: case 0x24F0: - return (double) 16; + return (double) 16.0; case 0x16EE: case 0x2470: case 0x2484: case 0x2498: case 0x24F1: - return (double) 17; + return (double) 17.0; case 0x0F32: - return (double) 17/2; + return (double) 17.0/2.0; case 0x16EF: case 0x2471: case 0x2485: case 0x2499: case 0x24F2: - return (double) 18; + return (double) 18.0; case 0x16F0: case 0x2472: case 0x2486: case 0x249A: case 0x24F3: - return (double) 19; + return (double) 19.0; case 0x0032: case 0x00B2: case 0x0662: @@ -2294,16 +2294,16 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7F8: case 0x22390: #endif - return (double) 2; + return (double) 2.0; case 0x2154: #ifdef Py_UNICODE_WIDE case 0x10177: case 0x1245B: case 0x1245E: #endif - return (double) 2/3; + return (double) 2.0/3.0; case 0x2156: - return (double) 2/5; + return (double) 2.0/5.0; case 0x1373: case 0x2473: case 0x2487: @@ -2319,37 +2319,37 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10A45: case 0x1D36A: #endif - return (double) 20; + return (double) 20.0; #ifdef Py_UNICODE_WIDE case 0x1011A: - return (double) 200; + return (double) 200.0; #endif #ifdef Py_UNICODE_WIDE case 0x10123: - return (double) 2000; + return (double) 2000.0; #endif #ifdef Py_UNICODE_WIDE case 0x1012C: - return (double) 20000; + return (double) 20000.0; #endif case 0x3251: - return (double) 21; + return (double) 21.0; case 0x3252: - return (double) 22; + return (double) 22.0; case 0x3253: - return (double) 23; + return (double) 23.0; case 0x3254: - return (double) 24; + return (double) 24.0; case 0x3255: - return (double) 25; + return (double) 25.0; case 0x3256: - return (double) 26; + return (double) 26.0; case 0x3257: - return (double) 27; + return (double) 27.0; case 0x3258: - return (double) 28; + return (double) 28.0; case 0x3259: - return (double) 29; + return (double) 29.0; case 0x0033: case 0x00B3: case 0x0663: @@ -2438,19 +2438,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x22998: case 0x23B1B: #endif - return (double) 3; + return (double) 3.0; case 0x0F2B: - return (double) 3/2; + return (double) 3.0/2.0; case 0x00BE: case 0x0D75: #ifdef Py_UNICODE_WIDE case 0x10178: #endif - return (double) 3/4; + return (double) 3.0/4.0; case 0x2157: - return (double) 3/5; + return (double) 3.0/5.0; case 0x215C: - return (double) 3/8; + return (double) 3.0/8.0; case 0x1374: case 0x303A: case 0x325A: @@ -2461,38 +2461,38 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D36B: case 0x20983: #endif - return (double) 30; + return (double) 30.0; #ifdef Py_UNICODE_WIDE case 0x1011B: case 0x1016B: - return (double) 300; + return (double) 300.0; #endif #ifdef Py_UNICODE_WIDE case 0x10124: - return (double) 3000; + return (double) 3000.0; #endif #ifdef Py_UNICODE_WIDE case 0x1012D: - return (double) 30000; + return (double) 30000.0; #endif case 0x325B: - return (double) 31; + return (double) 31.0; case 0x325C: - return (double) 32; + return (double) 32.0; case 0x325D: - return (double) 33; + return (double) 33.0; case 0x325E: - return (double) 34; + return (double) 34.0; case 0x325F: - return (double) 35; + return (double) 35.0; case 0x32B1: - return (double) 36; + return (double) 36.0; case 0x32B2: - return (double) 37; + return (double) 37.0; case 0x32B3: - return (double) 38; + return (double) 38.0; case 0x32B4: - return (double) 39; + return (double) 39.0; case 0x0034: case 0x0664: case 0x06F4: @@ -2574,9 +2574,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x200E2: case 0x2626D: #endif - return (double) 4; + return (double) 4.0; case 0x2158: - return (double) 4/5; + return (double) 4.0/5.0; case 0x1375: case 0x32B5: case 0x534C: @@ -2586,37 +2586,37 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x2098C: case 0x2099C: #endif - return (double) 40; + return (double) 40.0; #ifdef Py_UNICODE_WIDE case 0x1011C: - return (double) 400; + return (double) 400.0; #endif #ifdef Py_UNICODE_WIDE case 0x10125: - return (double) 4000; + return (double) 4000.0; #endif #ifdef Py_UNICODE_WIDE case 0x1012E: - return (double) 40000; + return (double) 40000.0; #endif case 0x32B6: - return (double) 41; + return (double) 41.0; case 0x32B7: - return (double) 42; + return (double) 42.0; case 0x32B8: - return (double) 43; + return (double) 43.0; case 0x32B9: - return (double) 44; + return (double) 44.0; case 0x32BA: - return (double) 45; + return (double) 45.0; case 0x32BB: - return (double) 46; + return (double) 46.0; case 0x32BC: - return (double) 47; + return (double) 47.0; case 0x32BD: - return (double) 48; + return (double) 48.0; case 0x32BE: - return (double) 49; + return (double) 49.0; case 0x0035: case 0x0665: case 0x06F5: @@ -2696,16 +2696,16 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7FB: case 0x20121: #endif - return (double) 5; + return (double) 5.0; case 0x0F2C: - return (double) 5/2; + return (double) 5.0/2.0; case 0x215A: #ifdef Py_UNICODE_WIDE case 0x1245C: #endif - return (double) 5/6; + return (double) 5.0/6.0; case 0x215D: - return (double) 5/8; + return (double) 5.0/8.0; case 0x1376: case 0x216C: case 0x217C: @@ -2724,7 +2724,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10323: case 0x1D36D: #endif - return (double) 50; + return (double) 50.0; case 0x216E: case 0x217E: #ifdef Py_UNICODE_WIDE @@ -2738,7 +2738,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1016F: case 0x10170: #endif - return (double) 500; + return (double) 500.0; case 0x2181: #ifdef Py_UNICODE_WIDE case 0x10126: @@ -2746,14 +2746,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1014E: case 0x10172: #endif - return (double) 5000; + return (double) 5000.0; case 0x2187: #ifdef Py_UNICODE_WIDE case 0x1012F: case 0x10147: case 0x10156: #endif - return (double) 50000; + return (double) 50000.0; case 0x0036: case 0x0666: case 0x06F6: @@ -2825,24 +2825,24 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7FC: case 0x20AEA: #endif - return (double) 6; + return (double) 6.0; case 0x1377: #ifdef Py_UNICODE_WIDE case 0x10115: case 0x1D36E: #endif - return (double) 60; + return (double) 60.0; #ifdef Py_UNICODE_WIDE case 0x1011E: - return (double) 600; + return (double) 600.0; #endif #ifdef Py_UNICODE_WIDE case 0x10127: - return (double) 6000; + return (double) 6000.0; #endif #ifdef Py_UNICODE_WIDE case 0x10130: - return (double) 60000; + return (double) 60000.0; #endif case 0x0037: case 0x0667: @@ -2914,28 +2914,28 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7FD: case 0x20001: #endif - return (double) 7; + return (double) 7.0; case 0x0F2D: - return (double) 7/2; + return (double) 7.0/2.0; case 0x215E: - return (double) 7/8; + return (double) 7.0/8.0; case 0x1378: #ifdef Py_UNICODE_WIDE case 0x10116: case 0x1D36F: #endif - return (double) 70; + return (double) 70.0; #ifdef Py_UNICODE_WIDE case 0x1011F: - return (double) 700; + return (double) 700.0; #endif #ifdef Py_UNICODE_WIDE case 0x10128: - return (double) 7000; + return (double) 7000.0; #endif #ifdef Py_UNICODE_WIDE case 0x10131: - return (double) 70000; + return (double) 70000.0; #endif case 0x0038: case 0x0668: @@ -3003,24 +3003,24 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7F4: case 0x1D7FE: #endif - return (double) 8; + return (double) 8.0; case 0x1379: #ifdef Py_UNICODE_WIDE case 0x10117: case 0x1D370: #endif - return (double) 80; + return (double) 80.0; #ifdef Py_UNICODE_WIDE case 0x10120: - return (double) 800; + return (double) 800.0; #endif #ifdef Py_UNICODE_WIDE case 0x10129: - return (double) 8000; + return (double) 8000.0; #endif #ifdef Py_UNICODE_WIDE case 0x10132: - return (double) 80000; + return (double) 80000.0; #endif case 0x0039: case 0x0669: @@ -3092,28 +3092,28 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7FF: case 0x2F890: #endif - return (double) 9; + return (double) 9.0; case 0x0F2E: - return (double) 9/2; + return (double) 9.0/2.0; case 0x137A: #ifdef Py_UNICODE_WIDE case 0x10118: case 0x10341: case 0x1D371: #endif - return (double) 90; + return (double) 90.0; #ifdef Py_UNICODE_WIDE case 0x10121: case 0x1034A: - return (double) 900; + return (double) 900.0; #endif #ifdef Py_UNICODE_WIDE case 0x1012A: - return (double) 9000; + return (double) 9000.0; #endif #ifdef Py_UNICODE_WIDE case 0x10133: - return (double) 90000; + return (double) 90000.0; #endif } return -1.0; -- cgit v1.2.1 From ca1d3e5d31c7885c0460aa8cc129d2fe4cbbace2 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 14 Oct 2009 17:14:16 +0000 Subject: Issue #7065: Fix a crash in bytes.maketrans and bytearray.maketrans when using byte values greater than 127. Patch by egreen. --- Objects/bytes_methods.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 3bac2d15eb..6908eb853f 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -427,7 +427,7 @@ _Py_bytes_maketrans(PyObject *args) { PyObject *frm, *to, *res = NULL; Py_buffer bfrm, bto; - int i; + Py_ssize_t i; char *p; bfrm.len = -1; @@ -452,7 +452,7 @@ _Py_bytes_maketrans(PyObject *args) for (i = 0; i < 256; i++) p[i] = i; for (i = 0; i < bfrm.len; i++) { - p[(int)((char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; } done: -- cgit v1.2.1 From 94be56fe981742b8657e2f07ecb86b5aca70711c Mon Sep 17 00:00:00 2001 From: Skip Montanaro Date: Sun, 18 Oct 2009 14:25:35 +0000 Subject: Issue 7147 - remove ability to attempt to build Python without complex number support (was broken anyway) --- Objects/complexobject.c | 4 ---- Objects/object.c | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 30d8b5216e..ccee38229c 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -12,8 +12,6 @@ #include #endif -#ifndef WITHOUT_COMPLEX - /* elementary operations on complex numbers */ static Py_complex c_1 = {1., 0.}; @@ -1108,5 +1106,3 @@ PyTypeObject PyComplex_Type = { complex_new, /* tp_new */ PyObject_Del, /* tp_free */ }; - -#endif diff --git a/Objects/object.c b/Objects/object.c index e8ac8a2e46..90cdc74195 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1536,10 +1536,9 @@ _Py_ReadyTypes(void) 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"); -- cgit v1.2.1 From 17eb2fc0f9b1763c1256301cc723f46eacf3e653 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 25 Oct 2009 20:43:34 +0000 Subject: Merged revisions 75697 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75697 | mark.dickinson | 2009-10-25 20:39:06 +0000 (Sun, 25 Oct 2009) | 3 lines Issue #1087418: Small performance boost for bitwise operations on longs. Initial patch by Gregory Smith; some tweaks added. ........ --- Objects/longobject.c | 166 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 66 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index ade812ab0e..ba869701c7 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3638,6 +3638,22 @@ lshift_error: return (PyObject *) maybe_small_long(z); } +/* Compute two's complement of digit vector a[0:m], writing result to + z[0:m]. The digit vector a need not be normalized, but should not + be entirely zero. a and z may point to the same digit vector. */ + +static void +v_complement(digit *z, digit *a, Py_ssize_t m) +{ + Py_ssize_t i; + digit carry = 1; + for (i = 0; i < m; ++i) { + carry += a[i] ^ PyLong_MASK; + z[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + assert(carry == 0); +} /* Bitwise and/xor/or operations */ @@ -3646,104 +3662,122 @@ long_bitwise(PyLongObject *a, int op, /* '&', '|', '^' */ PyLongObject *b) { - digit maska, maskb; /* 0 or PyLong_MASK */ - int negz; + int nega, negb, negz; Py_ssize_t size_a, size_b, size_z, i; PyLongObject *z; - digit diga, digb; - PyObject *v; - if (Py_SIZE(a) < 0) { - a = (PyLongObject *) long_invert(a); - if (a == NULL) + /* Bitwise operations for negative numbers operate as though + on a two's complement representation. So convert arguments + from sign-magnitude to two's complement, and convert the + result back to sign-magnitude at the end. */ + + /* If a is negative, replace it by its two's complement. */ + size_a = ABS(Py_SIZE(a)); + nega = Py_SIZE(a) < 0; + if (nega) { + z = _PyLong_New(size_a); + if (z == NULL) return NULL; - maska = PyLong_MASK; + v_complement(z->ob_digit, a->ob_digit, size_a); + a = z; } - else { + else + /* Keep reference count consistent. */ Py_INCREF(a); - maska = 0; - } - if (Py_SIZE(b) < 0) { - b = (PyLongObject *) long_invert(b); - if (b == NULL) { + + /* Same for b. */ + size_b = ABS(Py_SIZE(b)); + negb = Py_SIZE(b) < 0; + if (negb) { + z = _PyLong_New(size_b); + if (z == NULL) { Py_DECREF(a); return NULL; } - maskb = PyLong_MASK; + v_complement(z->ob_digit, b->ob_digit, size_b); + b = z; } - else { + else Py_INCREF(b); - maskb = 0; + + /* Swap a and b if necessary to ensure size_a >= size_b. */ + if (size_a < size_b) { + z = a; a = b; b = z; + size_z = size_a; size_a = size_b; size_b = size_z; + negz = nega; nega = negb; negb = negz; } - negz = 0; + /* JRH: The original logic here was to allocate the result value (z) + as the longer of the two operands. However, there are some cases + where the result is guaranteed to be shorter than that: AND of two + positives, OR of two negatives: use the shorter number. AND with + mixed signs: use the positive number. OR with mixed signs: use the + negative number. + */ switch (op) { case '^': - if (maska != maskb) { - maska ^= PyLong_MASK; - negz = -1; - } + negz = nega ^ negb; + size_z = size_a; break; case '&': - if (maska && maskb) { - op = '|'; - maska ^= PyLong_MASK; - maskb ^= PyLong_MASK; - negz = -1; - } + negz = nega & negb; + size_z = negb ? size_a : size_b; break; case '|': - if (maska || maskb) { - op = '&'; - maska ^= PyLong_MASK; - maskb ^= PyLong_MASK; - negz = -1; - } + negz = nega | negb; + size_z = negb ? size_b : size_a; break; + default: + PyErr_BadArgument(); + return NULL; } - /* JRH: The original logic here was to allocate the result value (z) - as the longer of the two operands. However, there are some cases - where the result is guaranteed to be shorter than that: AND of two - positives, OR of two negatives: use the shorter number. AND with - mixed signs: use the positive number. OR with mixed signs: use the - negative number. After the transformations above, op will be '&' - iff one of these cases applies, and mask will be non-0 for operands - whose length should be ignored. - */ - - size_a = Py_SIZE(a); - size_b = Py_SIZE(b); - size_z = op == '&' - ? (maska - ? size_b - : (maskb ? size_a : MIN(size_a, size_b))) - : MAX(size_a, size_b); - z = _PyLong_New(size_z); + /* We allow an extra digit if z is negative, to make sure that + the final two's complement of z doesn't overflow. */ + z = _PyLong_New(size_z + negz); if (z == NULL) { Py_DECREF(a); Py_DECREF(b); return NULL; } - for (i = 0; i < size_z; ++i) { - diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska; - digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb; - switch (op) { - case '&': z->ob_digit[i] = diga & digb; break; - case '|': z->ob_digit[i] = diga | digb; break; - case '^': z->ob_digit[i] = diga ^ digb; break; - } + /* Compute digits for overlap of a and b. */ + switch(op) { + case '&': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + break; + case '|': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + break; + case '^': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + break; + default: + PyErr_BadArgument(); + return NULL; + } + + /* Copy any remaining digits of a, inverting if necessary. */ + if (op == '^' && negb) + for (; i < size_z; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + else if (i < size_z) + memcpy(&z->ob_digit[i], &a->ob_digit[i], + (size_z-i)*sizeof(digit)); + + /* Complement result if negative. */ + if (negz) { + Py_SIZE(z) = -(Py_SIZE(z)); + z->ob_digit[size_z] = PyLong_MASK; + v_complement(z->ob_digit, z->ob_digit, size_z+1); } Py_DECREF(a); Py_DECREF(b); - z = long_normalize(z); - if (negz == 0) - return (PyObject *) maybe_small_long(z); - v = long_invert(z); - Py_DECREF(z); - return v; + return (PyObject *)maybe_small_long(long_normalize(z)); } static PyObject * -- cgit v1.2.1 From d753ed5d9807f77348476ce08b17009788d1d2ee Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 26 Oct 2009 21:12:50 +0000 Subject: Fix extra-long line; also makes py3k match trunk here. --- Objects/floatobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 20fe956f5e..ff5c0f6a69 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -183,7 +183,7 @@ PyFloat_FromString(PyObject *v) } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, - "float() argument must be a string or a number"); + "float() argument must be a string or a number"); return NULL; } last = s + len; -- cgit v1.2.1 From 8dfb62c96bed12fbdbcf92396a1a9a9b887bd48a Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 26 Oct 2009 21:51:18 +0000 Subject: Remove length limitation on string arguments to complex() --- Objects/complexobject.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index ccee38229c..b541308ae3 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -740,20 +740,20 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) char *end; double x=0.0, y=0.0, z; int got_bracket=0; - char s_buffer[256]; + char *s_buffer = NULL; Py_ssize_t len; if (PyUnicode_Check(v)) { - if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) { - PyErr_SetString(PyExc_ValueError, - "complex() literal too large to convert"); - return NULL; - } + 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)) + NULL)) { + PyMem_FREE(s_buffer); return NULL; + } s = s_buffer; len = strlen(s); } @@ -870,9 +870,13 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s-start != len) goto parse_error; + if (s_buffer) + PyMem_FREE(s_buffer); return complex_subtype_from_doubles(type, x, y); parse_error: + if (s_buffer) + PyMem_FREE(s_buffer); PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); return NULL; -- cgit v1.2.1 From e2e528b7ea61a96f6df252bcd70964932c394be0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 26 Oct 2009 22:05:06 +0000 Subject: Make sure memory is freed on error in complex_subtype_from_string. --- Objects/complexobject.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index b541308ae3..e5e07c1b6a 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -750,10 +750,8 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), s_buffer, - NULL)) { - PyMem_FREE(s_buffer); - return NULL; - } + NULL)) + goto error; s = s_buffer; len = strlen(s); } @@ -802,7 +800,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else - return NULL; + goto error; } if (end != s) { /* all 4 forms starting with land here */ @@ -815,7 +813,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else - return NULL; + goto error; } if (end != s) /* j */ @@ -875,10 +873,11 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) return complex_subtype_from_doubles(type, x, y); parse_error: - if (s_buffer) - PyMem_FREE(s_buffer); PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); + error: + if (s_buffer) + PyMem_FREE(s_buffer); return NULL; } -- cgit v1.2.1 From 40811947740e2d3c4cde019e304f5cf85c940f8a Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 27 Oct 2009 15:28:25 +0000 Subject: Merged revisions 75365,75394,75402-75403,75418,75459,75484,75592-75596,75600,75602-75607,75610-75613,75616-75617,75623,75627,75640,75647,75696,75795 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75365 | georg.brandl | 2009-10-11 22:16:16 +0200 (So, 11 Okt 2009) | 1 line Fix broken links found by "make linkcheck". scipy.org seems to be done right now, so I could not verify links going there. ........ r75394 | georg.brandl | 2009-10-13 20:10:59 +0200 (Di, 13 Okt 2009) | 1 line Fix markup. ........ r75402 | georg.brandl | 2009-10-14 17:51:48 +0200 (Mi, 14 Okt 2009) | 1 line #7125: fix typo. ........ r75403 | georg.brandl | 2009-10-14 17:57:46 +0200 (Mi, 14 Okt 2009) | 1 line #7126: os.environ changes *do* take effect in subprocesses started with os.system(). ........ r75418 | georg.brandl | 2009-10-14 20:48:32 +0200 (Mi, 14 Okt 2009) | 1 line #7116: str.join() takes an iterable. ........ r75459 | georg.brandl | 2009-10-17 10:57:43 +0200 (Sa, 17 Okt 2009) | 1 line Fix refleaks in _ctypes PyCSimpleType_New, which fixes the refleak seen in test___all__. ........ r75484 | georg.brandl | 2009-10-18 09:58:12 +0200 (So, 18 Okt 2009) | 1 line Fix missing word. ........ r75592 | georg.brandl | 2009-10-22 09:05:48 +0200 (Do, 22 Okt 2009) | 1 line Fix punctuation. ........ r75593 | georg.brandl | 2009-10-22 09:06:49 +0200 (Do, 22 Okt 2009) | 1 line Revert unintended change. ........ r75594 | georg.brandl | 2009-10-22 09:56:02 +0200 (Do, 22 Okt 2009) | 1 line Fix markup. ........ r75595 | georg.brandl | 2009-10-22 09:56:56 +0200 (Do, 22 Okt 2009) | 1 line Fix duplicate target. ........ r75596 | georg.brandl | 2009-10-22 10:05:04 +0200 (Do, 22 Okt 2009) | 1 line Add a new directive marking up implementation details and start using it. ........ r75600 | georg.brandl | 2009-10-22 13:01:46 +0200 (Do, 22 Okt 2009) | 1 line Make it more robust. ........ r75602 | georg.brandl | 2009-10-22 13:28:06 +0200 (Do, 22 Okt 2009) | 1 line Document new directive. ........ r75603 | georg.brandl | 2009-10-22 13:28:23 +0200 (Do, 22 Okt 2009) | 1 line Allow short form with text as argument. ........ r75604 | georg.brandl | 2009-10-22 13:36:50 +0200 (Do, 22 Okt 2009) | 1 line Fix stylesheet for multi-paragraph impl-details. ........ r75605 | georg.brandl | 2009-10-22 13:48:10 +0200 (Do, 22 Okt 2009) | 1 line Use "impl-detail" directive where applicable. ........ r75606 | georg.brandl | 2009-10-22 17:00:06 +0200 (Do, 22 Okt 2009) | 1 line #6324: membership test tries iteration via __iter__. ........ r75607 | georg.brandl | 2009-10-22 17:04:09 +0200 (Do, 22 Okt 2009) | 1 line #7088: document new functions in signal as Unix-only. ........ r75610 | georg.brandl | 2009-10-22 17:27:24 +0200 (Do, 22 Okt 2009) | 1 line Reorder __slots__ fine print and add a clarification. ........ r75611 | georg.brandl | 2009-10-22 17:42:32 +0200 (Do, 22 Okt 2009) | 1 line #7035: improve docs of the various _errors() functions, and give them docstrings. ........ r75612 | georg.brandl | 2009-10-22 17:52:15 +0200 (Do, 22 Okt 2009) | 1 line #7156: document curses as Unix-only. ........ r75613 | georg.brandl | 2009-10-22 17:54:35 +0200 (Do, 22 Okt 2009) | 1 line #6977: getopt does not support optional option arguments. ........ r75616 | georg.brandl | 2009-10-22 18:17:05 +0200 (Do, 22 Okt 2009) | 1 line Add proper references. ........ r75617 | georg.brandl | 2009-10-22 18:20:55 +0200 (Do, 22 Okt 2009) | 1 line Make printout margin important. ........ r75623 | georg.brandl | 2009-10-23 10:14:44 +0200 (Fr, 23 Okt 2009) | 1 line #7188: fix optionxform() docs. ........ r75627 | fred.drake | 2009-10-23 15:04:51 +0200 (Fr, 23 Okt 2009) | 2 lines add further note about what's passed to optionxform ........ r75640 | neil.schemenauer | 2009-10-23 21:58:17 +0200 (Fr, 23 Okt 2009) | 2 lines Improve some docstrings in the 'warnings' module. ........ r75647 | georg.brandl | 2009-10-24 12:04:19 +0200 (Sa, 24 Okt 2009) | 1 line Fix markup. ........ r75696 | georg.brandl | 2009-10-25 21:25:43 +0100 (So, 25 Okt 2009) | 1 line Fix a demo. ........ r75795 | georg.brandl | 2009-10-27 16:10:22 +0100 (Di, 27 Okt 2009) | 1 line Fix a strange mis-edit. ........ --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 767bed0776..c9808e1cc6 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7710,10 +7710,10 @@ unicode_isprintable(PyObject *self) } PyDoc_STRVAR(join__doc__, - "S.join(sequence) -> str\n\ + "S.join(iterable) -> str\n\ \n\ Return a string which is the concatenation of the strings in the\n\ -sequence. The separator between elements is S."); +iterable. The separator between elements is S."); static PyObject* unicode_join(PyObject *self, PyObject *data) -- cgit v1.2.1 From 26a4de345259275b630e67d752142a36fe834406 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 10 Nov 2009 19:50:40 +0000 Subject: Merge in the new GIL. --- Objects/longobject.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index ba869701c7..4d71ea2ce3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -96,10 +96,7 @@ maybe_small_long(PyLongObject *v) #define MIN(x, y) ((x) > (y) ? (y) : (x)) #define SIGCHECK(PyTryBlock) \ - if (--_Py_Ticker < 0) { \ - _Py_Ticker = _Py_CheckInterval; \ - if (PyErr_CheckSignals()) PyTryBlock \ - } + if (PyErr_CheckSignals()) PyTryBlock \ /* forward declaration */ static int bits_in_digit(digit d); -- cgit v1.2.1 From 87fe9ba82a0235dc2ade5e81ea9840bb1d969379 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 10 Nov 2009 21:23:15 +0000 Subject: death to compiler warning --- Objects/unicodeobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c9808e1cc6..cdb739a3d5 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2513,7 +2513,9 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s, *p++ = (char)(0x80 | (ch & 0x3f)); continue; } +#ifndef Py_UNICODE_WIDE encodeUCS4: +#endif /* Encode UCS4 Unicode ordinals */ *p++ = (char)(0xf0 | (ch >> 18)); *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); -- cgit v1.2.1 From 06bdc04829b15070dcfb088db2b1d3ad2611dfe6 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 13 Nov 2009 02:25:08 +0000 Subject: Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75149 | gregory.p.smith | 2009-09-29 16:56:31 -0500 (Tue, 29 Sep 2009) | 3 lines Mention issue6972 in extractall docs about overwriting things outside of the supplied path. ........ r75260 | andrew.kuchling | 2009-10-05 16:24:20 -0500 (Mon, 05 Oct 2009) | 1 line Wording fix ........ r75261 | andrew.kuchling | 2009-10-05 16:24:35 -0500 (Mon, 05 Oct 2009) | 1 line Fix narkup ........ r75262 | andrew.kuchling | 2009-10-05 16:25:03 -0500 (Mon, 05 Oct 2009) | 1 line Document 'skip' parameter to constructor ........ r75263 | andrew.kuchling | 2009-10-05 16:25:35 -0500 (Mon, 05 Oct 2009) | 1 line Note side benefit of socket.create_connection() ........ r75265 | andrew.kuchling | 2009-10-05 17:31:11 -0500 (Mon, 05 Oct 2009) | 1 line Reword sentence ........ r75266 | andrew.kuchling | 2009-10-05 17:32:48 -0500 (Mon, 05 Oct 2009) | 1 line Use standard comma punctuation; reword some sentences in the docs ........ r75267 | andrew.kuchling | 2009-10-05 17:42:56 -0500 (Mon, 05 Oct 2009) | 1 line Backport r73983: Document the thousands separator. ........ r75292 | benjamin.peterson | 2009-10-08 22:11:36 -0500 (Thu, 08 Oct 2009) | 1 line death to old CVS keyword ........ r75300 | benjamin.peterson | 2009-10-09 16:48:14 -0500 (Fri, 09 Oct 2009) | 1 line fix some coding style ........ r75376 | benjamin.peterson | 2009-10-11 20:26:07 -0500 (Sun, 11 Oct 2009) | 1 line platform we don't care about ........ r75405 | neil.schemenauer | 2009-10-14 12:17:14 -0500 (Wed, 14 Oct 2009) | 4 lines Issue #1754094: Improve the stack depth calculation in the compiler. There should be no other effect than a small decrease in memory use. Patch by Christopher Tur Lesniewski-Laas. ........ r75429 | benjamin.peterson | 2009-10-14 20:47:28 -0500 (Wed, 14 Oct 2009) | 1 line pep8ify if blocks ........ r75430 | benjamin.peterson | 2009-10-14 20:49:37 -0500 (Wed, 14 Oct 2009) | 1 line use floor division and add a test that exercises the tabsize codepath ........ r75431 | benjamin.peterson | 2009-10-14 20:56:25 -0500 (Wed, 14 Oct 2009) | 1 line change test to what I intended ........ r75432 | benjamin.peterson | 2009-10-14 22:05:39 -0500 (Wed, 14 Oct 2009) | 1 line some cleanups ........ r75433 | benjamin.peterson | 2009-10-14 22:06:55 -0500 (Wed, 14 Oct 2009) | 1 line make inspect.isabstract() always return a boolean; add a test for it, too #7069 ........ r75437 | benjamin.peterson | 2009-10-15 10:44:46 -0500 (Thu, 15 Oct 2009) | 1 line only clear a module's __dict__ if the module is the only one with a reference to it #7140 ........ r75445 | vinay.sajip | 2009-10-16 09:06:44 -0500 (Fri, 16 Oct 2009) | 1 line Issue #7120: logging: Removed import of multiprocessing which is causing crash in GAE. ........ r75501 | antoine.pitrou | 2009-10-18 13:37:11 -0500 (Sun, 18 Oct 2009) | 3 lines Add a comment about unreachable code, and fix a typo ........ r75551 | benjamin.peterson | 2009-10-19 22:14:10 -0500 (Mon, 19 Oct 2009) | 1 line use property api ........ r75572 | benjamin.peterson | 2009-10-20 16:55:17 -0500 (Tue, 20 Oct 2009) | 1 line clarify buffer arg #7178 ........ r75589 | benjamin.peterson | 2009-10-21 21:26:47 -0500 (Wed, 21 Oct 2009) | 1 line whitespace ........ r75590 | benjamin.peterson | 2009-10-21 21:36:47 -0500 (Wed, 21 Oct 2009) | 1 line rewrite to be nice to other implementations ........ r75591 | benjamin.peterson | 2009-10-21 21:50:38 -0500 (Wed, 21 Oct 2009) | 4 lines rewrite for style, clarify, and comments Also, use the hasattr() like scheme of allowing BaseException exceptions through. ........ r75657 | antoine.pitrou | 2009-10-24 07:41:27 -0500 (Sat, 24 Oct 2009) | 3 lines Fix compilation error in debug mode. ........ r75742 | benjamin.peterson | 2009-10-26 17:51:16 -0500 (Mon, 26 Oct 2009) | 1 line use 'is' instead of id() ........ r75868 | benjamin.peterson | 2009-10-27 15:59:18 -0500 (Tue, 27 Oct 2009) | 1 line test expect base classes ........ r75952 | georg.brandl | 2009-10-29 15:38:32 -0500 (Thu, 29 Oct 2009) | 1 line Use the correct function name in docstring. ........ r75953 | georg.brandl | 2009-10-29 15:39:50 -0500 (Thu, 29 Oct 2009) | 1 line Remove mention of the old -X command line switch. ........ r75954 | georg.brandl | 2009-10-29 15:53:00 -0500 (Thu, 29 Oct 2009) | 1 line Use constants instead of magic integers for test result. Do not re-run with --verbose3 for environment changing tests. ........ r75955 | georg.brandl | 2009-10-29 15:54:03 -0500 (Thu, 29 Oct 2009) | 1 line Use a single style for all the docstrings in the math module. ........ r75956 | georg.brandl | 2009-10-29 16:16:34 -0500 (Thu, 29 Oct 2009) | 1 line I do not think the "railroad" program mentioned is still available. ........ r75957 | georg.brandl | 2009-10-29 16:44:56 -0500 (Thu, 29 Oct 2009) | 1 line Fix constant name. ........ r76057 | benjamin.peterson | 2009-11-02 09:06:45 -0600 (Mon, 02 Nov 2009) | 1 line prevent a rather unlikely segfault ........ r76105 | georg.brandl | 2009-11-04 01:38:12 -0600 (Wed, 04 Nov 2009) | 1 line #7259: show correct equivalent for operator.i* operations in docstring; fix minor issues in operator docs. ........ r76139 | benjamin.peterson | 2009-11-06 19:04:38 -0600 (Fri, 06 Nov 2009) | 1 line spelling ........ r76143 | georg.brandl | 2009-11-07 02:26:07 -0600 (Sat, 07 Nov 2009) | 1 line #7271: fix typo. ........ r76162 | benjamin.peterson | 2009-11-08 22:10:53 -0600 (Sun, 08 Nov 2009) | 1 line discuss how to use -p ........ r76223 | georg.brandl | 2009-11-12 02:29:46 -0600 (Thu, 12 Nov 2009) | 1 line Give the profile module a module directive. ........ --- Objects/descrobject.c | 29 ++++++++++++++++------------- Objects/listobject.c | 10 ++++++++-- Objects/moduleobject.c | 5 ++++- 3 files changed, 28 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index a254339e48..a09e0e2068 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1293,26 +1293,29 @@ property_init(PyObject *self, PyObject *args, PyObject *kwds) /* 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 != NULL) { - /* get_doc already INCREF'd by GetAttr */ - if (Py_TYPE(self)==&PyProperty_Type) { + if (get_doc) { + if (Py_TYPE(self) == &PyProperty_Type) { Py_XDECREF(prop->prop_doc); prop->prop_doc = get_doc; - } else { - /* Put __doc__ in dict of the subclass instance instead, - otherwise it gets shadowed by class's __doc__. */ - if (PyObject_SetAttrString(self, "__doc__", get_doc) != 0) - { - /* DECREF for props handled by _dealloc */ - Py_DECREF(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; - } - Py_DECREF(get_doc); } prop->getter_doc = 1; - } else { + } + else if (PyErr_ExceptionMatches(PyExc_Exception)) { PyErr_Clear(); } + else { + return -1; + } } return 0; diff --git a/Objects/listobject.c b/Objects/listobject.c index 2bab4ef26b..09fba48f6d 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -183,9 +183,12 @@ PyList_GetItem(PyObject *op, Py_ssize_t i) return NULL; } if (i < 0 || i >= Py_SIZE(op)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } @@ -406,9 +409,12 @@ static PyObject * list_item(PyListObject *a, Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 11dd43d23c..c1dd228abf 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -312,7 +312,10 @@ module_dealloc(PyModuleObject *m) if (m->md_def && m->md_def->m_free) m->md_def->m_free(m); if (m->md_dict != NULL) { - _PyModule_Clear((PyObject *)m); + /* If we are the only ones holding a reference, we can clear + the dictionary. */ + if (Py_REFCNT(m->md_dict) == 1) + _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } if (m->md_state != NULL) -- cgit v1.2.1 From 35bd50b1f6866f909c125ee745c623da97cf065f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 15 Nov 2009 09:57:26 +0000 Subject: Issue #7298: Fix a variety of problems leading to wrong results with the fast versions of range.__reversed__ and range iteration. Also fix wrong results and a refleak for PyLong version of range.__reversed__. Thanks Eric Smith for reviewing, and for suggesting improved tests. --- Objects/rangeobject.c | 193 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 55 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index beff030eba..c5885f5942 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -488,16 +488,15 @@ PyTypeObject PyRangeIter_Type = { rangeiter_new, /* tp_new */ }; -/* Return number of items in range (lo, hi, step). step > 0 - * required. Return a value < 0 if & only if the true value is too - * large to fit in a signed long. +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. */ -static long +static unsigned long get_len_of_range(long lo, long hi, long step) { /* ------------------------------------------------------------- - If lo >= hi, the range is empty. - Else if n values are in the range, the last one is + 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 @@ -505,30 +504,37 @@ get_len_of_range(long lo, long hi, long step) 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. + precision to compute the RHS exactly. The analysis for step < 0 + is similar. ---------------------------------------------------------------*/ - long n = 0; - if (lo < hi) { - unsigned long uhi = (unsigned long)hi; - unsigned long ulo = (unsigned long)lo; - unsigned long diff = uhi - ulo - 1; - n = (long)(diff / (unsigned long)step + 1); - } - return n; + 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; } +/* Initialize a rangeiter object. If the length of the rangeiter object + is not representable as a C long, OverflowError is raised. */ + static PyObject * int_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + unsigned long ulen; if (it == NULL) return NULL; it->start = start; it->step = step; - if (step > 0) - it->len = get_len_of_range(start, stop, step); - else - it->len = get_len_of_range(stop, start, -step); + ulen = get_len_of_range(start, stop, step); + if (ulen > (unsigned long)LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "range too large to represent as a range_iterator"); + return NULL; + } + it->len = (long)ulen; it->index = 0; return (PyObject *)it; } @@ -637,23 +643,53 @@ range_iter(PyObject *seq) rangeobject *r = (rangeobject *)seq; longrangeiterobject *it; long lstart, lstop, lstep; + PyObject *int_it; assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* If all three fields and the length convert to long, use the int + * version */ lstart = PyLong_AsLong(r->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(r->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(r->step); - if (lstep != -1 || !PyErr_Occurred()) - return int_range_iter(lstart, lstop, lstep); - } + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(r->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(r->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; } - /* Some conversion failed, so there is an error set. Clear it, - and try again with a long range. */ - PyErr_Clear(); + /* round lstop to the next value congruent to lstart modulo lstep; + if the result would overflow, use PyLong version. */ + if (lstep > 0 && lstart < lstop) { + long extra = (lstep - 1) - (long)((lstop - 1UL - lstart) % lstep); + if ((unsigned long)extra > (unsigned long)LONG_MAX - lstop) + goto long_range; + lstop += extra; + } + else if (lstep < 0 && lstart > lstop) { + long extra = (lstep + 1) + (long)((lstart - 1UL - lstop) % + (0UL - lstep)); + if ((unsigned long)lstop - LONG_MIN < 0UL - extra) + goto long_range; + lstop += extra; + } + else + lstop = lstart; + + int_it = int_range_iter(lstart, lstop, lstep); + if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + goto long_range; + } + return (PyObject *)int_it; + long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -686,34 +722,80 @@ range_reverse(PyObject *seq) rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; PyObject *one, *sum, *diff, *len = NULL, *product; - long lstart, lstop, lstep; + long lstart, lstop, lstep, new_start, new_stop; + unsigned long ulen; - /* XXX(nnorwitz): do the calc for the new start/stop first, - then if they fit, call the proper iter()? - */ assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* reversed(range(start, stop, step)) can be expressed as + range(start+(n-1)*step, start-step, -step), where n is the number of + integers in the range. + + If each of start, stop, step, -step, start-step, and the length + of the iterator is representable as a C long, use the int + version. This excludes some cases where the reversed range is + representable as a range_iterator, but it's good enough for + common cases and it makes the checks simple. */ + lstart = PyLong_AsLong(range->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(range->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(range->step); - if (lstep != -1 || !PyErr_Occurred()) { - /* XXX(nnorwitz): need to check for overflow and simplify. */ - long len = get_len_of_range(lstart, lstop, lstep); - long new_start = lstart + (len - 1) * lstep; - long new_stop = lstart; - if (lstep > 0) - new_stop -= 1; - else - new_stop += 1; - return int_range_iter(new_start, new_stop, -lstep); - } - } + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; } - PyErr_Clear(); + lstop = PyLong_AsLong(range->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(range->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + /* check for possible overflow of -lstep */ + if (lstep == LONG_MIN) + goto long_range; + + /* check for overflow of lstart - lstep: + + for lstep > 0, need only check whether lstart - lstep < LONG_MIN. + for lstep < 0, need only check whether lstart - lstep > LONG_MAX + Rearrange these inequalities as: + + lstart - LONG_MIN < lstep (lstep > 0) + LONG_MAX - lstart < -lstep (lstep < 0) + + and compute both sides as unsigned longs, to avoid the + possibility of undefined behaviour due to signed overflow. */ + + if (lstep > 0) { + if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep) + goto long_range; + } + else { + if (LONG_MAX - (unsigned long)lstart < 0UL - lstep) + goto long_range; + } + + /* set lstop equal to the last element of the range, or to lstart if the + range is empty. */ + if (lstep > 0 && lstart < lstop) + lstop += -1 - (long)((lstop - 1UL - lstart) % lstep); + else if (lstep < 0 && lstart > lstop) + lstop += 1 + (long)((lstart - 1UL - lstop) % (0UL - lstep)); + else + lstop = lstart; + + ulen = get_len_of_range(lstart, lstop, lstep); + if (ulen > (unsigned long)LONG_MAX) + goto long_range; + + new_stop = lstart - lstep; + new_start = (long)(new_stop + ulen * lstep); + return int_range_iter(new_start, new_stop, -lstep); + +long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -732,7 +814,8 @@ range_reverse(PyObject *seq) if (!diff) goto create_failure; - product = PyNumber_Multiply(len, range->step); + product = PyNumber_Multiply(diff, range->step); + Py_DECREF(diff); if (!product) goto create_failure; @@ -741,11 +824,11 @@ range_reverse(PyObject *seq) it->start = sum; if (!it->start) goto create_failure; + it->step = PyNumber_Negative(range->step); if (!it->step) { Py_DECREF(it->start); - PyObject_Del(it); - return NULL; + goto create_failure; } /* Steal reference to len. */ -- cgit v1.2.1 From 5002146f08e3852c553ed818f4aa5e9534df9365 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 15 Nov 2009 10:04:50 +0000 Subject: r76292 commit accidentally committed some extra code; remove it --- Objects/rangeobject.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index c5885f5942..cabe785256 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -664,24 +664,6 @@ range_iter(PyObject *seq) PyErr_Clear(); goto long_range; } - /* round lstop to the next value congruent to lstart modulo lstep; - if the result would overflow, use PyLong version. */ - if (lstep > 0 && lstart < lstop) { - long extra = (lstep - 1) - (long)((lstop - 1UL - lstart) % lstep); - if ((unsigned long)extra > (unsigned long)LONG_MAX - lstop) - goto long_range; - lstop += extra; - } - else if (lstep < 0 && lstart > lstop) { - long extra = (lstep + 1) + (long)((lstart - 1UL - lstop) % - (0UL - lstep)); - if ((unsigned long)lstop - LONG_MIN < 0UL - extra) - goto long_range; - lstop += extra; - } - else - lstop = lstart; - int_it = int_range_iter(lstart, lstop, lstep); if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); @@ -778,15 +760,6 @@ range_reverse(PyObject *seq) goto long_range; } - /* set lstop equal to the last element of the range, or to lstart if the - range is empty. */ - if (lstep > 0 && lstart < lstop) - lstop += -1 - (long)((lstop - 1UL - lstart) % lstep); - else if (lstep < 0 && lstart > lstop) - lstop += 1 + (long)((lstart - 1UL - lstop) % (0UL - lstep)); - else - lstop = lstart; - ulen = get_len_of_range(lstart, lstop, lstep); if (ulen > (unsigned long)LONG_MAX) goto long_range; -- cgit v1.2.1 From 06329b32fb71019edafece7f25a8f5dca1760685 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 15 Nov 2009 12:56:08 +0000 Subject: Fix another case of potential signed overflow. --- Objects/rangeobject.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index cabe785256..ec75c8fcfe 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -411,7 +411,10 @@ static PyObject * rangeiter_next(rangeiterobject *r) { if (r->index < r->len) - return PyLong_FromLong(r->start + (r->index++) * r->step); + /* cast to unsigned to avoid possible signed overflow + in intermediate calculations. */ + return PyLong_FromLong((long)(r->start + + (unsigned long)(r->index++) * r->step)); return NULL; } -- cgit v1.2.1 From c99fc4b163c1bf5e86e4d8a26c14841cda8746bb Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 15 Nov 2009 13:58:49 +0000 Subject: Issue #6970: Remove redundant calls made when comparing objects. --- Objects/object.c | 4 +++- Objects/typeobject.c | 24 +----------------------- 2 files changed, 4 insertions(+), 24 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 90cdc74195..002acd04be 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -544,10 +544,12 @@ do_richcompare(PyObject *v, PyObject *w, int op) { richcmpfunc f; PyObject *res; + int checked_reverse_op = 0; if (v->ob_type != w->ob_type && PyType_IsSubtype(w->ob_type, v->ob_type) && (f = w->ob_type->tp_richcompare) != NULL) { + checked_reverse_op = 1; res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; @@ -559,7 +561,7 @@ do_richcompare(PyObject *v, PyObject *w, int op) return res; Py_DECREF(res); } - if ((f = w->ob_type->tp_richcompare) != NULL) { + if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 24866ff465..be4b6f861e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5068,7 +5068,7 @@ static char *name_op[] = { }; static PyObject * -half_richcompare(PyObject *self, PyObject *other, int op) +slot_tp_richcompare(PyObject *self, PyObject *other, int op) { PyObject *func, *args, *res; static PyObject *op_str[6]; @@ -5090,28 +5090,6 @@ half_richcompare(PyObject *self, PyObject *other, int op) 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) { -- cgit v1.2.1 From 62967533f9e410f0d0793c39b710e9e148486325 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 16 Nov 2009 00:34:25 +0000 Subject: fix one visible and several possible refleaks in rangeobject.c In some cases, the code was just reordered to allow for less decrefing. --- Objects/rangeobject.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index ec75c8fcfe..cd148c6667 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -533,6 +533,7 @@ int_range_iter(long start, long stop, long step) it->step = step; ulen = get_len_of_range(start, stop, step); if (ulen > (unsigned long)LONG_MAX) { + Py_DECREF(it); PyErr_SetString(PyExc_OverflowError, "range too large to represent as a range_iterator"); return NULL; @@ -584,16 +585,14 @@ longrangeiter_next(longrangeiterobject *r) if (!one) return NULL; - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(one); - return NULL; - } - new_index = PyNumber_Add(r->index, one); Py_DECREF(one); - if (!new_index) { - Py_DECREF(product); + if (!new_index) + return NULL; + + product = PyNumber_Multiply(r->index, r->step); + if (!product) { + Py_DECREF(new_index); return NULL; } @@ -603,6 +602,9 @@ longrangeiter_next(longrangeiterobject *r) Py_DECREF(r->index); r->index = new_index; } + else { + Py_DECREF(new_index); + } return result; } @@ -781,6 +783,9 @@ long_range: if (!len) goto create_failure; + /* Steal reference to len. */ + it->len = len; + one = PyLong_FromLong(1); if (!one) goto create_failure; @@ -802,24 +807,16 @@ long_range: goto create_failure; it->step = PyNumber_Negative(range->step); - if (!it->step) { - Py_DECREF(it->start); + if (!it->step) goto create_failure; - } - - /* Steal reference to len. */ - it->len = len; it->index = PyLong_FromLong(0); - if (!it->index) { - Py_DECREF(it); - return NULL; - } + if (!it->index) + goto create_failure; return (PyObject *)it; create_failure: - Py_XDECREF(len); - PyObject_Del(it); + Py_DECREF(it); return NULL; } -- cgit v1.2.1 From 59a800c448a4fc4fb370ab3bc03c6402a5817d66 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 16 Nov 2009 17:00:11 +0000 Subject: Merged revisions 76308 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76308 | mark.dickinson | 2009-11-15 16:18:58 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString, PyFormat_FromStringV and PyErr_Format. ........ --- Objects/unicodeobject.c | 113 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 23 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index cdb739a3d5..9c0be9b23c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -667,7 +667,8 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w, #undef CONVERT_WCHAR_TO_SURROGATES static void -makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c) +makefmt(char *fmt, int longflag, int longlongflag, int size_tflag, + int zeropad, int width, int precision, char c) { *fmt++ = '%'; if (width) { @@ -679,6 +680,19 @@ makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int pre fmt += sprintf(fmt, ".%d", precision); if (longflag) *fmt++ = 'l'; + else if (longlongflag) { + /* longlongflag should only ever be nonzero on machines with + HAVE_LONG_LONG defined */ +#ifdef HAVE_LONG_LONG + char *f = PY_FORMAT_LONG_LONG; + while (*f) + *fmt++ = *f++; +#else + /* we shouldn't ever get here */ + assert(0); + *fmt++ = 'l'; +#endif + } else if (size_tflag) { char *f = PY_FORMAT_SIZE_T; while (*f) @@ -690,6 +704,16 @@ makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int pre #define appendstring(string) {for (copy = string;*copy;) *s++ = *copy++;} +/* size of fixed-size buffer for formatting single arguments */ +#define ITEM_BUFFER_LEN 21 +/* maximum number of characters required for output of %ld. 21 characters + allows for 64-bit integers (in decimal) and an optional sign. */ +#define MAX_LONG_CHARS 21 +/* maximum number of characters required for output of %lld. + We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, + plus 1 for the sign. 53/22 is an upper bound for log10(256). */ +#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) + PyObject * PyUnicode_FromFormatV(const char *format, va_list vargs) { @@ -705,13 +729,13 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) Py_UNICODE *s; PyObject *string; /* used by sprintf */ - char buffer[21]; + char buffer[ITEM_BUFFER_LEN+1]; /* 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 */ + char fmt[61]; /* should be enough for %0width.precisionlld */ const char *copy; #ifdef VA_LIST_IS_ARRAY @@ -754,6 +778,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) /* step 3: 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; width = 0; while (ISDIGIT((unsigned)*f)) @@ -764,9 +791,21 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) /* 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')) + 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': @@ -777,14 +816,21 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) break; case 'd': case 'u': case 'i': case 'x': (void) va_arg(count, int); - /* 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; +#ifdef HAVE_LONG_LONG + if (longlongflag) { + if (width < MAX_LONG_LONG_CHARS) + width = MAX_LONG_LONG_CHARS; + } + else +#endif + /* MAX_LONG_CHARS is enough to hold a 64-bit integer, + including sign. 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 < MAX_LONG_CHARS) + width = MAX_LONG_CHARS; n += width; + /* XXX should allow for large precision here too. */ if (abuffersize < width) abuffersize = width; break; @@ -881,8 +927,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) n++; } expand: - if (abuffersize > 20) { - abuffer = PyObject_Malloc(abuffersize); + if (abuffersize > ITEM_BUFFER_LEN) { + /* add 1 for sprintf's trailing null byte */ + abuffer = PyObject_Malloc(abuffersize + 1); if (!abuffer) { PyErr_NoMemory(); goto fail; @@ -906,6 +953,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) if (*f == '%') { const char* p = f++; int longflag = 0; + int longlongflag = 0; int size_tflag = 0; zeropad = (*f == '0'); /* parse the width.precision part */ @@ -918,11 +966,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) 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 %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. */ if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { @@ -935,9 +991,14 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) *s++ = va_arg(vargs, int); break; case 'd': - makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'd'); + makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, + width, precision, 'd'); if (longflag) sprintf(realbuffer, fmt, va_arg(vargs, long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(realbuffer, fmt, va_arg(vargs, PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(realbuffer, fmt, va_arg(vargs, Py_ssize_t)); else @@ -945,9 +1006,15 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) appendstring(realbuffer); break; case 'u': - makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'u'); + makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, + width, precision, 'u'); if (longflag) sprintf(realbuffer, fmt, va_arg(vargs, unsigned long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(realbuffer, fmt, va_arg(vargs, + unsigned PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(realbuffer, fmt, va_arg(vargs, size_t)); else @@ -955,12 +1022,12 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) appendstring(realbuffer); break; case 'i': - makefmt(fmt, 0, 0, zeropad, width, precision, 'i'); + makefmt(fmt, 0, 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'); + makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x'); sprintf(realbuffer, fmt, va_arg(vargs, int)); appendstring(realbuffer); break; -- cgit v1.2.1 From f1d22a195d0fbb33aa042ae4d9bcc9fd9d3c2d39 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 19 Nov 2009 03:08:32 +0000 Subject: fix __bytes__ handling here in py3x Merged revisions 76395 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76395 | benjamin.peterson | 2009-11-18 21:00:02 -0600 (Wed, 18 Nov 2009) | 1 line #5037 proxy __unicode__ correctly ........ --- Objects/weakrefobject.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'Objects') diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 214dd95da7..27f015d3a0 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -435,6 +435,13 @@ proxy_checkref(PyWeakReference *proxy) return generic(proxy, v, w); \ } +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } + /* direct slots */ @@ -576,6 +583,15 @@ proxy_iternext(PyWeakReference *proxy) } +WRAP_METHOD(proxy_bytes, "__bytes__"); + + +static PyMethodDef proxy_methods[] = { + {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, + {NULL, NULL} +}; + + static PyNumberMethods proxy_as_number = { proxy_add, /*nb_add*/ proxy_sub, /*nb_subtract*/ @@ -661,6 +677,7 @@ _PyWeakref_ProxyType = { 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ }; -- cgit v1.2.1 From 7e20442f707b90d4d2eb0b47eabe9b29b923103e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 25 Nov 2009 17:46:26 +0000 Subject: Merged revisions 75264,75268,75293,75318,75391-75392,75436,75478,75971,76003,76058,76140-76141,76231,76380,76428-76429 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r75264 | andrew.kuchling | 2009-10-05 17:30:22 -0500 (Mon, 05 Oct 2009) | 1 line Add various items ........ r75268 | andrew.kuchling | 2009-10-05 17:45:39 -0500 (Mon, 05 Oct 2009) | 1 line Remove two notes ........ r75293 | kristjan.jonsson | 2009-10-09 09:32:19 -0500 (Fri, 09 Oct 2009) | 2 lines http://bugs.python.org/issue7029 a non-default timer wasn't actually used by the individual Tests. ........ r75318 | benjamin.peterson | 2009-10-10 16:15:58 -0500 (Sat, 10 Oct 2009) | 1 line remove script which uses long gone module ........ r75391 | andrew.kuchling | 2009-10-13 10:49:33 -0500 (Tue, 13 Oct 2009) | 1 line Link to PEP ........ r75392 | andrew.kuchling | 2009-10-13 11:11:49 -0500 (Tue, 13 Oct 2009) | 1 line Various link, textual, and markup fixes ........ r75436 | benjamin.peterson | 2009-10-15 10:39:15 -0500 (Thu, 15 Oct 2009) | 1 line don't need to mess up sys.path ........ r75478 | senthil.kumaran | 2009-10-17 20:58:45 -0500 (Sat, 17 Oct 2009) | 3 lines Fix a typo. ........ r75971 | benjamin.peterson | 2009-10-30 22:56:15 -0500 (Fri, 30 Oct 2009) | 1 line add some checks for evaluation order with parenthesis #7210 ........ r76003 | antoine.pitrou | 2009-10-31 19:30:13 -0500 (Sat, 31 Oct 2009) | 6 lines Hopefully fix the buildbot problems on test_mailbox, by computing the maildir toc cache refresh date before actually refreshing the cache. (see #6896) ........ r76058 | benjamin.peterson | 2009-11-02 10:14:19 -0600 (Mon, 02 Nov 2009) | 1 line grant list.index() a more informative error message #7252 ........ r76140 | nick.coghlan | 2009-11-07 02:13:55 -0600 (Sat, 07 Nov 2009) | 1 line Add test for runpy.run_module package execution and use something other than logging as the example of a non-executable package ........ r76141 | nick.coghlan | 2009-11-07 02:15:01 -0600 (Sat, 07 Nov 2009) | 1 line Some minor cleanups to private runpy code and docstrings ........ r76231 | benjamin.peterson | 2009-11-12 17:42:23 -0600 (Thu, 12 Nov 2009) | 1 line this main is much more useful ........ r76380 | antoine.pitrou | 2009-11-18 14:20:46 -0600 (Wed, 18 Nov 2009) | 3 lines Mention Giampolo R's new FTP TLS support in the what's new file ........ r76428 | benjamin.peterson | 2009-11-19 20:15:50 -0600 (Thu, 19 Nov 2009) | 1 line turn goto into do while loop ........ r76429 | benjamin.peterson | 2009-11-19 20:56:43 -0600 (Thu, 19 Nov 2009) | 2 lines avoid doing an uneeded import in a function ........ --- Objects/listobject.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 09fba48f6d..f54b97ddb5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2098,7 +2098,8 @@ static PyObject * listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v; + PyObject *v, *format_tuple, *err_string; + static PyObject *err_format = NULL; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -2121,7 +2122,20 @@ listindex(PyListObject *self, PyObject *args) else if (cmp < 0) return NULL; } - PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list"); + if (err_format == NULL) { + err_format = PyUnicode_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 = PyUnicode_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; } -- cgit v1.2.1 From fa58d96a44585766f47c9b33187a5e838981073b Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 28 Nov 2009 12:35:42 +0000 Subject: Merged revisions 76561 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76561 | mark.dickinson | 2009-11-28 12:30:36 +0000 (Sat, 28 Nov 2009) | 5 lines Include ieeefp.h (when available) in pyport.h instead of individually in Objects/floatobject.c and Objects/complexobject.c. This should silence compiler warnings about implicit declaration of the 'finite' function on Solaris. ........ --- Objects/complexobject.c | 4 ---- Objects/floatobject.c | 4 ---- 2 files changed, 8 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index e5e07c1b6a..562e41f6f9 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -8,10 +8,6 @@ #include "Python.h" #include "structmember.h" -#ifdef HAVE_IEEEFP_H -#include -#endif - /* elementary operations on complex numbers */ static Py_complex c_1 = {1., 0.}; diff --git a/Objects/floatobject.c b/Objects/floatobject.c index ff5c0f6a69..b281f815dc 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -15,10 +15,6 @@ #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#ifdef HAVE_IEEEFP_H -#include -#endif - #ifdef _OSF_SOURCE /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ -- cgit v1.2.1 From 002ce3dbd34d6685452401a1c32c7777a8f50fb2 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sun, 29 Nov 2009 17:56:54 +0000 Subject: Keep this file in sync with trunk. --- Objects/stringlib/formatter.h | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index c722460472..f4a3ea3d58 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -937,13 +937,6 @@ format_float_internal(PyObject *value, format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x0301000 - /* 'F' is the same as 'f', per the PEP */ - /* This is no longer the case in 3.x */ - if (type == 'F') - type = 'f'; -#endif - val = PyFloat_AsDouble(value); if (val == -1.0 && PyErr_Occurred()) goto done; @@ -957,12 +950,6 @@ format_float_internal(PyObject *value, if (precision < 0) precision = default_precision; -#if PY_VERSION_HEX < 0x03010000 - /* 3.1 no longer converts large 'f' to 'g'. */ - if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) - type = 'g'; -#endif - /* 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. */ @@ -1134,13 +1121,6 @@ format_complex_internal(PyObject *value, format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x03010000 - /* This is no longer the case in 3.x */ - /* 'F' is the same as 'f', per the PEP */ - if (type == 'F') - type = 'f'; -#endif - if (precision < 0) precision = default_precision; -- cgit v1.2.1 From 9e6bf8f3049bd8aded29bdbe6360a70d3f85bfd7 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 30 Nov 2009 01:01:42 +0000 Subject: Issue #5748: bytesobject.c should not have its own private defines for stringlib macros. Also removed unused defines and include for localutil.h. --- Objects/bytesobject.c | 18 ++---------------- Objects/stringlib/stringdefs.h | 1 + Objects/stringlib/unicodedefs.h | 1 + 3 files changed, 4 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 27d4f95f06..41eee40d55 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -563,29 +563,15 @@ PyBytes_AsStringAndSize(register PyObject *obj, /* Methods */ #include "stringlib/stringdefs.h" -#define STRINGLIB_CHAR char - -#define STRINGLIB_CMP memcmp -#define STRINGLIB_LEN PyBytes_GET_SIZE -#define STRINGLIB_NEW PyBytes_FromStringAndSize -#define STRINGLIB_STR PyBytes_AS_STRING -/* #define STRINGLIB_WANT_CONTAINS_OBJ 1 */ - -#define STRINGLIB_EMPTY nullstring -#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact -#define STRINGLIB_MUTABLE 0 #include "stringlib/fastsearch.h" - #include "stringlib/count.h" #include "stringlib/find.h" #include "stringlib/partition.h" #include "stringlib/ctype.h" -#include "stringlib/transmogrify.h" -#define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyBytes_InsertThousandsGroupingLocale -#include "stringlib/localeutil.h" +#define STRINGLIB_MUTABLE 0 +#include "stringlib/transmogrify.h" PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h index a5672c7e6b..f85357fb0f 100644 --- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -21,6 +21,7 @@ #define STRINGLIB_NEW PyBytes_FromStringAndSize #define STRINGLIB_RESIZE _PyBytes_Resize #define STRINGLIB_CHECK PyBytes_Check +#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h index 366acfe001..c23c392e56 100644 --- a/Objects/stringlib/unicodedefs.h +++ b/Objects/stringlib/unicodedefs.h @@ -21,6 +21,7 @@ #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 #define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale -- cgit v1.2.1 From f4a893939a986a38c5032afa570fd3be2960fc3c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 3 Dec 2009 03:01:27 +0000 Subject: Merged revisions 76644 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76644 | benjamin.peterson | 2009-12-02 20:52:39 -0600 (Wed, 02 Dec 2009) | 4 lines disable pymalloc tricks with the --with-valgrind option #2422 Patch from James Henstridge. ........ --- Objects/obmalloc.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'Objects') diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 9cf90c418e..fa985da987 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -2,6 +2,21 @@ #ifdef WITH_PYMALLOC +#ifdef WITH_VALGRIND +#include + +/* 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, @@ -728,6 +743,13 @@ PyObject_Malloc(size_t nbytes) 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 @@ -927,6 +949,11 @@ PyObject_Free(void *p) 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. */ @@ -1121,6 +1148,9 @@ PyObject_Free(void *p) return; } +#ifdef WITH_VALGRIND +redirect: +#endif /* We didn't allocate this address. */ free(p); } @@ -1150,6 +1180,12 @@ PyObject_Realloc(void *p, size_t nbytes) 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 */ @@ -1177,6 +1213,9 @@ PyObject_Realloc(void *p, size_t nbytes) } 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 -- cgit v1.2.1 From 4f168582d7c7bef1c51e25ade3ae754952f71aa8 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 4 Dec 2009 10:06:06 +0000 Subject: Issue #7430: Remove lingering reference to cmp in recursion error message. --- Objects/object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 002acd04be..b0a54719a0 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -603,7 +603,7 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op) PyErr_BadInternalCall(); return NULL; } - if (Py_EnterRecursiveCall(" in cmp")) + if (Py_EnterRecursiveCall(" in comparison")) return NULL; res = do_richcompare(v, w, op); Py_LeaveRecursiveCall(); -- cgit v1.2.1 From 63a013c4e1409e2fb1930f85623b1a694bbfe1dd Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 7 Dec 2009 19:34:59 +0000 Subject: Fix error message, for consistency with messages for % and //, and for consistency with trunk --- Objects/longobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 4d71ea2ce3..b46ce4eb47 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3231,7 +3231,7 @@ long_true_divide(PyObject *a, PyObject *b) if (bd == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "int division or modulo by zero"); + "integer division or modulo by zero"); return NULL; } -- cgit v1.2.1 From 35656d3f0fc57c1140c2181c620df0b692da75ec Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 12 Dec 2009 19:18:27 +0000 Subject: Merged revisions 76763 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r76763 | antoine.pitrou | 2009-12-12 20:13:08 +0100 (sam., 12 déc. 2009) | 7 lines Issue #7466: segmentation fault when the garbage collector is called in the middle of populating a tuple. Patch by Florent Xicluna. (note: no NEWS entry for trunk since the bug was introduced in 2.7/3.1) ........ --- Objects/tupleobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 290107ad34..884174dca4 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -850,7 +850,8 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; - _PyObject_GC_UNTRACK(v); + 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++) { -- cgit v1.2.1 From bde3ba94e45d38d65aa47a6bb57242ff9d6a8eb5 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 13 Dec 2009 02:10:36 +0000 Subject: Merged revisions 76052,76522,76591,76689,76697,76733 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76052 | gregory.p.smith | 2009-11-01 20:02:38 -0600 (Sun, 01 Nov 2009) | 5 lines see issue1006238, this merges in the following patch to ease cross compiling the printf %zd check. http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.5-cross-printf.patch?rev=1.1&view=markup ........ r76522 | barry.warsaw | 2009-11-25 12:38:32 -0600 (Wed, 25 Nov 2009) | 2 lines Add mktime_tz to __all__. It's documented as being available in email.utils. ........ r76591 | benjamin.peterson | 2009-11-29 16:26:26 -0600 (Sun, 29 Nov 2009) | 4 lines now that deepcopy can handle instance methods, this hack can be removed #7409 Thanks Robert Collins ........ r76689 | benjamin.peterson | 2009-12-06 11:37:48 -0600 (Sun, 06 Dec 2009) | 1 line rewrite translate_newlines for clarity ........ r76697 | benjamin.peterson | 2009-12-06 15:24:30 -0600 (Sun, 06 Dec 2009) | 2 lines fix test_parser from tokenizer tweak ........ r76733 | benjamin.peterson | 2009-12-09 21:37:59 -0600 (Wed, 09 Dec 2009) | 1 line substitute PyDict_Check() for PyObject_IsInstance ........ --- Objects/abstract.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 5247824770..d4cba74798 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1453,7 +1453,7 @@ PyNumber_ToBase(PyObject *n, int base) int PySequence_Check(PyObject *s) { - if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) + if (PyDict_Check(s)) return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; -- cgit v1.2.1 From a62759933238ade9dd26f10640d246cb7ba5a7c0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 21 Dec 2009 12:37:06 +0000 Subject: Keep PyLong_AsLongAndOverflow documentation and implementation in sync between py3k and trunk; merge new tests from trunk to py3k. (See issue #7528.) --- Objects/longobject.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index b46ce4eb47..8e4093c79d 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -346,9 +346,10 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) if (!PyLong_Check(vv)) { PyNumberMethods *nb; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); return -1; } vv = (*nb->nb_int) (vv); @@ -388,13 +389,13 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) prev = x; x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { - *overflow = Py_SIZE(v) > 0 ? 1 : -1; + *overflow = sign; goto exit; } } - /* Haven't lost any bits, but casting to long requires extra care - * (see comment above). - */ + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ if (x <= (unsigned long)LONG_MAX) { res = (long)x * sign; } @@ -402,9 +403,9 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) res = LONG_MIN; } else { - *overflow = Py_SIZE(v) > 0 ? 1 : -1; + *overflow = sign; /* res is already set to -1 */ - } + } } exit: if (do_decref) { -- cgit v1.2.1 From e9f7686790ec3472e632b173fa171794835eec12 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 27 Dec 2009 15:09:50 +0000 Subject: Merged revisions 77062 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77062 | mark.dickinson | 2009-12-27 14:55:57 +0000 (Sun, 27 Dec 2009) | 2 lines Issue #1811: Improve accuracy and consistency of true division for integers. ........ --- Objects/longobject.c | 280 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 250 insertions(+), 30 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 8e4093c79d..429b635a50 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3213,47 +3213,267 @@ long_div(PyObject *a, PyObject *b) return (PyObject *)div; } +/* PyLong/PyLong -> float, with correctly rounded result. */ + +#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) +#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) + static PyObject * -long_true_divide(PyObject *a, PyObject *b) +long_true_divide(PyObject *v, PyObject *w) { - double ad, bd; - int failed, aexp = -1, bexp = -1; + PyLongObject *a, *b, *x; + Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; + digit mask, low; + int inexact, negate, a_is_small, b_is_small; + double dx, result; - CHECK_BINOP(a, b); - ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp); - bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp); - failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred(); - if (failed) - return NULL; - /* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x, - but should really be set correctly after sucessful calls to - _PyLong_AsScaledDouble() */ - assert(aexp >= 0 && bexp >= 0); + CHECK_BINOP(v, w); + a = (PyLongObject *)v; + b = (PyLongObject *)w; + + /* + Method in a nutshell: + + 0. reduce to case a, b > 0; filter out obvious underflow/overflow + 1. choose a suitable integer 'shift' + 2. use integer arithmetic to compute x = floor(2**-shift*a/b) + 3. adjust x for correct rounding + 4. convert x to a double dx with the same value + 5. return ldexp(dx, shift). + + In more detail: + + 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b + returns either 0.0 or -0.0, depending on the sign of b. For a and + b both nonzero, ignore signs of a and b, and add the sign back in + at the end. Now write a_bits and b_bits for the bit lengths of a + and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise + for b). Then + + 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). + + So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and + so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - + DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of + the way, we can assume that + + DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. + + 1. The integer 'shift' is chosen so that x has the right number of + bits for a double, plus two or three extra bits that will be used + in the rounding decisions. Writing a_bits and b_bits for the + number of significant bits in a and b respectively, a + straightforward formula for shift is: + + shift = a_bits - b_bits - DBL_MANT_DIG - 2 + + This is fine in the usual case, but if a/b is smaller than the + smallest normal float then it can lead to double rounding on an + IEEE 754 platform, giving incorrectly rounded results. So we + adjust the formula slightly. The actual formula used is: + + shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 + + 2. The quantity x is computed by first shifting a (left -shift bits + if shift <= 0, right shift bits if shift > 0) and then dividing by + b. For both the shift and the division, we keep track of whether + the result is inexact, in a flag 'inexact'; this information is + needed at the rounding stage. + + With the choice of shift above, together with our assumption that + a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows + that x >= 1. + + 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace + this with an exactly representable float of the form + + round(x/2**extra_bits) * 2**(extra_bits+shift). + + For float representability, we need x/2**extra_bits < + 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - + DBL_MANT_DIG. This translates to the condition: + + extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG + + To round, we just modify the bottom digit of x in-place; this can + end up giving a digit with value > PyLONG_MASK, but that's not a + problem since digits can hold values up to 2*PyLONG_MASK+1. + + With the original choices for shift above, extra_bits will always + be 2 or 3. Then rounding under the round-half-to-even rule, we + round up iff the most significant of the extra bits is 1, and + either: (a) the computation of x in step 2 had an inexact result, + or (b) at least one other of the extra bits is 1, or (c) the least + significant bit of x (above those to be rounded) is 1. + + 4. Conversion to a double is straightforward; all floating-point + operations involved in the conversion are exact, so there's no + danger of rounding errors. + + 5. Use ldexp(x, shift) to compute x*2**shift, the final result. + The result will always be exactly representable as a double, except + in the case that it overflows. To avoid dependence on the exact + behaviour of ldexp on overflow, we check for overflow before + applying ldexp. The result of ldexp is adjusted for sign before + returning. + */ - if (bd == 0.0) { + /* Reduce to case where a and b are both positive. */ + a_size = ABS(Py_SIZE(a)); + b_size = ABS(Py_SIZE(b)); + negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, - "integer division or modulo by zero"); - return NULL; + "division by zero"); + goto error; } - - /* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */ - ad /= bd; /* overflow/underflow impossible here */ - aexp -= bexp; - if (aexp > INT_MAX / PyLong_SHIFT) + if (a_size == 0) + goto underflow_or_zero; + + /* Fast path for a and b small (exactly representable in a double). + Relies on floating-point division being correctly rounded; results + may be subject to double rounding on x86 machines that operate with + the x87 FPU set to 64-bit precision. */ + a_is_small = a_size <= MANT_DIG_DIGITS || + (a_size == MANT_DIG_DIGITS+1 && + a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b_is_small = b_size <= MANT_DIG_DIGITS || + (b_size == MANT_DIG_DIGITS+1 && + b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + if (a_is_small && b_is_small) { + double da, db; + da = a->ob_digit[--a_size]; + while (a_size > 0) + da = da * PyLong_BASE + a->ob_digit[--a_size]; + db = b->ob_digit[--b_size]; + while (b_size > 0) + db = db * PyLong_BASE + b->ob_digit[--b_size]; + result = da / db; + goto success; + } + + /* Catch obvious cases of underflow and overflow */ + diff = a_size - b_size; + if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) + /* Extreme overflow */ goto overflow; - else if (aexp < -(INT_MAX / PyLong_SHIFT)) - return PyFloat_FromDouble(0.0); /* underflow to 0 */ - errno = 0; - ad = ldexp(ad, aexp * PyLong_SHIFT); - if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */ + else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) + /* Extreme underflow */ + goto underflow_or_zero; + /* Next line is now safe from overflowing a Py_ssize_t */ + diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - + bits_in_digit(b->ob_digit[b_size - 1]); + /* Now diff = a_bits - b_bits. */ + if (diff > DBL_MAX_EXP) goto overflow; - return PyFloat_FromDouble(ad); + else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) + goto underflow_or_zero; + + /* Choose value for shift; see comments for step 1 above. */ + shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; + + inexact = 0; + + /* x = abs(a * 2**-shift) */ + if (shift <= 0) { + Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; + digit rem; + /* x = a << -shift */ + if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { + /* In practice, it's probably impossible to end up + here. Both a and b would have to be enormous, + using close to SIZE_T_MAX bytes of memory each. */ + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow during division"); + goto error; + } + x = _PyLong_New(a_size + shift_digits + 1); + if (x == NULL) + goto error; + for (i = 0; i < shift_digits; i++) + x->ob_digit[i] = 0; + rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + a_size, -shift % PyLong_SHIFT); + x->ob_digit[a_size + shift_digits] = rem; + } + else { + Py_ssize_t shift_digits = shift / PyLong_SHIFT; + digit rem; + /* x = a >> shift */ + assert(a_size >= shift_digits); + x = _PyLong_New(a_size - shift_digits); + if (x == NULL) + goto error; + rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + a_size - shift_digits, shift % PyLong_SHIFT); + /* set inexact if any of the bits shifted out is nonzero */ + if (rem) + inexact = 1; + while (!inexact && shift_digits > 0) + if (a->ob_digit[--shift_digits]) + inexact = 1; + } + long_normalize(x); + x_size = Py_SIZE(x); + + /* x //= b. If the remainder is nonzero, set inexact. We own the only + reference to x, so it's safe to modify it in-place. */ + if (b_size == 1) { + digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, + b->ob_digit[0]); + long_normalize(x); + if (rem) + inexact = 1; + } + else { + PyLongObject *div, *rem; + div = x_divrem(x, b, &rem); + Py_DECREF(x); + x = div; + if (x == NULL) + goto error; + if (Py_SIZE(rem)) + inexact = 1; + Py_DECREF(rem); + } + x_size = ABS(Py_SIZE(x)); + assert(x_size > 0); /* result of division is never zero */ + x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); + + /* The number of extra bits that have to be rounded away. */ + extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + assert(extra_bits == 2 || extra_bits == 3); + + /* Round by directly modifying the low digit of x. */ + mask = (digit)1 << (extra_bits - 1); + low = x->ob_digit[0] | inexact; + if (low & mask && low & (3*mask-1)) + low += mask; + x->ob_digit[0] = low & ~(mask-1U); + + /* Convert x to a double dx; the conversion is exact. */ + dx = x->ob_digit[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + Py_DECREF(x); -overflow: + /* Check whether ldexp result will overflow a double. */ + if (shift + x_bits >= DBL_MAX_EXP && + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, x_bits))) + goto overflow; + result = ldexp(dx, shift); + + success: + return PyFloat_FromDouble(negate ? -result : result); + + underflow_or_zero: + return PyFloat_FromDouble(negate ? -0.0 : 0.0); + + overflow: PyErr_SetString(PyExc_OverflowError, - "int/int too large for a float"); + "integer division result too large for a float"); + error: return NULL; - } static PyObject * -- cgit v1.2.1 From 62dfa64c139b9db08f3ba7b1ec83d792487e30d5 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 30 Dec 2009 16:22:49 +0000 Subject: Merged revisions 77139-77140 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77139 | mark.dickinson | 2009-12-30 12:12:23 +0000 (Wed, 30 Dec 2009) | 3 lines Issue #7534: Fix handling of nans, infinities, and negative zero in ** operator, on IEEE 754 platforms. Thanks Marcos Donolo for original patch. ........ r77140 | mark.dickinson | 2009-12-30 12:22:49 +0000 (Wed, 30 Dec 2009) | 1 line Add Marcos Donolo for work on issue 7534 patch. ........ --- Objects/floatobject.c | 97 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 23 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index b281f815dc..33196ff476 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -671,10 +671,15 @@ float_floor_div(PyObject *v, PyObject *w) 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 " @@ -686,20 +691,56 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) 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 */ + if (iw == 0) { /* v**0 is 1, even 0**0 */ return PyFloat_FromDouble(1.0); } - if (iv == 0.0) { /* 0**w is error if w<0, else 1 */ + 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"); + "0.0 cannot be raised to a " + "negative power"); return NULL; } - return PyFloat_FromDouble(0.0); - } - if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ - return PyFloat_FromDouble(1.0); + /* 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. @@ -710,33 +751,41 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) */ return PyComplex_Type.tp_as_number->nb_power(v, w, z); } - /* iw is an exact integer, albeit perhaps a very large one. + /* 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; we let that slide in math.pow() (which currently - * reflects all platform accidents), but not for Python's **. - */ - if (iv == -1.0 && Py_IS_FINITE(iw)) { - /* Return 1 if iw is even, -1 if iw is odd; there's - * no guarantee that any C integral type is big - * enough to hold iw, so we have to check this - * indirectly. - */ - ix = floor(iw * 0.5) * 2.0; - return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0); - } - /* Else iv != -1.0, and overflow or underflow are possible. - * Unless we're to write pow() ourselves, we have to trust - * the platform to do this correctly. + * 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. @@ -748,6 +797,8 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) return PyFloat_FromDouble(ix); } +#undef DOUBLE_IS_ODD_INTEGER + static PyObject * float_neg(PyFloatObject *v) { -- cgit v1.2.1 From e6c183a6753c04b19d8d802a2e48708f2afdf75e Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Thu, 31 Dec 2009 03:56:09 +0000 Subject: Issue #6687: Moved the special-case for integers out of PyBytes_FromObject. --- Objects/bytesobject.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 41eee40d55..cb634481bd 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2884,6 +2884,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) const char *encoding = NULL; const char *errors = NULL; PyObject *new = NULL; + Py_ssize_t size; static char *kwlist[] = {"source", "encoding", "errors", 0}; if (type != &PyBytes_Type) @@ -2914,6 +2915,25 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) assert(PyBytes_Check(new)); return new; } + /* Is it an integer? */ + size = PyNumber_AsSsize_t(x, PyExc_ValueError); + if (size == -1 && PyErr_Occurred()) { + PyErr_Clear(); + } + else { + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + new = PyBytes_FromStringAndSize(NULL, size); + if (new == NULL) { + return NULL; + } + if (size > 0) { + memset(((PyBytesObject*)new)->ob_sval, 0, size); + } + return new; + } /* If it's not unicode, there can't be encoding or errors */ if (encoding != NULL || errors != NULL) { @@ -2934,27 +2954,6 @@ PyBytes_FromObject(PyObject *x) PyErr_BadInternalCall(); return NULL; } - - /* Is it an int? */ - size = PyNumber_AsSsize_t(x, PyExc_ValueError); - if (size == -1 && PyErr_Occurred()) { - PyErr_Clear(); - } - else { - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) { - return NULL; - } - if (size > 0) { - memset(((PyBytesObject*)new)->ob_sval, 0, size); - } - return new; - } - /* Use the modern buffer interface */ if (PyObject_CheckBuffer(x)) { Py_buffer view; @@ -2974,6 +2973,11 @@ PyBytes_FromObject(PyObject *x) PyBuffer_Release(&view); return NULL; } + if (PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "cannot convert unicode object to bytes"); + return NULL; + } /* For iterator version, create a string object and resize as needed */ /* XXX(gb): is 64 a good value? also, optimize if length is known */ -- cgit v1.2.1 From 4e01c124fcd6934ccc196a74eb0de8d4167e939f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 2 Jan 2010 15:33:56 +0000 Subject: Merged revisions 77234 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77234 | mark.dickinson | 2010-01-02 14:45:40 +0000 (Sat, 02 Jan 2010) | 7 lines Refactor some longobject internals: PyLong_AsDouble and _PyLong_AsScaledDouble (the latter renamed to _PyLong_Frexp) now use the same core code. The exponent produced by _PyLong_Frexp now has type Py_ssize_t instead of the previously used int, and no longer needs scaling by PyLong_SHIFT. This frees the math module from having to know anything about the PyLong implementation. This closes issue #5576. ........ --- Objects/longobject.c | 367 ++++++++++++++++++++------------------------------- 1 file changed, 146 insertions(+), 221 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 429b635a50..2e2eca8e45 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -98,9 +98,6 @@ maybe_small_long(PyLongObject *v) #define SIGCHECK(PyTryBlock) \ if (PyErr_CheckSignals()) PyTryBlock \ -/* forward declaration */ -static int bits_in_digit(digit d); - /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature of the algorithms used, this could save at most be one word anyway. */ @@ -911,224 +908,6 @@ Overflow: } -double -_PyLong_AsScaledDouble(PyObject *vv, int *exponent) -{ -/* NBITS_WANTED should be > the number of bits in a double's precision, - but small enough so that 2**NBITS_WANTED is within the normal double - range. nbitsneeded is set to 1 less than that because the most-significant - Python digit contains at least 1 significant bit, but we don't want to - bother counting them (catering to the worst case cheaply). - - 57 is one more than VAX-D double precision; I (Tim) don't know of a double - format with more precision than that; it's 1 larger so that we add in at - least one round bit to stand in for the ignored least-significant bits. -*/ -#define NBITS_WANTED 57 - PyLongObject *v; - double x; - const double multiplier = (double)(1L << PyLong_SHIFT); - Py_ssize_t i; - int sign; - int nbitsneeded; - - if (vv == NULL || !PyLong_Check(vv)) { - PyErr_BadInternalCall(); - return -1; - } - v = (PyLongObject *)vv; - i = Py_SIZE(v); - sign = 1; - if (i < 0) { - sign = -1; - i = -(i); - } - else if (i == 0) { - *exponent = 0; - return 0.0; - } - --i; - x = (double)v->ob_digit[i]; - nbitsneeded = NBITS_WANTED - 1; - /* Invariant: i Python digits remain unaccounted for. */ - while (i > 0 && nbitsneeded > 0) { - --i; - x = x * multiplier + (double)v->ob_digit[i]; - nbitsneeded -= PyLong_SHIFT; - } - /* There are i digits we didn't shift in. Pretending they're all - zeroes, the true value is x * 2**(i*PyLong_SHIFT). */ - *exponent = i; - assert(x > 0.0); - return x * sign; -#undef NBITS_WANTED -} - -/* Get a C double from a long int object. Rounds to the nearest double, - using the round-half-to-even rule in the case of a tie. */ - -double -PyLong_AsDouble(PyObject *vv) -{ - PyLongObject *v = (PyLongObject *)vv; - Py_ssize_t rnd_digit, rnd_bit, m, n; - digit lsb, *d; - int round_up = 0; - double x; - - if (vv == NULL || !PyLong_Check(vv)) { - PyErr_BadInternalCall(); - return -1.0; - } - - /* Notes on the method: for simplicity, assume v is positive and >= - 2**DBL_MANT_DIG. (For negative v we just ignore the sign until the - end; for small v no rounding is necessary.) Write n for the number - of bits in v, so that 2**(n-1) <= v < 2**n, and n > DBL_MANT_DIG. - - Some terminology: the *rounding bit* of v is the 1st bit of v that - will be rounded away (bit n - DBL_MANT_DIG - 1); the *parity bit* - is the bit immediately above. The round-half-to-even rule says - that we round up if the rounding bit is set, unless v is exactly - halfway between two floats and the parity bit is zero. - - Write d[0] ... d[m] for the digits of v, least to most significant. - Let rnd_bit be the index of the rounding bit, and rnd_digit the - index of the PyLong digit containing the rounding bit. Then the - bits of the digit d[rnd_digit] look something like: - - rounding bit - | - v - msb -> sssssrttttttttt <- lsb - ^ - | - parity bit - - where 's' represents a 'significant bit' that will be included in - the mantissa of the result, 'r' is the rounding bit, and 't' - represents a 'trailing bit' following the rounding bit. Note that - if the rounding bit is at the top of d[rnd_digit] then the parity - bit will be the lsb of d[rnd_digit+1]. If we set - - lsb = 1 << (rnd_bit % PyLong_SHIFT) - - then d[rnd_digit] & (PyLong_BASE - 2*lsb) selects just the - significant bits of d[rnd_digit], d[rnd_digit] & (lsb-1) gets the - trailing bits, and d[rnd_digit] & lsb gives the rounding bit. - - We initialize the double x to the integer given by digits - d[rnd_digit:m-1], but with the rounding bit and trailing bits of - d[rnd_digit] masked out. So the value of x comes from the top - DBL_MANT_DIG bits of v, multiplied by 2*lsb. Note that in the loop - that produces x, all floating-point operations are exact (assuming - that FLT_RADIX==2). Now if we're rounding down, the value we want - to return is simply - - x * 2**(PyLong_SHIFT * rnd_digit). - - and if we're rounding up, it's - - (x + 2*lsb) * 2**(PyLong_SHIFT * rnd_digit). - - Under the round-half-to-even rule, we round up if, and only - if, the rounding bit is set *and* at least one of the - following three conditions is satisfied: - - (1) the parity bit is set, or - (2) at least one of the trailing bits of d[rnd_digit] is set, or - (3) at least one of the digits d[i], 0 <= i < rnd_digit - is nonzero. - - Finally, we have to worry about overflow. If v >= 2**DBL_MAX_EXP, - or equivalently n > DBL_MAX_EXP, then overflow occurs. If v < - 2**DBL_MAX_EXP then we're usually safe, but there's a corner case - to consider: if v is very close to 2**DBL_MAX_EXP then it's - possible that v is rounded up to exactly 2**DBL_MAX_EXP, and then - again overflow occurs. - */ - - if (Py_SIZE(v) == 0) - return 0.0; - m = ABS(Py_SIZE(v)) - 1; - d = v->ob_digit; - assert(d[m]); /* v should be normalized */ - - /* fast path for case where 0 < abs(v) < 2**DBL_MANT_DIG */ - if (m < DBL_MANT_DIG / PyLong_SHIFT || - (m == DBL_MANT_DIG / PyLong_SHIFT && - d[m] < (digit)1 << DBL_MANT_DIG%PyLong_SHIFT)) { - x = d[m]; - while (--m >= 0) - x = x*PyLong_BASE + d[m]; - return Py_SIZE(v) < 0 ? -x : x; - } - - /* if m is huge then overflow immediately; otherwise, compute the - number of bits n in v. The condition below implies n (= #bits) >= - m * PyLong_SHIFT + 1 > DBL_MAX_EXP, hence v >= 2**DBL_MAX_EXP. */ - if (m > (DBL_MAX_EXP-1)/PyLong_SHIFT) - goto overflow; - n = m * PyLong_SHIFT + bits_in_digit(d[m]); - if (n > DBL_MAX_EXP) - goto overflow; - - /* find location of rounding bit */ - assert(n > DBL_MANT_DIG); /* dealt with |v| < 2**DBL_MANT_DIG above */ - rnd_bit = n - DBL_MANT_DIG - 1; - rnd_digit = rnd_bit/PyLong_SHIFT; - lsb = (digit)1 << (rnd_bit%PyLong_SHIFT); - - /* Get top DBL_MANT_DIG bits of v. Assumes PyLong_SHIFT < - DBL_MANT_DIG, so we'll need bits from at least 2 digits of v. */ - x = d[m]; - assert(m > rnd_digit); - while (--m > rnd_digit) - x = x*PyLong_BASE + d[m]; - x = x*PyLong_BASE + (d[m] & (PyLong_BASE-2*lsb)); - - /* decide whether to round up, using round-half-to-even */ - assert(m == rnd_digit); - if (d[m] & lsb) { /* if (rounding bit is set) */ - digit parity_bit; - if (lsb == PyLong_BASE/2) - parity_bit = d[m+1] & 1; - else - parity_bit = d[m] & 2*lsb; - if (parity_bit) - round_up = 1; - else if (d[m] & (lsb-1)) - round_up = 1; - else { - while (--m >= 0) { - if (d[m]) { - round_up = 1; - break; - } - } - } - } - - /* and round up if necessary */ - if (round_up) { - x += 2*lsb; - if (n == DBL_MAX_EXP && - x == ldexp((double)(2*lsb), DBL_MANT_DIG)) { - /* overflow corner case */ - goto overflow; - } - } - - /* shift, adjust for sign, and return */ - x = ldexp(x, rnd_digit*PyLong_SHIFT); - return Py_SIZE(v) < 0 ? -x : x; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C double"); - return -1.0; -} - /* Create a new long (or int) object from a C pointer */ PyObject * @@ -2442,6 +2221,152 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) return long_normalize(a); } +/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <= + abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is + rounded to DBL_MANT_DIG significant bits using round-half-to-even. + If a == 0, return 0.0 and set *e = 0. If the resulting exponent + e is larger than PY_SSIZE_T_MAX, raise OverflowError and return + -1.0. */ + +/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */ +#if DBL_MANT_DIG == 53 +#define EXP2_DBL_MANT_DIG 9007199254740992.0 +#else +#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG)) +#endif + +double +_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) +{ + Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size; + /* See below for why x_digits is always large enough. */ + digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT]; + double dx; + /* Correction term for round-half-to-even rounding. For a digit x, + "x + half_even_correction[x & 7]" gives x rounded to the nearest + multiple of 4, rounding ties to a multiple of 8. */ + static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; + + a_size = ABS(Py_SIZE(a)); + if (a_size == 0) { + /* Special case for 0: significand 0.0, exponent 0. */ + *e = 0; + return 0.0; + } + a_bits = bits_in_digit(a->ob_digit[a_size-1]); + /* The following is an overflow-free version of the check + "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ + if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && + (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || + a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) + goto overflow; + a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; + + /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] + (shifting left if a_bits <= DBL_MANT_DIG + 2). + + Number of digits needed for result: write // for floor division. + Then if shifting left, we end up using + + 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT + + digits. If shifting right, we use + + a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT + + digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with + the inequalities + + m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT + m // PyLong_SHIFT - n // PyLong_SHIFT <= + 1 + (m - n - 1) // PyLong_SHIFT, + + valid for any integers m and n, we find that x_size satisfies + + x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT + + in both cases. + */ + if (a_bits <= DBL_MANT_DIG + 2) { + shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; + shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; + x_size = 0; + while (x_size < shift_digits) + x_digits[x_size++] = 0; + rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + shift_bits); + x_size += a_size; + x_digits[x_size++] = rem; + } + else { + shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; + shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; + rem = v_rshift(x_digits, a->ob_digit + shift_digits, + a_size - shift_digits, shift_bits); + x_size = a_size - shift_digits; + /* For correct rounding below, we need the least significant + bit of x to be 'sticky' for this shift: if any of the bits + shifted out was nonzero, we set the least significant bit + of x. */ + if (rem) + x_digits[0] |= 1; + else + while (shift_digits > 0) + if (a->ob_digit[--shift_digits]) { + x_digits[0] |= 1; + break; + } + } + assert(1 <= x_size && x_size <= sizeof(x_digits)/sizeof(digit)); + + /* Round, and convert to double. */ + x_digits[0] += half_even_correction[x_digits[0] & 7]; + dx = x_digits[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x_digits[--x_size]; + + /* Rescale; make correction if result is 1.0. */ + dx /= 4.0 * EXP2_DBL_MANT_DIG; + if (dx == 1.0) { + if (a_bits == PY_SSIZE_T_MAX) + goto overflow; + dx = 0.5; + a_bits += 1; + } + + *e = a_bits; + return Py_SIZE(a) < 0 ? -dx : dx; + + overflow: + /* exponent > PY_SSIZE_T_MAX */ + PyErr_SetString(PyExc_OverflowError, + "huge integer: number of bits overflows a Py_ssize_t"); + *e = 0; + return -1.0; +} + +/* Get a C double from a long int object. Rounds to the nearest double, + using the round-half-to-even rule in the case of a tie. */ + +double +PyLong_AsDouble(PyObject *v) +{ + Py_ssize_t exponent; + double x; + + if (v == NULL || !PyLong_Check(v)) { + PyErr_BadInternalCall(); + return -1.0; + } + x = _PyLong_Frexp((PyLongObject *)v, &exponent); + if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { + PyErr_SetString(PyExc_OverflowError, + "long int too large to convert to float"); + return -1.0; + } + return ldexp(x, exponent); +} + /* Methods */ static void -- cgit v1.2.1 From e374ec15876072f863f090020d8fe0f677d1e9d6 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 2 Jan 2010 21:40:36 +0000 Subject: Merged revisions 77241 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77241 | antoine.pitrou | 2010-01-02 22:12:58 +0100 (sam., 02 janv. 2010) | 4 lines Issue #7462: Implement the stringlib fast search algorithm for the `rfind`, `rindex`, `rsplit` and `rpartition` methods. Patch by Florent Xicluna. ........ --- Objects/bytearrayobject.c | 39 ++++---------- Objects/stringlib/README.txt | 4 -- Objects/stringlib/fastsearch.h | 112 +++++++++++++++++++++++++++------------- Objects/stringlib/find.h | 32 +++++------- Objects/stringlib/partition.h | 12 ++--- Objects/stringlib/stringdefs.h | 1 - Objects/stringlib/unicodedefs.h | 19 ------- 7 files changed, 103 insertions(+), 116 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c09ccde743..827c47b1df 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1035,7 +1035,6 @@ bytearray_dealloc(PyByteArrayObject *self) /* Methods */ #define STRINGLIB_CHAR char -#define STRINGLIB_CMP memcmp #define STRINGLIB_LEN PyByteArray_GET_SIZE #define STRINGLIB_STR PyByteArray_AS_STRING #define STRINGLIB_NEW PyByteArray_FromStringAndSize @@ -2214,14 +2213,11 @@ 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, i, j; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j, pos; Py_ssize_t maxsplit = -1, count = 0; const char *s = PyByteArray_AS_STRING(self), *sub; PyObject *list, *str, *subobj = Py_None; Py_buffer vsub; -#ifdef USE_FAST - Py_ssize_t pos; -#endif if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit)) return NULL; @@ -2253,7 +2249,6 @@ bytearray_split(PyByteArrayObject *self, PyObject *args) return NULL; } -#ifdef USE_FAST i = j = 0; while (maxsplit-- > 0) { pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH); @@ -2263,18 +2258,6 @@ bytearray_split(PyByteArrayObject *self, PyObject *args) SPLIT_ADD(s, i, j); i = j + n; } -#else - i = j = 0; - while ((j+n <= len) && (maxsplit-- > 0)) { - for (; j+n <= len; j++) { - if (Py_STRING_MATCH(s, j, sub, n)) { - SPLIT_ADD(s, i, j); - i = j = j + n; - break; - } - } - } -#endif SPLIT_ADD(s, i, len); FIX_PREALLOC_SIZE(list); PyBuffer_Release(&vsub); @@ -2452,7 +2435,7 @@ 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, i, j; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n, j, pos; Py_ssize_t maxsplit = -1, count = 0; const char *s = PyByteArray_AS_STRING(self), *sub; PyObject *list, *str, *subobj = Py_None; @@ -2489,17 +2472,13 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *args) } j = len; - i = j - n; - - while ( (i >= 0) && (maxsplit-- > 0) ) { - for (; i>=0; i--) { - if (Py_STRING_MATCH(s, i, sub, n)) { - SPLIT_ADD(s, i + n, j); - j = i; - i -= n; - break; - } - } + + while (maxsplit-- > 0) { + pos = fastsearch(s, j, sub, n, FAST_RSEARCH); + if (pos < 0) + break; + SPLIT_ADD(s, pos + n, j); + j = pos; } SPLIT_ADD(s, 0, j); FIX_PREALLOC_SIZE(list); diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt index aec3441dfe..c884ec3c2f 100644 --- a/Objects/stringlib/README.txt +++ b/Objects/stringlib/README.txt @@ -15,10 +15,6 @@ STRINGLIB_EMPTY a PyObject representing the empty string -int STRINGLIB_CMP(STRINGLIB_CHAR*, STRINGLIB_CHAR*, Py_ssize_t) - - compares two strings. returns 0 if they match, and non-zero if not. - Py_ssize_t STRINGLIB_LEN(PyObject*) returns the length of the given string object (which must be of the diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 23bccfb01d..7b9dd47a5d 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -5,7 +5,7 @@ /* 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/stringlib.htm */ + 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 @@ -16,6 +16,7 @@ #define FAST_COUNT 0 #define FAST_SEARCH 1 +#define FAST_RSEARCH 2 Py_LOCAL_INLINE(Py_ssize_t) fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, @@ -41,51 +42,92 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, if (s[i] == p[0]) count++; return count; - } else { + } 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; - - /* create compressed boyer-moore delta 1 table */ skip = mlast - 1; - /* process pattern[:-1] */ - for (mask = i = 0; i < mlast; i++) { - mask |= (1 << (p[i] & 0x1F)); - if (p[i] == p[mlast]) - skip = mlast - i - 1; - } - /* process pattern[-1] outside the loop */ - mask |= (1 << (p[mlast] & 0x1F)); - - 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) + + if (mode != FAST_RSEARCH) { + + /* create compressed boyer-moore delta 1 table */ + + /* process pattern[:-1] */ + for (mask = i = 0; i < mlast; i++) { + mask |= (1 << (p[i] & 0x1F)); + if (p[i] == p[mlast]) + skip = mlast - i - 1; + } + /* process pattern[-1] outside the loop */ + mask |= (1 << (p[mlast] & 0x1F)); + + 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++; + i = i + mlast; + continue; + } + /* miss: check if next character is part of pattern */ + if (!(mask & (1 << (s[i+m] & 0x1F)))) + i = i + m; + else + i = i + skip; + } else { + /* skip: check if next character is part of pattern */ + if (!(mask & (1 << (s[i+m] & 0x1F)))) + i = i + m; + } + } + } else { /* FAST_RSEARCH */ + + /* create compressed boyer-moore delta 1 table */ + + /* process pattern[0] outside the loop */ + mask = (1 << (p[0] & 0x1F)); + /* process pattern[:0:-1] */ + for (i = mlast; i > 0; i--) { + mask |= (1 << (p[i] & 0x1F)); + 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; - count++; - i = i + mlast; - continue; + /* miss: check if previous character is part of pattern */ + if (!(mask & (1 << (s[i-1] & 0x1F)))) + i = i - m; + else + i = i - skip; + } else { + /* skip: check if previous character is part of pattern */ + if (!(mask & (1 << (s[i-1] & 0x1F)))) + i = i - m; } - /* miss: check if next character is part of pattern */ - if (!(mask & (1 << (s[i+m] & 0x1F)))) - i = i + m; - else - i = i + skip; - } else { - /* skip: check if next character is part of pattern */ - if (!(mask & (1 << (s[i+m] & 0x1F)))) - i = i + m; } } diff --git a/Objects/stringlib/find.h b/Objects/stringlib/find.h index bf065309d7..bf27d6a5cf 100644 --- a/Objects/stringlib/find.h +++ b/Objects/stringlib/find.h @@ -32,20 +32,19 @@ stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, Py_ssize_t offset) { - /* XXX - create reversefastsearch helper! */ - if (sub_len == 0) { - if (str_len < 0) - return -1; - return str_len + offset; - } else { - Py_ssize_t j, pos = -1; - for (j = str_len - sub_len; j >= 0; --j) - if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) { - pos = j + offset; - break; - } - return pos; - } + 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, FAST_RSEARCH); + + if (pos >= 0) + pos += offset; + + return pos; } Py_LOCAL_INLINE(Py_ssize_t) @@ -64,10 +63,7 @@ stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len, if (end < 0) end = 0; - return stringlib_find( - str + start, end - start, - sub, sub_len, start - ); + return stringlib_find(str + start, end - start, sub, sub_len, start); } Py_LOCAL_INLINE(Py_ssize_t) diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h index 105ba317d6..2f26212983 100644 --- a/Objects/stringlib/partition.h +++ b/Objects/stringlib/partition.h @@ -58,7 +58,7 @@ stringlib_rpartition( ) { PyObject* out; - Py_ssize_t pos, j; + Py_ssize_t pos; if (sep_len == 0) { PyErr_SetString(PyExc_ValueError, "empty separator"); @@ -69,20 +69,14 @@ stringlib_rpartition( if (!out) return NULL; - /* XXX - create reversefastsearch helper! */ - pos = -1; - for (j = str_len - sep_len; j >= 0; --j) - if (STRINGLIB_CMP(str+j, sep, sep_len) == 0) { - pos = j; - break; - } + pos = fastsearch(str, str_len, sep, sep_len, FAST_RSEARCH); if (pos < 0) { 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); + Py_INCREF(str_obj); PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj); return out; } diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h index f85357fb0f..8a650fe293 100644 --- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -22,7 +22,6 @@ #define STRINGLIB_RESIZE _PyBytes_Resize #define STRINGLIB_CHECK PyBytes_Check #define STRINGLIB_CHECK_EXACT PyBytes_CheckExact -#define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping #define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h index c23c392e56..a4d2144d8a 100644 --- a/Objects/stringlib/unicodedefs.h +++ b/Objects/stringlib/unicodedefs.h @@ -35,23 +35,4 @@ #define STRINGLIB_WANT_CONTAINS_OBJ 1 -/* STRINGLIB_CMP was defined as: - -Py_LOCAL_INLINE(int) -STRINGLIB_CMP(const Py_UNICODE* str, const Py_UNICODE* other, Py_ssize_t len) -{ - if (str[0] != other[0]) - return 1; - return memcmp((void*) str, (void*) other, len * sizeof(Py_UNICODE)); -} - -but unfortunately that gives a error if the function isn't used in a file that -includes this file. So, reluctantly convert it to a macro instead. */ - -#define STRINGLIB_CMP(str, other, len) \ - (((str)[0] != (other)[0]) ? \ - 1 : \ - memcmp((void*) (str), (void*) (other), (len) * sizeof(Py_UNICODE))) - - #endif /* !STRINGLIB_UNICODEDEFS_H */ -- cgit v1.2.1 From 87e0b57f5e7077c835f2ab4381c2ecbbdd1ce090 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 4 Jan 2010 01:10:28 +0000 Subject: Merged revisions 77292-77293 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77292 | benjamin.peterson | 2010-01-03 18:43:01 -0600 (Sun, 03 Jan 2010) | 1 line do correct lookup of the __complex__ method ........ r77293 | benjamin.peterson | 2010-01-03 19:00:47 -0600 (Sun, 03 Jan 2010) | 1 line factor out __complex__ lookup code to fix another case ........ --- Objects/complexobject.c | 62 +++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 562e41f6f9..73183676a6 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -262,12 +262,25 @@ PyComplex_ImagAsDouble(PyObject *op) } } +static PyObject * +try_complex_special_method(PyObject *op) { + PyObject *f; + static PyObject *complexstr; + + f = _PyObject_LookupSpecial(op, "__complex__", &complexstr); + if (f) { + 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; - static PyObject *complex_str = NULL; assert(op); /* If op is already of type PyComplex_Type, return its value */ @@ -280,21 +293,7 @@ PyComplex_AsCComplex(PyObject *op) cv.real = -1.; cv.imag = 0.; - if (complex_str == NULL) { - if (!(complex_str = PyUnicode_FromString("__complex__"))) - return cv; - } - - { - PyObject *complexfunc; - complexfunc = _PyType_Lookup(op->ob_type, complex_str); - /* complexfunc is a borrowed reference */ - if (complexfunc) { - newop = PyObject_CallFunctionObjArgs(complexfunc, op, NULL); - if (!newop) - return cv; - } - } + newop = try_complex_special_method(op); if (newop) { if (!PyComplex_Check(newop)) { @@ -307,6 +306,9 @@ PyComplex_AsCComplex(PyObject *op) 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 { @@ -880,13 +882,12 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *r, *i, *tmp, *f; + 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 PyObject *complexstr; static char *kwlist[] = {"real", "imag", 0}; r = Py_False; @@ -921,26 +922,15 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - /* XXX Hack to support classes with __complex__ method */ - if (complexstr == NULL) { - complexstr = PyUnicode_InternFromString("__complex__"); - if (complexstr == NULL) - return NULL; - } - f = PyObject_GetAttr(r, complexstr); - if (f == NULL) - PyErr_Clear(); - else { - PyObject *args = PyTuple_New(0); - if (args == NULL) - return NULL; - r = PyEval_CallObject(f, args); - Py_DECREF(args); - Py_DECREF(f); - if (r == NULL) - 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; -- cgit v1.2.1 From a5b561d12550b49fab44f7b908e5caa3a238866b Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Sat, 9 Jan 2010 20:35:09 +0000 Subject: Issue #1023290: Added API for the conversion of longs to bytes and vice-versa. --- Objects/longobject.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 2e2eca8e45..cfe7b5c748 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4296,6 +4296,201 @@ long_is_finite(PyObject *v) } #endif + +PyDoc_STRVAR(long_to_bytes_doc, +"int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\ +\n\ +Return an array of bytes representing an integer.\n\ +\n\ +The integer is represented using length bytes. An OverflowError is\n\ +raised if the integer is not representable with the given number of\n\ +bytes.\n\ +\n\ +The byteorder argument determines the byte order used to represent the\n\ +integer. If byteorder is 'big', the most significant byte is at the\n\ +beginning of the byte array. If byteorder is 'little', the most\n\ +significant byte is at the end of the byte array. To request the native\n\ +byte order of the host system, use `sys.byteorder' as the byte order value.\n\ +\n\ +The signed keyword-only argument determines whether two's complement is\n\ +used to represent the integer. If signed is False and a negative integer\n\ +is given, an OverflowError is raised."); + +static PyObject * +long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) +{ + PyObject *byteorder_str; + PyObject *is_signed_obj = NULL; + Py_ssize_t length; + int little_endian; + int is_signed; + PyObject *bytes; + static PyObject *little_str = NULL, *big_str = NULL; + static char *kwlist[] = {"length", "byteorder", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "nO|O:to_bytes", kwlist, + &length, &byteorder_str, + &is_signed_obj)) + return NULL; + + if (args != NULL && Py_SIZE(args) > 2) { + PyErr_SetString(PyExc_TypeError, + "'signed' is a keyword-only argument"); + return NULL; + } + if (little_str == NULL) { + little_str = PyUnicode_InternFromString("little"); + big_str = PyUnicode_InternFromString("big"); + if (little_str == NULL || big_str == NULL) + return NULL; + } + + if (PyObject_RichCompareBool(byteorder_str, little_str, Py_EQ)) + little_endian = 1; + else if (PyObject_RichCompareBool(byteorder_str, big_str, Py_EQ)) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + if (is_signed_obj != NULL) { + int cmp = PyObject_IsTrue(is_signed_obj); + if (cmp < 0) + return NULL; + is_signed = cmp ? 1 : 0; + } + else { + /* If the signed argument was omitted, use False as the + default. */ + is_signed = 0; + } + + if (length < 0) { + PyErr_SetString(PyExc_ValueError, + "length argument must be non-negative"); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, length); + if (bytes == NULL) + return NULL; + + if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes), + length, little_endian, is_signed) < 0) { + Py_DECREF(bytes); + return NULL; + } + + return bytes; +} + +PyDoc_STRVAR(long_from_bytes_doc, +"int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\ +\n\ +Return the integer represented by the given array of bytes.\n\ +\n\ +The bytes argument must either support the buffer protocol or be an\n\ +iterable object producing bytes. Bytes and bytearray are examples of\n\ +built-in objects that support the buffer protocol.\n\ +\n\ +The byteorder argument determines the byte order used to represent the\n\ +integer. If byteorder is 'big', the most significant byte is at the\n\ +beginning of the byte array. If byteorder is 'little', the most\n\ +significant byte is at the end of the byte array. To request the native\n\ +byte order of the host system, use `sys.byteorder' as the byte order value.\n\ +\n\ +The signed keyword-only argument indicates whether two's complement is\n\ +used to represent the integer."); + +static PyObject * +long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *byteorder_str; + PyObject *is_signed_obj = NULL; + int little_endian; + int is_signed; + PyObject *obj; + PyObject *bytes; + PyObject *long_obj; + static PyObject *little_str = NULL, *big_str = NULL; + static char *kwlist[] = {"bytes", "byteorder", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:from_bytes", kwlist, + &obj, &byteorder_str, + &is_signed_obj)) + return NULL; + + if (args != NULL && Py_SIZE(args) > 2) { + PyErr_SetString(PyExc_TypeError, + "'signed' is a keyword-only argument"); + return NULL; + } + if (little_str == NULL) { + little_str = PyUnicode_InternFromString("little"); + big_str = PyUnicode_InternFromString("big"); + if (little_str == NULL || big_str == NULL) + return NULL; + } + + if (PyObject_RichCompareBool(byteorder_str, little_str, Py_EQ)) + little_endian = 1; + else if (PyObject_RichCompareBool(byteorder_str, big_str, Py_EQ)) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + if (is_signed_obj != NULL) { + int cmp = PyObject_IsTrue(is_signed_obj); + if (cmp < 0) + return NULL; + is_signed = cmp ? 1 : 0; + } + else { + /* If the signed argument was omitted, use False as the + default. */ + is_signed = 0; + } + + bytes = PyObject_Bytes(obj); + if (bytes == NULL) + return NULL; + + long_obj = _PyLong_FromByteArray( + (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), + little_endian, is_signed); + Py_DECREF(bytes); + + /* If from_bytes() was used on subclass, allocate new subclass + * instance, initialize it with decoded long value and return it. + */ + if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { + PyLongObject *newobj; + int i; + Py_ssize_t n = ABS(Py_SIZE(long_obj)); + + newobj = (PyLongObject *)type->tp_alloc(type, n); + if (newobj == NULL) { + Py_DECREF(long_obj); + return NULL; + } + assert(PyLong_Check(newobj)); + Py_SIZE(newobj) = Py_SIZE(long_obj); + for (i = 0; i < n; i++) { + newobj->ob_digit[i] = + ((PyLongObject *)long_obj)->ob_digit[i]; + } + Py_DECREF(long_obj); + return (PyObject *)newobj; + } + + return long_obj; +} + static PyMethodDef long_methods[] = { {"conjugate", (PyCFunction)long_long, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -4305,6 +4500,10 @@ static PyMethodDef long_methods[] = { {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, "Returns always True."}, #endif + {"to_bytes", (PyCFunction)long_to_bytes, + METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc}, + {"from_bytes", (PyCFunction)long_from_bytes, + METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc}, {"__trunc__", (PyCFunction)long_long, METH_NOARGS, "Truncating an Integral returns itself."}, {"__floor__", (PyCFunction)long_long, METH_NOARGS, -- cgit v1.2.1 From 5eed9352062944454ea8c1e7cef1f901b8936d1d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 9 Jan 2010 21:45:28 +0000 Subject: Python strings ending with '\0' should not be equivalent to their C counterparts in PyUnicode_CompareWithASCIIString --- Objects/unicodeobject.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9c0be9b23c..40377ea48d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7001,6 +7001,11 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) for (i = 0; id[i] && str[i]; i++) if (id[i] != str[i]) return ((int)id[i] < (int)str[i]) ? -1 : 1; + /* This check keeps Python strings that end in '\0' from comparing equal + to C strings identical up to that point. */ + if (PyUnicode_GET_SIZE(uni) != i) + /* We'll say the Python string is longer. */ + return 1; if (id[i]) return 1; /* uni is longer */ if (str[i]) -- cgit v1.2.1 From 74d5cadd3c16d3c6782712c50f7221197f60d62c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 9 Jan 2010 21:50:11 +0000 Subject: simplify string comparison of from_bytes/to_bytes --- Objects/longobject.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index cfe7b5c748..afac856cd0 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4325,10 +4325,9 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) int little_endian; int is_signed; PyObject *bytes; - static PyObject *little_str = NULL, *big_str = NULL; static char *kwlist[] = {"length", "byteorder", "signed", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "nO|O:to_bytes", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist, &length, &byteorder_str, &is_signed_obj)) return NULL; @@ -4338,16 +4337,10 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) "'signed' is a keyword-only argument"); return NULL; } - if (little_str == NULL) { - little_str = PyUnicode_InternFromString("little"); - big_str = PyUnicode_InternFromString("big"); - if (little_str == NULL || big_str == NULL) - return NULL; - } - if (PyObject_RichCompareBool(byteorder_str, little_str, Py_EQ)) + if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) little_endian = 1; - else if (PyObject_RichCompareBool(byteorder_str, big_str, Py_EQ)) + else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) little_endian = 0; else { PyErr_SetString(PyExc_ValueError, @@ -4414,10 +4407,9 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *obj; PyObject *bytes; PyObject *long_obj; - static PyObject *little_str = NULL, *big_str = NULL; static char *kwlist[] = {"bytes", "byteorder", "signed", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:from_bytes", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist, &obj, &byteorder_str, &is_signed_obj)) return NULL; @@ -4427,16 +4419,10 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) "'signed' is a keyword-only argument"); return NULL; } - if (little_str == NULL) { - little_str = PyUnicode_InternFromString("little"); - big_str = PyUnicode_InternFromString("big"); - if (little_str == NULL || big_str == NULL) - return NULL; - } - if (PyObject_RichCompareBool(byteorder_str, little_str, Py_EQ)) + if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) little_endian = 1; - else if (PyObject_RichCompareBool(byteorder_str, big_str, Py_EQ)) + else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) little_endian = 0; else { PyErr_SetString(PyExc_ValueError, -- cgit v1.2.1 From fd21a89c70d7960e568d56bd19255a8c7a8d493a Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Sat, 9 Jan 2010 22:14:46 +0000 Subject: Issue #6688: Optimize PyBytes_FromObject(). - Add special-cases for list and tuple objects. - Use _PyObject_LengthHint() instead of an arbitrary value for the size of the initial buffer of the returned object. --- Objects/bytesobject.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index cb634481bd..eb11940ccf 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2979,17 +2979,62 @@ PyBytes_FromObject(PyObject *x) return NULL; } + if (PyList_CheckExact(x)) { + new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); + if (new == NULL) + return NULL; + for (i = 0; i < Py_SIZE(x); i++) { + Py_ssize_t value = PyNumber_AsSsize_t( + PyList_GET_ITEM(x, i), PyExc_ValueError); + if (value == -1 && PyErr_Occurred()) { + Py_DECREF(new); + return NULL; + } + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + Py_DECREF(new); + return NULL; + } + ((PyBytesObject *)new)->ob_sval[i] = value; + } + return new; + } + if (PyTuple_CheckExact(x)) { + new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); + if (new == NULL) + return NULL; + for (i = 0; i < Py_SIZE(x); i++) { + Py_ssize_t value = PyNumber_AsSsize_t( + PyTuple_GET_ITEM(x, i), PyExc_ValueError); + if (value == -1 && PyErr_Occurred()) { + Py_DECREF(new); + return NULL; + } + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + Py_DECREF(new); + return NULL; + } + ((PyBytesObject *)new)->ob_sval[i] = value; + } + return new; + } + /* For iterator version, create a string object and resize as needed */ - /* XXX(gb): is 64 a good value? also, optimize if length is known */ - /* XXX(guido): perhaps use Pysequence_Fast() -- I can't imagine the - input being a truly long iterator. */ - size = 64; + size = _PyObject_LengthHint(x, 64); + if (size == -1 && PyErr_Occurred()) + return NULL; + /* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from + returning a shared empty bytes string. This required because we + want to call _PyBytes_Resize() the returned object, which we can + only do on bytes objects with refcount == 1. */ + size += 1; new = PyBytes_FromStringAndSize(NULL, size); if (new == NULL) return NULL; - /* XXX Optimize this if the arguments is a list, tuple */ - /* Get the iterator */ it = PyObject_GetIter(x); if (it == NULL) @@ -3023,7 +3068,7 @@ PyBytes_FromObject(PyObject *x) /* Append the byte */ if (i >= size) { - size *= 2; + size = 2 * size + 1; if (_PyBytes_Resize(&new, size) < 0) goto error; } -- cgit v1.2.1 From 34f637dff18b243a0b75f22dc5b3a5bdb98f97a0 Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Tue, 12 Jan 2010 01:23:09 +0000 Subject: Issue #7382: Fix bytes.__getnewargs__. --- Objects/bytesobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index eb11940ccf..680a769490 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2807,7 +2807,7 @@ bytes_sizeof(PyBytesObject *v) static PyObject * bytes_getnewargs(PyBytesObject *v) { - return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v)); + return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); } -- cgit v1.2.1 From 26447c09d91747bda7e3589685ede476c1faab4c Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 13 Jan 2010 08:07:53 +0000 Subject: Merged revisions 77461 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77461 | antoine.pitrou | 2010-01-13 08:55:48 +0100 (mer., 13 janv. 2010) | 5 lines Issue #7622: Improve the split(), rsplit(), splitlines() and replace() methods of bytes, bytearray and unicode objects by using a common implementation based on stringlib's fast search. Patch by Florent Xicluna. ........ --- Objects/bytearrayobject.c | 506 ++++--------------------- Objects/bytesobject.c | 523 ++++---------------------- Objects/stringlib/count.h | 16 +- Objects/stringlib/ctype.h | 1 - Objects/stringlib/fastsearch.h | 40 +- Objects/stringlib/find.h | 56 ++- Objects/stringlib/partition.h | 83 +++-- Objects/stringlib/split.h | 788 +++++++++++++++++++++++++++++++++++++++ Objects/stringlib/stringdefs.h | 2 + Objects/stringlib/transmogrify.h | 91 ----- Objects/stringlib/unicodedefs.h | 2 + Objects/unicodeobject.c | 420 ++++----------------- 12 files changed, 1110 insertions(+), 1418 deletions(-) create mode 100644 Objects/stringlib/split.h (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 827c47b1df..823c800a50 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1039,14 +1039,16 @@ bytearray_dealloc(PyByteArrayObject *self) #define STRINGLIB_STR PyByteArray_AS_STRING #define STRINGLIB_NEW PyByteArray_FromStringAndSize #define STRINGLIB_EMPTY nullbytes +#define STRINGLIB_ISSPACE Py_ISSPACE +#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact #define STRINGLIB_MUTABLE 1 -#define FROM_BYTEARRAY 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" @@ -1054,21 +1056,20 @@ bytearray_dealloc(PyByteArrayObject *self) /* The following Py_LOCAL_INLINE and Py_LOCAL functions were copied from the old char* style string object. */ -Py_LOCAL_INLINE(void) -_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t 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; -} - +/* 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) @@ -1136,10 +1137,10 @@ bytearray_count(PyByteArrayObject *self, PyObject *args) if (_getbuffer(sub_obj, &vsub) < 0) return NULL; - _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self)); + ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self)); count_obj = PyLong_FromSsize_t( - stringlib_count(str + start, end - start, vsub.buf, vsub.len) + stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX) ); PyBuffer_Release(&vsub); return count_obj; @@ -1247,7 +1248,7 @@ _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start if (_getbuffer(substr, &vsubstr) < 0) return -1; - _adjust_indices(&start, &end, len); + ADJUST_INDICES(start, end, len); if (direction < 0) { /* startswith */ @@ -1459,20 +1460,11 @@ bytearray_maketrans(PyObject *null, PyObject *args) } -#define FORWARD 1 -#define REVERSE -1 - /* find and count characters and substrings */ #define findchar(target, target_len, c) \ ((char *)memchr((const void *)(target), c, target_len)) -/* Don't call if length < 2 */ -#define Py_STRING_MATCH(target, offset, pattern, length) \ - (target[offset] == pattern[0] && \ - target[offset+length-1] == pattern[length-1] && \ - !memcmp(target+offset+1, pattern+1, length-2) ) - /* Bytes ops must return a string, create a copy */ Py_LOCAL(PyByteArrayObject *) @@ -1500,93 +1492,6 @@ countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount return count; } -Py_LOCAL(Py_ssize_t) -findstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction) -{ - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings always match at the first attempt */ - if (pattern_len == 0) - return (direction > 0) ? start : end; - - end -= pattern_len; - - if (direction < 0) { - for (; end >= start; end--) - if (Py_STRING_MATCH(target, end, pattern, pattern_len)) - return end; - } else { - for (; start <= end; start++) - if (Py_STRING_MATCH(target, start, pattern, pattern_len)) - return start; - } - return -1; -} - -Py_LOCAL_INLINE(Py_ssize_t) -countstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction, Py_ssize_t maxcount) -{ - Py_ssize_t count=0; - - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings match everywhere */ - if (pattern_len == 0 || maxcount == 0) { - if (target_len+1 < maxcount) - return target_len+1; - return maxcount; - } - - end -= pattern_len; - if (direction < 0) { - for (; (end >= start); end--) - if (Py_STRING_MATCH(target, end, pattern, pattern_len)) { - count++; - if (--maxcount <= 0) break; - end -= pattern_len-1; - } - } else { - for (; (start <= end); start++) - if (Py_STRING_MATCH(target, start, pattern, pattern_len)) { - count++; - if (--maxcount <= 0) - break; - start += pattern_len-1; - } - } - return count; -} - /* Algorithms for different cases of string replacement */ @@ -1708,10 +1613,9 @@ replace_delete_substring(PyByteArrayObject *self, self_len = PyByteArray_GET_SIZE(self); self_s = PyByteArray_AS_STRING(self); - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, 1, - maxcount); + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); if (count == 0) { /* no matches */ @@ -1730,9 +1634,9 @@ replace_delete_substring(PyByteArrayObject *self, start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset == -1) break; next = start + offset; @@ -1808,9 +1712,9 @@ replace_substring_in_place(PyByteArrayObject *self, self_s = PyByteArray_AS_STRING(self); self_len = PyByteArray_GET_SIZE(self); - offset = findstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD); + 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); @@ -1830,9 +1734,9 @@ replace_substring_in_place(PyByteArrayObject *self, end = result_s + self_len; while ( --maxcount > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset==-1) break; Py_MEMCPY(start+offset, to_s, from_len); @@ -1925,9 +1829,10 @@ replace_substring(PyByteArrayObject *self, self_s = PyByteArray_AS_STRING(self); self_len = PyByteArray_GET_SIZE(self); - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD, maxcount); + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); + if (count == 0) { /* no matches, return unchanged */ return return_self(self); @@ -1954,9 +1859,9 @@ replace_substring(PyByteArrayObject *self, start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset == -1) break; next = start+offset; @@ -2085,123 +1990,6 @@ bytearray_replace(PyByteArrayObject *self, PyObject *args) return res; } - -/* 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) \ - str = PyByteArray_FromStringAndSize((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); - -#define SPLIT_ADD(data, left, right) { \ - str = PyByteArray_FromStringAndSize((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (count < MAX_PREALLOC) { \ - PyList_SET_ITEM(list, count, str); \ - } else { \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); \ - } \ - count++; } - -/* Always force the list to the expected size. */ -#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count - - -Py_LOCAL_INLINE(PyObject *) -split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = 0; - while ((j < len) && (maxcount-- > 0)) { - for(; j < len; j++) { - /* I found that using memchr makes no difference */ - if (s[j] == ch) { - SPLIT_ADD(s, i, j); - i = j = j + 1; - break; - } - } - } - if (i <= len) { - SPLIT_ADD(s, i, len); - } - FIX_PREALLOC_SIZE(list); - return list; - - onError: - Py_DECREF(list); - return NULL; -} - - -Py_LOCAL_INLINE(PyObject *) -split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - for (i = j = 0; i < len; ) { - /* find a token */ - while (i < len && Py_ISSPACE(s[i])) - i++; - j = i; - while (i < len && !Py_ISSPACE(s[i])) - i++; - if (j < i) { - if (maxcount-- <= 0) - break; - SPLIT_ADD(s, j, i); - while (i < len && Py_ISSPACE(s[i])) - i++; - j = i; - } - } - if (j < len) { - SPLIT_ADD(s, j, len); - } - FIX_PREALLOC_SIZE(list); - return list; - - onError: - Py_DECREF(list); - return NULL; -} - PyDoc_STRVAR(split__doc__, "B.split([sep[, maxsplit]]) -> list of bytearrays\n\ \n\ @@ -2213,10 +2001,10 @@ 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, i, j, pos; - Py_ssize_t maxsplit = -1, count = 0; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *str, *subobj = Py_None; + PyObject *list, *subobj = Py_None; Py_buffer vsub; if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit)) @@ -2225,73 +2013,18 @@ bytearray_split(PyByteArrayObject *self, PyObject *args) maxsplit = PY_SSIZE_T_MAX; if (subobj == Py_None) - return split_whitespace(s, len, maxsplit); + return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); if (_getbuffer(subobj, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyBuffer_Release(&vsub); - return NULL; - } - if (n == 1) { - list = split_char(s, len, sub[0], maxsplit); - PyBuffer_Release(&vsub); - return list; - } - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyBuffer_Release(&vsub); - return NULL; - } - - i = j = 0; - while (maxsplit-- > 0) { - pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH); - if (pos < 0) - break; - j = i+pos; - SPLIT_ADD(s, i, j); - i = j + n; - } - SPLIT_ADD(s, i, len); - FIX_PREALLOC_SIZE(list); + list = stringlib_split( + (PyObject*) self, s, len, sub, n, maxsplit + ); PyBuffer_Release(&vsub); return list; - - onError: - Py_DECREF(list); - PyBuffer_Release(&vsub); - return NULL; -} - -/* stringlib's partition shares nullbytes in some cases. - undo this, we don't want the nullbytes to be shared. */ -static PyObject * -make_nullbytes_unique(PyObject *result) -{ - if (result != NULL) { - int i; - assert(PyTuple_Check(result)); - assert(PyTuple_GET_SIZE(result) == 3); - for (i = 0; i < 3; i++) { - if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) { - PyObject *new = PyByteArray_FromStringAndSize(NULL, 0); - if (new == NULL) { - Py_DECREF(result); - result = NULL; - break; - } - Py_DECREF(nullbytes); - PyTuple_SET_ITEM(result, i, new); - } - } - } - return result; } PyDoc_STRVAR(partition__doc__, @@ -2318,7 +2051,7 @@ bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) ); Py_DECREF(bytesep); - return make_nullbytes_unique(result); + return result; } PyDoc_STRVAR(rpartition__doc__, @@ -2346,81 +2079,7 @@ bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) ); Py_DECREF(bytesep); - return make_nullbytes_unique(result); -} - -Py_LOCAL_INLINE(PyObject *) -rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = len - 1; - while ((i >= 0) && (maxcount-- > 0)) { - for (; i >= 0; i--) { - if (s[i] == ch) { - SPLIT_ADD(s, i + 1, j + 1); - j = i = i - 1; - break; - } - } - } - if (j >= -1) { - SPLIT_ADD(s, 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 *) -rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount) -{ - register Py_ssize_t i, j, count = 0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - for (i = j = len - 1; i >= 0; ) { - /* find a token */ - while (i >= 0 && Py_ISSPACE(s[i])) - i--; - j = i; - while (i >= 0 && !Py_ISSPACE(s[i])) - i--; - if (j > i) { - if (maxcount-- <= 0) - break; - SPLIT_ADD(s, i + 1, j + 1); - while (i >= 0 && Py_ISSPACE(s[i])) - i--; - j = i; - } - } - if (j >= 0) { - SPLIT_ADD(s, 0, j + 1); - } - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; - - return list; - - onError: - Py_DECREF(list); - return NULL; + return result; } PyDoc_STRVAR(rsplit__doc__, @@ -2435,10 +2094,10 @@ 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, j, pos; - Py_ssize_t maxsplit = -1, count = 0; + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *str, *subobj = Py_None; + PyObject *list, *subobj = Py_None; Py_buffer vsub; if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit)) @@ -2447,50 +2106,18 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *args) maxsplit = PY_SSIZE_T_MAX; if (subobj == Py_None) - return rsplit_whitespace(s, len, maxsplit); + return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); if (_getbuffer(subobj, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyBuffer_Release(&vsub); - return NULL; - } - else if (n == 1) { - list = rsplit_char(s, len, sub[0], maxsplit); - PyBuffer_Release(&vsub); - return list; - } - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyBuffer_Release(&vsub); - return NULL; - } - - j = len; - - while (maxsplit-- > 0) { - pos = fastsearch(s, j, sub, n, FAST_RSEARCH); - if (pos < 0) - break; - SPLIT_ADD(s, pos + n, j); - j = pos; - } - SPLIT_ADD(s, 0, j); - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; + list = stringlib_rsplit( + (PyObject*) self, s, len, sub, n, maxsplit + ); PyBuffer_Release(&vsub); return list; - -onError: - Py_DECREF(list); - PyBuffer_Release(&vsub); - return NULL; } PyDoc_STRVAR(reverse__doc__, @@ -2956,6 +2583,27 @@ bytearray_join(PyByteArrayObject *self, PyObject *it) return NULL; } +PyDoc_STRVAR(splitlines__doc__, +"B.splitlines([keepends]) -> 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 (static method)\n\ \n\ @@ -3134,7 +2782,7 @@ bytearray_methods[] = { {"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)stringlib_splitlines, METH_VARARGS, + {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS, splitlines__doc__}, {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 680a769490..183722ca74 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -56,7 +56,7 @@ static PyBytesObject *nullstring; If `str' is NULL then PyBytes_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 + PyBytes 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 @@ -568,9 +568,9 @@ PyBytes_AsStringAndSize(register PyObject *obj, #include "stringlib/count.h" #include "stringlib/find.h" #include "stringlib/partition.h" +#include "stringlib/split.h" #include "stringlib/ctype.h" -#define STRINGLIB_MUTABLE 0 #include "stringlib/transmogrify.h" PyObject * @@ -1000,133 +1000,6 @@ static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"}; #define STRIPNAME(i) (stripformat[i]+3) - -/* Don't call if length < 2 */ -#define Py_STRING_MATCH(target, offset, pattern, length) \ - (target[offset] == pattern[0] && \ - target[offset+length-1] == pattern[length-1] && \ - !memcmp(target+offset+1, pattern+1, length-2) ) - - -/* 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_ADD(data, left, right) { \ - str = PyBytes_FromStringAndSize((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (count < MAX_PREALLOC) { \ - PyList_SET_ITEM(list, count, str); \ - } else { \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); \ - } \ - count++; } - -/* Always force the list to the expected size. */ -#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count - -#define SKIP_SPACE(s, i, len) { while (i=0 && ISSPACE(s[i])) i--; } -#define RSKIP_NONSPACE(s, i) { while (i>=0 && !ISSPACE(s[i])) i--; } - -Py_LOCAL_INLINE(PyObject *) -split_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit) -{ - const char *s = PyBytes_AS_STRING(self); - Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit)); - - if (list == NULL) - return NULL; - - i = j = 0; - - while (maxsplit-- > 0) { - SKIP_SPACE(s, i, len); - if (i==len) break; - j = i; i++; - SKIP_NONSPACE(s, i, len); - if (j == 0 && i == len && PyBytes_CheckExact(self)) { - /* No whitespace in self, so just use it as list[0] */ - Py_INCREF(self); - PyList_SET_ITEM(list, 0, (PyObject *)self); - count++; - break; - } - SPLIT_ADD(s, j, i); - } - - if (i < len) { - /* Only occurs when maxsplit was reached */ - /* Skip any remaining whitespace and copy to end of string */ - SKIP_SPACE(s, i, len); - if (i != len) - SPLIT_ADD(s, i, len); - } - FIX_PREALLOC_SIZE(list); - return list; - onError: - Py_DECREF(list); - return NULL; -} - -Py_LOCAL_INLINE(PyObject *) -split_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - const char *s = PyBytes_AS_STRING(self); - register Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = 0; - while ((j < len) && (maxcount-- > 0)) { - for(; j list of bytes\n\ \n\ @@ -1138,74 +1011,26 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * bytes_split(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; - Py_ssize_t maxsplit = -1, count=0; + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *str, *subobj = Py_None; -#ifdef USE_FAST - Py_ssize_t pos; -#endif + PyObject *list, *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 split_whitespace(self, len, maxsplit); + return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); if (_getbuffer(subobj, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyBuffer_Release(&vsub); - return NULL; - } - else if (n == 1) { - list = split_char(self, len, sub[0], maxsplit); - PyBuffer_Release(&vsub); - return list; - } - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyBuffer_Release(&vsub); - return NULL; - } - -#ifdef USE_FAST - i = j = 0; - while (maxsplit-- > 0) { - pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH); - if (pos < 0) - break; - j = i+pos; - SPLIT_ADD(s, i, j); - i = j + n; - } -#else - i = j = 0; - while ((j+n <= len) && (maxsplit-- > 0)) { - for (; j+n <= len; j++) { - if (Py_STRING_MATCH(s, j, sub, n)) { - SPLIT_ADD(s, i, j); - i = j = j + n; - break; - } - } - } -#endif - SPLIT_ADD(s, i, len); - FIX_PREALLOC_SIZE(list); + list = stringlib_split((PyObject*) self, s, len, sub, n, maxsplit); PyBuffer_Release(&vsub); return list; - - onError: - Py_DECREF(list); - PyBuffer_Release(&vsub); - return NULL; } PyDoc_STRVAR(partition__doc__, @@ -1263,90 +1088,6 @@ bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) ); } -Py_LOCAL_INLINE(PyObject *) -rsplit_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit) -{ - const char *s = PyBytes_AS_STRING(self); - Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit)); - - if (list == NULL) - return NULL; - - i = j = len-1; - - while (maxsplit-- > 0) { - RSKIP_SPACE(s, i); - if (i<0) break; - j = i; i--; - RSKIP_NONSPACE(s, i); - if (j == len-1 && i < 0 && PyBytes_CheckExact(self)) { - /* No whitespace in self, so just use it as list[0] */ - Py_INCREF(self); - PyList_SET_ITEM(list, 0, (PyObject *)self); - count++; - break; - } - SPLIT_ADD(s, i + 1, j + 1); - } - if (i >= 0) { - /* Only occurs when maxsplit was reached. Skip any remaining - whitespace and copy to beginning of string. */ - RSKIP_SPACE(s, i); - if (i >= 0) - SPLIT_ADD(s, 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 *) -rsplit_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount) -{ - const char *s = PyBytes_AS_STRING(self); - register Py_ssize_t i, j, count=0; - PyObject *str; - PyObject *list = PyList_New(PREALLOC_SIZE(maxcount)); - - if (list == NULL) - return NULL; - - i = j = len - 1; - while ((i >= 0) && (maxcount-- > 0)) { - for (; i >= 0; i--) { - if (s[i] == ch) { - SPLIT_ADD(s, i + 1, j + 1); - j = i = i - 1; - break; - } - } - } - if (i < 0 && count == 0 && PyBytes_CheckExact(self)) { - /* ch not in self, so just use self as list[0] */ - Py_INCREF(self); - PyList_SET_ITEM(list, 0, (PyObject *)self); - count++; - } - else if (j >= -1) { - SPLIT_ADD(s, 0, j + 1); - } - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; - return list; - - onError: - Py_DECREF(list); - return NULL; -} - PyDoc_STRVAR(rsplit__doc__, "B.rsplit([sep[, maxsplit]]) -> list of bytes\n\ \n\ @@ -1360,71 +1101,28 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; - Py_ssize_t maxsplit = -1, count=0; - const char *s, *sub; + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; + const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *str, *subobj = Py_None; + PyObject *list, *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 rsplit_whitespace(self, len, maxsplit); + return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); if (_getbuffer(subobj, &vsub) < 0) return NULL; sub = vsub.buf; n = vsub.len; - if (n == 0) { - PyErr_SetString(PyExc_ValueError, "empty separator"); - PyBuffer_Release(&vsub); - return NULL; - } - else if (n == 1) { - list = rsplit_char(self, len, sub[0], maxsplit); - PyBuffer_Release(&vsub); - return list; - } - - list = PyList_New(PREALLOC_SIZE(maxsplit)); - if (list == NULL) { - PyBuffer_Release(&vsub); - return NULL; - } - - j = len; - i = j - n; - - s = PyBytes_AS_STRING(self); - while ( (i >= 0) && (maxsplit-- > 0) ) { - for (; i>=0; i--) { - if (Py_STRING_MATCH(s, i, sub, n)) { - SPLIT_ADD(s, i + n, j); - j = i; - i -= n; - break; - } - } - } - SPLIT_ADD(s, 0, j); - FIX_PREALLOC_SIZE(list); - if (PyList_Reverse(list) < 0) - goto onError; + list = stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit); PyBuffer_Release(&vsub); return list; - -onError: - Py_DECREF(list); - PyBuffer_Release(&vsub); - return NULL; } -#undef SPLIT_ADD -#undef MAX_PREALLOC -#undef PREALLOC_SIZE - PyDoc_STRVAR(join__doc__, "B.join(iterable_of_bytes) -> bytes\n\ @@ -1531,20 +1229,20 @@ _PyBytes_Join(PyObject *sep, PyObject *x) return bytes_join(sep, x); } -Py_LOCAL_INLINE(void) -bytes_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t 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; -} +/* 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) bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) @@ -1591,7 +1289,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) PyDoc_STRVAR(find__doc__, "B.find(sub[, start[, end]]) -> int\n\ \n\ -Return the lowest index in S where substring sub is found,\n\ +Return the lowest index in B 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\ @@ -1801,7 +1499,7 @@ PyDoc_STRVAR(count__doc__, "B.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\ +string B[start:end]. Optional arguments start and end are interpreted\n\ as in slice notation."); static PyObject * @@ -1823,10 +1521,10 @@ bytes_count(PyBytesObject *self, PyObject *args) else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) return NULL; - bytes_adjust_indices(&start, &end, PyBytes_GET_SIZE(self)); + ADJUST_INDICES(start, end, PyBytes_GET_SIZE(self)); return PyLong_FromSsize_t( - stringlib_count(str + start, end - start, sub, sub_len) + stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) ); } @@ -1943,9 +1641,6 @@ bytes_maketrans(PyObject *null, PyObject *args) return _Py_bytes_maketrans(args); } -#define FORWARD 1 -#define REVERSE -1 - /* find and count characters and substrings */ #define findchar(target, target_len, c) \ @@ -1981,94 +1676,6 @@ countchar(const char *target, int target_len, char c, Py_ssize_t maxcount) return count; } -Py_LOCAL(Py_ssize_t) -findstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction) -{ - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings always match at the first attempt */ - if (pattern_len == 0) - return (direction > 0) ? start : end; - - end -= pattern_len; - - if (direction < 0) { - for (; end >= start; end--) - if (Py_STRING_MATCH(target, end, pattern, pattern_len)) - return end; - } else { - for (; start <= end; start++) - if (Py_STRING_MATCH(target, start,pattern,pattern_len)) - return start; - } - return -1; -} - -Py_LOCAL_INLINE(Py_ssize_t) -countstring(const char *target, Py_ssize_t target_len, - const char *pattern, Py_ssize_t pattern_len, - Py_ssize_t start, - Py_ssize_t end, - int direction, Py_ssize_t maxcount) -{ - Py_ssize_t count=0; - - if (start < 0) { - start += target_len; - if (start < 0) - start = 0; - } - if (end > target_len) { - end = target_len; - } else if (end < 0) { - end += target_len; - if (end < 0) - end = 0; - } - - /* zero-length substrings match everywhere */ - if (pattern_len == 0 || maxcount == 0) { - if (target_len+1 < maxcount) - return target_len+1; - return maxcount; - } - - end -= pattern_len; - if (direction < 0) { - for (; (end >= start); end--) - if (Py_STRING_MATCH(target, end,pattern,pattern_len)) { - count++; - if (--maxcount <= 0) break; - end -= pattern_len-1; - } - } else { - for (; (start <= end); start++) - if (Py_STRING_MATCH(target, start, - pattern, pattern_len)) { - count++; - if (--maxcount <= 0) - break; - start += pattern_len-1; - } - } - return count; -} - /* Algorithms for different cases of string replacement */ @@ -2189,10 +1796,9 @@ replace_delete_substring(PyBytesObject *self, self_len = PyBytes_GET_SIZE(self); self_s = PyBytes_AS_STRING(self); - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, 1, - maxcount); + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); if (count == 0) { /* no matches */ @@ -2211,9 +1817,9 @@ replace_delete_substring(PyBytesObject *self, start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset == -1) break; next = start + offset; @@ -2289,9 +1895,9 @@ replace_substring_in_place(PyBytesObject *self, self_s = PyBytes_AS_STRING(self); self_len = PyBytes_GET_SIZE(self); - offset = findstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD); + 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); @@ -2311,9 +1917,9 @@ replace_substring_in_place(PyBytesObject *self, end = result_s + self_len; while ( --maxcount > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset==-1) break; Py_MEMCPY(start+offset, to_s, from_len); @@ -2407,9 +2013,10 @@ replace_substring(PyBytesObject *self, self_s = PyBytes_AS_STRING(self); self_len = PyBytes_GET_SIZE(self); - count = countstring(self_s, self_len, - from_s, from_len, - 0, self_len, FORWARD, maxcount); + count = stringlib_count(self_s, self_len, + from_s, from_len, + maxcount); + if (count == 0) { /* no matches, return unchanged */ return return_self(self); @@ -2438,9 +2045,9 @@ replace_substring(PyBytesObject *self, start = self_s; end = self_s + self_len; while (count-- > 0) { - offset = findstring(start, end-start, - from_s, from_len, - 0, end-start, FORWARD); + offset = stringlib_find(start, end-start, + from_s, from_len, + 0); if (offset == -1) break; next = start+offset; @@ -2598,7 +2205,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, return -1; str = PyBytes_AS_STRING(self); - bytes_adjust_indices(&start, &end, len); + ADJUST_INDICES(start, end, len); if (direction < 0) { /* startswith */ @@ -2703,7 +2310,7 @@ bytes_endswith(PyBytesObject *self, PyObject *args) PyDoc_STRVAR(decode__doc__, "B.decode([encoding[, errors]]) -> str\n\ \n\ -Decode S using the codec registered for encoding. encoding defaults\n\ +Decode 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\ @@ -2725,6 +2332,28 @@ bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) } +PyDoc_STRVAR(splitlines__doc__, +"B.splitlines([keepends]) -> 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* +bytes_splitlines(PyObject *self, PyObject *args) +{ + int keepends = 0; + + if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) + return NULL; + + return stringlib_splitlines( + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); +} + + PyDoc_STRVAR(fromhex_doc, "bytes.fromhex(string) -> bytes\n\ \n\ @@ -2857,7 +2486,7 @@ bytes_methods[] = { {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, - {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, + {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS, splitlines__doc__}, {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, @@ -3239,7 +2868,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) /* _PyBytes_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. + * Return value: a new PyBytes*, 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. diff --git a/Objects/stringlib/count.h b/Objects/stringlib/count.h index eba37e9cc8..de34f96b3e 100644 --- a/Objects/stringlib/count.h +++ b/Objects/stringlib/count.h @@ -9,28 +9,22 @@ 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) + 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 + 1; + return (str_len < maxcount) ? str_len + 1 : maxcount; - count = fastsearch(str, str_len, sub, sub_len, FAST_COUNT); + count = fastsearch(str, str_len, sub, sub_len, maxcount, FAST_COUNT); if (count < 0) - count = 0; /* no match */ + return 0; /* no match */ return count; } #endif - -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ diff --git a/Objects/stringlib/ctype.h b/Objects/stringlib/ctype.h index 8951276814..739cf3d9eb 100644 --- a/Objects/stringlib/ctype.h +++ b/Objects/stringlib/ctype.h @@ -107,4 +107,3 @@ stringlib_swapcase(PyObject *self) STRINGLIB_LEN(self)); return newobj; } - diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 7b9dd47a5d..21cf3a2ab7 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -18,10 +18,13 @@ #define FAST_SEARCH 1 #define FAST_RSEARCH 2 +#define BLOOM_ADD(mask, ch) ((mask |= (1 << ((ch) & (LONG_BIT - 1))))) +#define BLOOM(mask, ch) ((mask & (1 << ((ch) & (LONG_BIT - 1))))) + Py_LOCAL_INLINE(Py_ssize_t) fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, const STRINGLIB_CHAR* p, Py_ssize_t m, - int mode) + Py_ssize_t maxcount, int mode) { long mask; Py_ssize_t skip, count = 0; @@ -29,7 +32,7 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, w = n - m; - if (w < 0) + if (w < 0 || (mode == FAST_COUNT && maxcount == 0)) return -1; /* look for special cases */ @@ -39,8 +42,11 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* use special case for 1-character strings */ if (mode == FAST_COUNT) { for (i = 0; i < n; i++) - if (s[i] == p[0]) + if (s[i] == p[0]) { count++; + if (count == maxcount) + return maxcount; + } return count; } else if (mode == FAST_SEARCH) { for (i = 0; i < n; i++) @@ -56,19 +62,20 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, mlast = m - 1; skip = mlast - 1; + mask = 0; if (mode != FAST_RSEARCH) { /* create compressed boyer-moore delta 1 table */ /* process pattern[:-1] */ - for (mask = i = 0; i < mlast; i++) { - mask |= (1 << (p[i] & 0x1F)); + for (i = 0; i < mlast; i++) { + BLOOM_ADD(mask, p[i]); if (p[i] == p[mlast]) skip = mlast - i - 1; } /* process pattern[-1] outside the loop */ - mask |= (1 << (p[mlast] & 0x1F)); + BLOOM_ADD(mask, p[mlast]); for (i = 0; i <= w; i++) { /* note: using mlast in the skip path slows things down on x86 */ @@ -82,17 +89,19 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, 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 (!(mask & (1 << (s[i+m] & 0x1F)))) + if (!BLOOM(mask, s[i+m])) i = i + m; else i = i + skip; } else { /* skip: check if next character is part of pattern */ - if (!(mask & (1 << (s[i+m] & 0x1F)))) + if (!BLOOM(mask, s[i+m])) i = i + m; } } @@ -101,10 +110,10 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* create compressed boyer-moore delta 1 table */ /* process pattern[0] outside the loop */ - mask = (1 << (p[0] & 0x1F)); + BLOOM_ADD(mask, p[0]); /* process pattern[:0:-1] */ for (i = mlast; i > 0; i--) { - mask |= (1 << (p[i] & 0x1F)); + BLOOM_ADD(mask, p[i]); if (p[i] == p[0]) skip = i - 1; } @@ -119,13 +128,13 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* got a match! */ return i; /* miss: check if previous character is part of pattern */ - if (!(mask & (1 << (s[i-1] & 0x1F)))) + if (!BLOOM(mask, s[i-1])) i = i - m; else i = i - skip; } else { /* skip: check if previous character is part of pattern */ - if (!(mask & (1 << (s[i-1] & 0x1F)))) + if (!BLOOM(mask, s[i-1])) i = i - m; } } @@ -137,10 +146,3 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, } #endif - -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ diff --git a/Objects/stringlib/find.h b/Objects/stringlib/find.h index bf27d6a5cf..f915296cae 100644 --- a/Objects/stringlib/find.h +++ b/Objects/stringlib/find.h @@ -19,7 +19,7 @@ stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len, if (sub_len == 0) return offset; - pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH); + pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH); if (pos >= 0) pos += offset; @@ -39,7 +39,7 @@ stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len, if (sub_len == 0) return str_len + offset; - pos = fastsearch(str, str_len, sub, sub_len, FAST_RSEARCH); + pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_RSEARCH); if (pos >= 0) pos += offset; @@ -47,22 +47,27 @@ stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len, 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) { - if (start < 0) - start += str_len; - if (start < 0) - start = 0; - if (end > str_len) - end = str_len; - if (end < 0) - end += str_len; - if (end < 0) - end = 0; - + ADJUST_INDICES(start, end, str_len); return stringlib_find(str + start, end - start, sub, sub_len, start); } @@ -71,17 +76,7 @@ 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) { - if (start < 0) - start += str_len; - if (start < 0) - start = 0; - if (end > str_len) - end = str_len; - if (end < 0) - end += str_len; - if (end < 0) - end = 0; - + ADJUST_INDICES(start, end, str_len); return stringlib_rfind(str + start, end - start, sub, sub_len, start); } @@ -96,9 +91,9 @@ stringlib_contains_obj(PyObject* str, PyObject* sub) ) != -1; } -#endif /* STRINGLIB_STR */ +#endif /* STRINGLIB_WANT_CONTAINS_OBJ */ -#ifdef FROM_UNICODE +#if STRINGLIB_IS_UNICODE /* This function is a helper for the "find" family (find, rfind, index, @@ -146,13 +141,6 @@ _ParseTupleFinds (PyObject *args, PyObject **substring, return 1; } -#endif /* FROM_UNICODE */ +#endif /* STRINGLIB_IS_UNICODE */ #endif /* STRINGLIB_FIND_H */ - -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h index 2f26212983..0170bddbf0 100644 --- a/Objects/stringlib/partition.h +++ b/Objects/stringlib/partition.h @@ -8,33 +8,39 @@ #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 - ) +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; + return NULL; } out = PyTuple_New(3); if (!out) - return NULL; + return NULL; - pos = fastsearch(str, str_len, sep, sep_len, FAST_SEARCH); + pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH); if (pos < 0) { - 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); - return out; +#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)); @@ -44,41 +50,47 @@ stringlib_partition( PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos)); if (PyErr_Occurred()) { - Py_DECREF(out); - return NULL; + 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 - ) +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; + return NULL; } out = PyTuple_New(3); if (!out) - return NULL; + return NULL; - pos = fastsearch(str, str_len, sep, sep_len, FAST_RSEARCH); + pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH); if (pos < 0) { - 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); - return out; +#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)); @@ -88,18 +100,11 @@ stringlib_rpartition( PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos)); if (PyErr_Occurred()) { - Py_DECREF(out); - return NULL; + Py_DECREF(out); + return NULL; } return out; } #endif - -/* -Local variables: -c-basic-offset: 4 -indent-tabs-mode: nil -End: -*/ diff --git a/Objects/stringlib/split.h b/Objects/stringlib/split.h new file mode 100644 index 0000000000..00b29b31d0 --- /dev/null +++ b/Objects/stringlib/split.h @@ -0,0 +1,788 @@ +/* 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 +/* 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/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h index 8a650fe293..1c49426ff6 100644 --- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -11,6 +11,8 @@ #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 diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index 7dc81776ab..1e132e54aa 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -1,13 +1,6 @@ /* NOTE: this API is -ONLY- for use with single byte character strings. */ /* Do not use it with Unicode. */ -#include "bytes_methods.h" - -#ifndef STRINGLIB_MUTABLE -#warning "STRINGLIB_MUTABLE not defined before #include, assuming 0" -#define STRINGLIB_MUTABLE 0 -#endif - /* 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. */ @@ -269,87 +262,3 @@ stringlib_zfill(PyObject *self, PyObject *args) return (PyObject*) s; } - - -#define _STRINGLIB_SPLIT_APPEND(data, left, right) \ - str = STRINGLIB_NEW((data) + (left), \ - (right) - (left)); \ - if (str == NULL) \ - goto onError; \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); - -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> 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* -stringlib_splitlines(PyObject *self, PyObject *args) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len; - int keepends = 0; - PyObject *list; - PyObject *str; - char *data; - - if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; - - data = STRINGLIB_STR(self); - len = STRINGLIB_LEN(self); - - /* 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.*/ - - list = PyList_New(0); - if (!list) - goto onError; - - for (i = j = 0; i < len; ) { - Py_ssize_t eol; - - /* Find a line and append it */ - while (i < len && data[i] != '\n' && data[i] != '\r') - i++; - - /* Skip the line break reading CRLF as one line break */ - eol = i; - if (i < len) { - if (data[i] == '\r' && i + 1 < len && - data[i+1] == '\n') - i += 2; - else - i++; - if (keepends) - eol = i; - } - _STRINGLIB_SPLIT_APPEND(data, j, eol); - j = i; - } - if (j < len) { - _STRINGLIB_SPLIT_APPEND(data, j, len); - } - - return list; - - onError: - Py_XDECREF(list); - return NULL; -} - -#undef _STRINGLIB_SPLIT_APPEND - diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h index a4d2144d8a..09dae6dc9e 100644 --- a/Objects/stringlib/unicodedefs.h +++ b/Objects/stringlib/unicodedefs.h @@ -11,6 +11,8 @@ #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 diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 40377ea48d..3d49db162b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -210,7 +210,8 @@ PyUnicode_GetMax(void) static BLOOM_MASK bloom_linebreak; -#define BLOOM(mask, ch) ((mask & (1 << ((ch) & 0x1F)))) +#define BLOOM_ADD(mask, ch) ((mask |= (1 << ((ch) & (LONG_BIT - 1))))) +#define BLOOM(mask, ch) ((mask & (1 << ((ch) & (LONG_BIT - 1))))) #define BLOOM_LINEBREAK(ch) \ ((ch) < 128U ? ascii_linebreak[(ch)] : \ @@ -225,7 +226,7 @@ Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len) mask = 0; for (i = 0; i < len; i++) - mask |= (1 << (ptr[i] & 0x1F)); + BLOOM_ADD(mask, ptr[i]); return mask; } @@ -5873,28 +5874,30 @@ int PyUnicode_EncodeDecimal(Py_UNICODE *s, #include "stringlib/unicodedefs.h" #include "stringlib/fastsearch.h" + #include "stringlib/count.h" -/* Include _ParseTupleFinds from find.h */ -#define FROM_UNICODE #include "stringlib/find.h" #include "stringlib/partition.h" +#include "stringlib/split.h" #define _Py_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping #define _Py_InsertThousandsGroupingLocale _PyUnicode_InsertThousandsGroupingLocale #include "stringlib/localeutil.h" /* helper macro to fixup start/end slice values */ -#define FIX_START_END(obj) \ - if (start < 0) \ - start += (obj)->length; \ - if (start < 0) \ - start = 0; \ - if (end > (obj)->length) \ - end = (obj)->length; \ - if (end < 0) \ - end += (obj)->length; \ - if (end < 0) \ - end = 0; +#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, @@ -5914,10 +5917,10 @@ Py_ssize_t PyUnicode_Count(PyObject *str, return -1; } - FIX_START_END(str_obj); - + ADJUST_INDICES(start, end, str_obj->length); result = stringlib_count( - str_obj->str + start, end - start, sub_obj->str, sub_obj->length + str_obj->str + start, end - start, sub_obj->str, sub_obj->length, + PY_SSIZE_T_MAX ); Py_DECREF(sub_obj); @@ -5972,8 +5975,7 @@ int tailmatch(PyUnicodeObject *self, if (substring->length == 0) return 1; - FIX_START_END(self); - + ADJUST_INDICES(start, end, self->length); end -= substring->length; if (end < start) return 0; @@ -6314,305 +6316,40 @@ PyUnicodeObject *pad(PyUnicodeObject *self, return u; } -#define SPLIT_APPEND(data, left, right) \ - str = PyUnicode_FromUnicode((data) + (left), (right) - (left)); \ - if (!str) \ - goto onError; \ - if (PyList_Append(list, str)) { \ - Py_DECREF(str); \ - goto onError; \ - } \ - else \ - Py_DECREF(str); - -static -PyObject *split_whitespace(PyUnicodeObject *self, - PyObject *list, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - PyObject *str; - register const Py_UNICODE *buf = self->str; - - for (i = j = 0; i < len; ) { - /* find a token */ - while (i < len && Py_UNICODE_ISSPACE(buf[i])) - i++; - j = i; - while (i < len && !Py_UNICODE_ISSPACE(buf[i])) - i++; - if (j < i) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(buf, j, i); - while (i < len && Py_UNICODE_ISSPACE(buf[i])) - i++; - j = i; - } - } - if (j < len) { - SPLIT_APPEND(buf, j, len); - } - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -PyObject *PyUnicode_Splitlines(PyObject *string, - int keepends) +PyObject *PyUnicode_Splitlines(PyObject *string, int keepends) { - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len; PyObject *list; - PyObject *str; - Py_UNICODE *data; string = PyUnicode_FromObject(string); if (string == NULL) return NULL; - data = PyUnicode_AS_UNICODE(string); - len = PyUnicode_GET_SIZE(string); - list = PyList_New(0); - if (!list) - goto onError; - - for (i = j = 0; i < len; ) { - Py_ssize_t eol; - - /* Find a line and append it */ - while (i < len && !BLOOM_LINEBREAK(data[i])) - i++; - - /* Skip the line break reading CRLF as one line break */ - eol = i; - if (i < len) { - if (data[i] == '\r' && i + 1 < len && - data[i+1] == '\n') - i += 2; - else - i++; - if (keepends) - eol = i; - } - SPLIT_APPEND(data, j, eol); - j = i; - } - if (j < len) { - SPLIT_APPEND(data, j, len); - } + list = stringlib_splitlines( + (PyObject*) string, PyUnicode_AS_UNICODE(string), + PyUnicode_GET_SIZE(string), keepends); Py_DECREF(string); return list; - - onError: - Py_XDECREF(list); - Py_DECREF(string); - return NULL; } -static -PyObject *split_char(PyUnicodeObject *self, - PyObject *list, - Py_UNICODE ch, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - PyObject *str; - register const Py_UNICODE *buf = self->str; - - for (i = j = 0; i < len; ) { - if (buf[i] == ch) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(buf, j, i); - i = j = i + 1; - } else - i++; - } - if (j <= len) { - SPLIT_APPEND(buf, j, len); - } - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -static -PyObject *split_substring(PyUnicodeObject *self, - PyObject *list, - PyUnicodeObject *substring, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - Py_ssize_t sublen = substring->length; - PyObject *str; - - for (i = j = 0; i <= len - sublen; ) { - if (Py_UNICODE_MATCH(self, i, substring)) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(self->str, j, i); - i = j = i + sublen; - } else - i++; - } - if (j <= len) { - SPLIT_APPEND(self->str, j, len); - } - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -static -PyObject *rsplit_whitespace(PyUnicodeObject *self, - PyObject *list, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - PyObject *str; - register const Py_UNICODE *buf = self->str; - - for (i = j = len - 1; i >= 0; ) { - /* find a token */ - while (i >= 0 && Py_UNICODE_ISSPACE(buf[i])) - i--; - j = i; - while (i >= 0 && !Py_UNICODE_ISSPACE(buf[i])) - i--; - if (j > i) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(buf, i + 1, j + 1); - while (i >= 0 && Py_UNICODE_ISSPACE(buf[i])) - i--; - j = i; - } - } - if (j >= 0) { - SPLIT_APPEND(buf, 0, j + 1); - } - if (PyList_Reverse(list) < 0) - goto onError; - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -static -PyObject *rsplit_char(PyUnicodeObject *self, - PyObject *list, - Py_UNICODE ch, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - PyObject *str; - register const Py_UNICODE *buf = self->str; - - for (i = j = len - 1; i >= 0; ) { - if (buf[i] == ch) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(buf, i + 1, j + 1); - j = i = i - 1; - } else - i--; - } - if (j >= -1) { - SPLIT_APPEND(buf, 0, j + 1); - } - if (PyList_Reverse(list) < 0) - goto onError; - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -static -PyObject *rsplit_substring(PyUnicodeObject *self, - PyObject *list, - PyUnicodeObject *substring, - Py_ssize_t maxcount) -{ - register Py_ssize_t i; - register Py_ssize_t j; - Py_ssize_t len = self->length; - Py_ssize_t sublen = substring->length; - PyObject *str; - - for (i = len - sublen, j = len; i >= 0; ) { - if (Py_UNICODE_MATCH(self, i, substring)) { - if (maxcount-- <= 0) - break; - SPLIT_APPEND(self->str, i + sublen, j); - j = i; - i -= sublen; - } else - i--; - } - if (j >= 0) { - SPLIT_APPEND(self->str, 0, j); - } - if (PyList_Reverse(list) < 0) - goto onError; - return list; - - onError: - Py_DECREF(list); - return NULL; -} - -#undef SPLIT_APPEND - static PyObject *split(PyUnicodeObject *self, PyUnicodeObject *substring, Py_ssize_t maxcount) { - PyObject *list; - if (maxcount < 0) maxcount = PY_SSIZE_T_MAX; - list = PyList_New(0); - if (!list) - return NULL; - if (substring == NULL) - return split_whitespace(self,list,maxcount); - - else if (substring->length == 1) - return split_char(self,list,substring->str[0],maxcount); + return stringlib_split_whitespace( + (PyObject*) self, self->str, self->length, maxcount + ); - else if (substring->length == 0) { - Py_DECREF(list); - PyErr_SetString(PyExc_ValueError, "empty separator"); - return NULL; - } - else - return split_substring(self,list,substring,maxcount); + return stringlib_split( + (PyObject*) self, self->str, self->length, + substring->str, substring->length, + maxcount + ); } static @@ -6620,28 +6357,19 @@ PyObject *rsplit(PyUnicodeObject *self, PyUnicodeObject *substring, Py_ssize_t maxcount) { - PyObject *list; - if (maxcount < 0) maxcount = PY_SSIZE_T_MAX; - list = PyList_New(0); - if (!list) - return NULL; - if (substring == NULL) - return rsplit_whitespace(self,list,maxcount); - - else if (substring->length == 1) - return rsplit_char(self,list,substring->str[0],maxcount); + return stringlib_rsplit_whitespace( + (PyObject*) self, self->str, self->length, maxcount + ); - else if (substring->length == 0) { - Py_DECREF(list); - PyErr_SetString(PyExc_ValueError, "empty separator"); - return NULL; - } - else - return rsplit_substring(self,list,substring,maxcount); + return stringlib_rsplit( + (PyObject*) self, self->str, self->length, + substring->str, substring->length, + maxcount + ); } static @@ -6654,9 +6382,13 @@ PyObject *replace(PyUnicodeObject *self, if (maxcount < 0) maxcount = PY_SSIZE_T_MAX; + else if (maxcount == 0 || self->length == 0) + goto nothing; if (str1->length == str2->length) { /* same length */ + if (str1->length == 0) + goto nothing; Py_ssize_t i; if (str1->length == 1) { /* replace characters */ @@ -6676,8 +6408,8 @@ PyObject *replace(PyUnicodeObject *self, u->str[i] = u2; } } else { - i = fastsearch( - self->str, self->length, str1->str, str1->length, FAST_SEARCH + i = stringlib_find( + self->str, self->length, str1->str, str1->length, 0 ); if (i < 0) goto nothing; @@ -6685,14 +6417,20 @@ PyObject *replace(PyUnicodeObject *self, if (!u) return NULL; Py_UNICODE_COPY(u->str, self->str, self->length); - while (i <= self->length - str1->length) - if (Py_UNICODE_MATCH(self, i, str1)) { - if (--maxcount < 0) - break; - Py_UNICODE_COPY(u->str+i, str2->str, str2->length); - i += str1->length; - } else - i++; + + /* 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 { @@ -6701,9 +6439,8 @@ PyObject *replace(PyUnicodeObject *self, Py_UNICODE *p; /* replace strings */ - n = stringlib_count(self->str, self->length, str1->str, str1->length); - if (n > maxcount) - n = maxcount; + 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)); */ @@ -6733,15 +6470,12 @@ PyObject *replace(PyUnicodeObject *self, if (str1->length > 0) { while (n-- > 0) { /* look for next match */ - j = i; - while (j <= e) { - if (Py_UNICODE_MATCH(self, j, str1)) - break; - j++; - } - if (j > i) { - if (j > e) - break; + 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; @@ -7192,11 +6926,11 @@ unicode_count(PyUnicodeObject *self, PyObject *args) if (substring == NULL) return NULL; - FIX_START_END(self); - + ADJUST_INDICES(start, end, self->length); result = PyLong_FromSsize_t( stringlib_count(self->str + start, end - start, - substring->str, substring->length) + substring->str, substring->length, + PY_SSIZE_T_MAX) ); Py_DECREF(substring); @@ -10066,11 +9800,3 @@ Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c) #ifdef __cplusplus } #endif - - -/* - Local variables: - c-basic-offset: 4 - indent-tabs-mode: nil - End: -*/ -- cgit v1.2.1 From 9f12fcc5d2f9567a9b5ef041a35cb5359673786f Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 13 Jan 2010 08:58:08 +0000 Subject: Merged revisions 77463 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77463 | antoine.pitrou | 2010-01-13 09:55:20 +0100 (mer., 13 janv. 2010) | 3 lines Fix Windows build (re r77461) ........ --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 3d49db162b..d8d9c35690 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6386,10 +6386,10 @@ PyObject *replace(PyUnicodeObject *self, goto nothing; if (str1->length == str2->length) { + Py_ssize_t i; /* same length */ if (str1->length == 0) goto nothing; - Py_ssize_t i; if (str1->length == 1) { /* replace characters */ Py_UNICODE u1, u2; -- cgit v1.2.1 From 98a8b05ada8965f366dfe12bf8b2d84665ce801d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 13 Jan 2010 09:19:15 +0000 Subject: svnmerge duplicated contents of Objects/stringlib/split.h --- Objects/stringlib/split.h | 394 ---------------------------------------------- 1 file changed, 394 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/split.h b/Objects/stringlib/split.h index 00b29b31d0..60e77674f0 100644 --- a/Objects/stringlib/split.h +++ b/Objects/stringlib/split.h @@ -50,400 +50,6 @@ 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 -/* 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 -- cgit v1.2.1 From 2cc2273b77e9f7560db343d96772ad41dedcf852 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 13 Jan 2010 14:19:12 +0000 Subject: Merged revisions 77469-77470 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77469 | antoine.pitrou | 2010-01-13 14:43:37 +0100 (mer., 13 janv. 2010) | 3 lines Test commit to try to diagnose failures of the IA-64 buildbot ........ r77470 | antoine.pitrou | 2010-01-13 15:01:26 +0100 (mer., 13 janv. 2010) | 3 lines Sanitize bloom filter macros ........ --- Objects/stringlib/fastsearch.h | 34 +++++++++++++++++++++++----------- Objects/unicodeobject.c | 16 +++++++++++++--- 2 files changed, 36 insertions(+), 14 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 21cf3a2ab7..7525951c06 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -18,15 +18,27 @@ #define FAST_SEARCH 1 #define FAST_RSEARCH 2 -#define BLOOM_ADD(mask, ch) ((mask |= (1 << ((ch) & (LONG_BIT - 1))))) -#define BLOOM(mask, ch) ((mask & (1 << ((ch) & (LONG_BIT - 1))))) +#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) { - long mask; + unsigned long mask; Py_ssize_t skip, count = 0; Py_ssize_t i, j, mlast, w; @@ -70,12 +82,12 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* process pattern[:-1] */ for (i = 0; i < mlast; i++) { - BLOOM_ADD(mask, p[i]); + STRINGLIB_BLOOM_ADD(mask, p[i]); if (p[i] == p[mlast]) skip = mlast - i - 1; } /* process pattern[-1] outside the loop */ - BLOOM_ADD(mask, p[mlast]); + STRINGLIB_BLOOM_ADD(mask, p[mlast]); for (i = 0; i <= w; i++) { /* note: using mlast in the skip path slows things down on x86 */ @@ -95,13 +107,13 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, continue; } /* miss: check if next character is part of pattern */ - if (!BLOOM(mask, s[i+m])) + 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 (!BLOOM(mask, s[i+m])) + if (!STRINGLIB_BLOOM(mask, s[i+m])) i = i + m; } } @@ -110,10 +122,10 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* create compressed boyer-moore delta 1 table */ /* process pattern[0] outside the loop */ - BLOOM_ADD(mask, p[0]); + STRINGLIB_BLOOM_ADD(mask, p[0]); /* process pattern[:0:-1] */ for (i = mlast; i > 0; i--) { - BLOOM_ADD(mask, p[i]); + STRINGLIB_BLOOM_ADD(mask, p[i]); if (p[i] == p[0]) skip = i - 1; } @@ -128,13 +140,13 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* got a match! */ return i; /* miss: check if previous character is part of pattern */ - if (!BLOOM(mask, s[i-1])) + if (!STRINGLIB_BLOOM(mask, s[i-1])) i = i - m; else i = i - skip; } else { /* skip: check if previous character is part of pattern */ - if (!BLOOM(mask, s[i-1])) + if (!STRINGLIB_BLOOM(mask, s[i-1])) i = i - m; } } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d8d9c35690..35683d0d31 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -206,12 +206,22 @@ PyUnicode_GetMax(void) /* 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; -#define BLOOM_ADD(mask, ch) ((mask |= (1 << ((ch) & (LONG_BIT - 1))))) -#define BLOOM(mask, ch) ((mask & (1 << ((ch) & (LONG_BIT - 1))))) +#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)] : \ @@ -221,7 +231,7 @@ 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 */ - long mask; + BLOOM_MASK mask; Py_ssize_t i; mask = 0; -- cgit v1.2.1 From 7728f7962a5f077c0f0fdaaadeb58425f514a687 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 17 Jan 2010 12:38:54 +0000 Subject: Merged revisions 77573 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77573 | antoine.pitrou | 2010-01-17 13:26:20 +0100 (dim., 17 janv. 2010) | 6 lines Issue #7561: Operations on empty bytearrays (such as `int(bytearray())`) could crash in many places because of the PyByteArray_AS_STRING() macro returning NULL. The macro now returns a statically allocated empty string instead. ........ --- Objects/bytearrayobject.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 823c800a50..7d525222b9 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -5,23 +5,16 @@ #include "structmember.h" #include "bytes_methods.h" -static PyByteArrayObject *nullbytes = NULL; +char _PyByteArray_empty_string[] = ""; void PyByteArray_Fini(void) { - Py_CLEAR(nullbytes); } int PyByteArray_Init(void) { - nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type); - if (nullbytes == NULL) - return 0; - nullbytes->ob_bytes = NULL; - Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0; - nullbytes->ob_exports = 0; return 1; } @@ -65,10 +58,7 @@ bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) obj->ob_exports++; return 0; } - if (obj->ob_bytes == NULL) - ptr = ""; - else - ptr = obj->ob_bytes; + ptr = (void *) PyByteArray_AS_STRING(obj); ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); if (ret >= 0) { obj->ob_exports++; @@ -152,7 +142,7 @@ PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) Py_DECREF(new); return PyErr_NoMemory(); } - if (bytes != NULL) + if (bytes != NULL && size > 0) memcpy(new->ob_bytes, bytes, size); new->ob_bytes[size] = '\0'; /* Trailing null byte */ } @@ -1038,7 +1028,6 @@ bytearray_dealloc(PyByteArrayObject *self) #define STRINGLIB_LEN PyByteArray_GET_SIZE #define STRINGLIB_STR PyByteArray_AS_STRING #define STRINGLIB_NEW PyByteArray_FromStringAndSize -#define STRINGLIB_EMPTY nullbytes #define STRINGLIB_ISSPACE Py_ISSPACE #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact -- cgit v1.2.1 From 672444df68908d5499d03149f13fcb61f5973164 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 25 Jan 2010 11:58:28 +0000 Subject: Merged revisions 77743 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77743 | ezio.melotti | 2010-01-25 13:24:37 +0200 (Mon, 25 Jan 2010) | 1 line #7775: fixed docstring for rpartition ........ --- Objects/bytearrayobject.c | 2 +- Objects/bytesobject.c | 2 +- Objects/unicodeobject.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 7d525222b9..3603d4f9f8 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2044,7 +2044,7 @@ bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) } PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (tail, sep, head)\n\ +"B.rpartition(sep) -> (head, sep, tail)\n\ \n\ Search for the separator sep in B, starting at the end of B,\n\ and return the part before it, the separator itself, and the\n\ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 183722ca74..890d0447df 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1061,7 +1061,7 @@ bytes_partition(PyBytesObject *self, PyObject *sep_obj) } PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (tail, sep, head)\n\ +"B.rpartition(sep) -> (head, sep, tail)\n\ \n\ Search for the separator sep in B, starting at the end of B,\n\ and return the part before it, the separator itself, and the\n\ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 35683d0d31..79b0aa7457 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8201,7 +8201,7 @@ unicode_partition(PyUnicodeObject *self, PyObject *separator) } PyDoc_STRVAR(rpartition__doc__, - "S.rpartition(sep) -> (tail, sep, head)\n\ + "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\ -- cgit v1.2.1 From 9c88a1b6a64250820928ce0e35cafff809c288f6 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 29 Jan 2010 17:27:24 +0000 Subject: Merged revisions 77821 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77821 | mark.dickinson | 2010-01-29 17:11:39 +0000 (Fri, 29 Jan 2010) | 3 lines Issue #7788: Fix a crash produced by deleting a list slice with huge step value. Patch by Marcin Bachry. ........ --- Objects/bytearrayobject.c | 3 ++- Objects/listobject.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 3603d4f9f8..42f1ed6e6f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -642,7 +642,8 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu else { if (needed == 0) { /* Delete slice */ - Py_ssize_t cur, i; + size_t cur; + Py_ssize_t i; if (!_canresize(self)) return -1; diff --git a/Objects/listobject.c b/Objects/listobject.c index f54b97ddb5..a97d47506f 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2444,7 +2444,8 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) if (value == NULL) { /* delete slice */ PyObject **garbage; - Py_ssize_t cur, i; + size_t cur; + Py_ssize_t i; if (slicelength <= 0) return 0; -- cgit v1.2.1 From 121201981e5394eff79b6304523ca376109864f2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 30 Jan 2010 10:30:15 +0000 Subject: Merged revisions 77842 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77842 | mark.dickinson | 2010-01-30 10:08:33 +0000 (Sat, 30 Jan 2010) | 4 lines Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a long long variant of PyLong_AsLongAndOverflow. Patch by Case Van Horsen. ........ --- Objects/longobject.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index afac856cd0..db7a91c556 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -971,6 +971,7 @@ PyLong_AsVoidPtr(PyObject *vv) */ #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one +#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) /* Create a new long int object from a C PY_LONG_LONG int. */ @@ -1269,6 +1270,101 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op) } #undef IS_LITTLE_ENDIAN +/* Get a C long long int from a Python long or Python int object. + On overflow, returns -1 and sets *overflow to 1 or -1 depending + on the sign of the result. Otherwise *overflow is 0. + + For other errors (e.g., type error), returns -1 and sets an error + condition. +*/ + +PY_LONG_LONG +PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) +{ + /* This version by Tim Peters */ + register PyLongObject *v; + unsigned PY_LONG_LONG x, prev; + PY_LONG_LONG res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + return -1; + } + vv = (*nb->nb_int) (vv); + if (vv == NULL) + return -1; + do_decref = 1; + if (!PyLong_Check(vv)) { + Py_DECREF(vv); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + + res = -1; + v = (PyLongObject *)vv; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) + v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { + res = (PY_LONG_LONG)x * sign; + } + else if (sign < 0 && x == PY_ABS_LLONG_MIN) { + res = PY_LLONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } + exit: + if (do_decref) { + Py_DECREF(vv); + } + return res; +} + #endif /* HAVE_LONG_LONG */ #define CHECK_BINOP(v,w) \ -- cgit v1.2.1 From 3b6fcce9393ca4b5f0cef38af4507887c0d7076b Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 30 Jan 2010 18:06:17 +0000 Subject: Move docstrings for long.to_bytes and long.from_bytes after the corresponding functions. --- Objects/longobject.c | 54 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index db7a91c556..ce87084e28 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4393,25 +4393,6 @@ long_is_finite(PyObject *v) #endif -PyDoc_STRVAR(long_to_bytes_doc, -"int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\ -\n\ -Return an array of bytes representing an integer.\n\ -\n\ -The integer is represented using length bytes. An OverflowError is\n\ -raised if the integer is not representable with the given number of\n\ -bytes.\n\ -\n\ -The byteorder argument determines the byte order used to represent the\n\ -integer. If byteorder is 'big', the most significant byte is at the\n\ -beginning of the byte array. If byteorder is 'little', the most\n\ -significant byte is at the end of the byte array. To request the native\n\ -byte order of the host system, use `sys.byteorder' as the byte order value.\n\ -\n\ -The signed keyword-only argument determines whether two's complement is\n\ -used to represent the integer. If signed is False and a negative integer\n\ -is given, an OverflowError is raised."); - static PyObject * long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) { @@ -4475,14 +4456,14 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) return bytes; } -PyDoc_STRVAR(long_from_bytes_doc, -"int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\ +PyDoc_STRVAR(long_to_bytes_doc, +"int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\ \n\ -Return the integer represented by the given array of bytes.\n\ +Return an array of bytes representing an integer.\n\ \n\ -The bytes argument must either support the buffer protocol or be an\n\ -iterable object producing bytes. Bytes and bytearray are examples of\n\ -built-in objects that support the buffer protocol.\n\ +The integer is represented using length bytes. An OverflowError is\n\ +raised if the integer is not representable with the given number of\n\ +bytes.\n\ \n\ The byteorder argument determines the byte order used to represent the\n\ integer. If byteorder is 'big', the most significant byte is at the\n\ @@ -4490,8 +4471,9 @@ beginning of the byte array. If byteorder is 'little', the most\n\ significant byte is at the end of the byte array. To request the native\n\ byte order of the host system, use `sys.byteorder' as the byte order value.\n\ \n\ -The signed keyword-only argument indicates whether two's complement is\n\ -used to represent the integer."); +The signed keyword-only argument determines whether two's complement is\n\ +used to represent the integer. If signed is False and a negative integer\n\ +is given, an OverflowError is raised."); static PyObject * long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -4573,6 +4555,24 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) return long_obj; } +PyDoc_STRVAR(long_from_bytes_doc, +"int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\ +\n\ +Return the integer represented by the given array of bytes.\n\ +\n\ +The bytes argument must either support the buffer protocol or be an\n\ +iterable object producing bytes. Bytes and bytearray are examples of\n\ +built-in objects that support the buffer protocol.\n\ +\n\ +The byteorder argument determines the byte order used to represent the\n\ +integer. If byteorder is 'big', the most significant byte is at the\n\ +beginning of the byte array. If byteorder is 'little', the most\n\ +significant byte is at the end of the byte array. To request the native\n\ +byte order of the host system, use `sys.byteorder' as the byte order value.\n\ +\n\ +The signed keyword-only argument indicates whether two's complement is\n\ +used to represent the integer."); + static PyMethodDef long_methods[] = { {"conjugate", (PyCFunction)long_long, METH_NOARGS, "Returns self, the complex conjugate of any int."}, -- cgit v1.2.1 From caa3cd8bba7ec6e1d45bca7c59b39ec591998ea5 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 2 Feb 2010 22:47:00 +0000 Subject: Merged revisions 77916 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r77916 | antoine.pitrou | 2010-02-02 23:36:17 +0100 (mar., 02 févr. 2010) | 4 lines Issue #7385: Fix a crash in `MemoryView_FromObject` when `PyObject_GetBuffer` fails. Patch by Florent Xicluna. ........ --- Objects/memoryobject.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 7acd569d73..e92a771dfd 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -76,6 +76,7 @@ PyObject * PyMemoryView_FromObject(PyObject *base) { PyMemoryViewObject *mview; + Py_buffer view; if (!PyObject_CheckBuffer(base)) { PyErr_SetString(PyExc_TypeError, @@ -84,20 +85,17 @@ PyMemoryView_FromObject(PyObject *base) return NULL; } - mview = (PyMemoryViewObject *) - PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); - if (mview == NULL) + if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0) return NULL; - mview->base = NULL; - if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) { - Py_DECREF(mview); + mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view); + if (mview == NULL) { + PyBuffer_Release(&view); return NULL; } mview->base = base; Py_INCREF(base); - _PyObject_GC_TRACK(mview); return (PyObject *)mview; } -- cgit v1.2.1 From 220fbc62b4fada78f9aec1e1eccc40adb6e7f5a1 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 3 Feb 2010 02:35:45 +0000 Subject: Merged revisions 77484,77487,77561,77570,77593,77603,77608,77667,77702-77703,77739,77858,77887,77889 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r77484 | skip.montanaro | 2010-01-13 19:12:34 -0600 (Wed, 13 Jan 2010) | 4 lines Update PyEval_EvalFrame to PyEval_EvalFrameEx. This looks to have been done partially before. Also add a comment describing how this might have to work with different versions of the interpreter. ........ r77487 | ezio.melotti | 2010-01-14 05:34:10 -0600 (Thu, 14 Jan 2010) | 1 line Fixed typo ........ r77561 | georg.brandl | 2010-01-17 02:42:30 -0600 (Sun, 17 Jan 2010) | 1 line #7699: improve datetime docs: straightforward linking to strftime/strptime section, mark classmethods as such. ........ r77570 | georg.brandl | 2010-01-17 06:14:42 -0600 (Sun, 17 Jan 2010) | 1 line Add note about usage of STRINGLIB_EMPTY. ........ r77593 | georg.brandl | 2010-01-17 17:33:53 -0600 (Sun, 17 Jan 2010) | 1 line Fix internal reference. ........ r77603 | benjamin.peterson | 2010-01-18 17:07:56 -0600 (Mon, 18 Jan 2010) | 8 lines data descriptors do not override the class dictionary if __get__ is not defined Adjust documentation and add a test to verify this behavior. See http://mail.python.org/pipermail/python-dev/2010-January/095637.html for discussion. ........ r77608 | gregory.p.smith | 2010-01-19 02:19:03 -0600 (Tue, 19 Jan 2010) | 6 lines Do not compile stubs for the sha2 series hashes in the openssl hashlib module when the openssl version is too old to support them. That leads both compiled code bloat and to unittests attempting to test implementations that don't exist for comparison purposes on such platforms. ........ r77667 | mark.dickinson | 2010-01-21 12:32:27 -0600 (Thu, 21 Jan 2010) | 1 line Add two more test_strtod test values. ........ r77702 | georg.brandl | 2010-01-23 02:43:31 -0600 (Sat, 23 Jan 2010) | 1 line #7762: fix refcount annotation of PyUnicode_Tailmatch(). ........ r77703 | georg.brandl | 2010-01-23 02:47:54 -0600 (Sat, 23 Jan 2010) | 1 line #7725: fix referencing issue. ........ r77739 | benjamin.peterson | 2010-01-24 21:52:52 -0600 (Sun, 24 Jan 2010) | 1 line mention from_float() in error message ........ r77858 | georg.brandl | 2010-01-30 11:57:48 -0600 (Sat, 30 Jan 2010) | 1 line #7802: fix invalid example (heh). ........ r77887 | georg.brandl | 2010-01-31 12:51:49 -0600 (Sun, 31 Jan 2010) | 5 lines Fix-up ftplib documentation: move exception descriptions to toplevel, not inside a class remove attribution in "versionadded" spell and grammar check docstring of FTP_TLS ........ r77889 | michael.foord | 2010-01-31 13:59:26 -0600 (Sun, 31 Jan 2010) | 1 line Minor modification to unittest documentation. ........ --- Objects/stringlib/README.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt index c884ec3c2f..ab506d60f9 100644 --- a/Objects/stringlib/README.txt +++ b/Objects/stringlib/README.txt @@ -13,7 +13,8 @@ STRINGLIB_CHAR STRINGLIB_EMPTY - a PyObject representing the empty string + a PyObject representing the empty string, only to be used if + STRINGLIB_MUTABLE is 0 Py_ssize_t STRINGLIB_LEN(PyObject*) @@ -31,9 +32,9 @@ STRINGLIB_CHAR* STRINGLIB_STR(PyObject*) int STRINGLIB_CHECK_EXACT(PyObject *) - returns true if the object is an instance of our type, not a subclass. + 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. + must be 0 or 1 to tell the cpp macros in stringlib code if the object + being operated on is mutable or not -- cgit v1.2.1 From 694d6ac995d3fcf894b42b9b5993e39cf634d941 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 14 Feb 2010 12:53:32 +0000 Subject: Merged revisions 78183-78184 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78183 | mark.dickinson | 2010-02-14 12:16:43 +0000 (Sun, 14 Feb 2010) | 1 line Silence some 'comparison between signed and unsigned' compiler warnings. ........ r78184 | mark.dickinson | 2010-02-14 12:31:26 +0000 (Sun, 14 Feb 2010) | 1 line Silence more compiler warnings; fix an instance of potential undefined behaviour from signed overflow. ........ --- Objects/bytearrayobject.c | 9 +++++---- Objects/listobject.c | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 42f1ed6e6f..8f833d8efd 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -656,7 +656,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu i < slicelen; cur += step, i++) { Py_ssize_t lim = step - 1; - if (cur + step >= PyByteArray_GET_SIZE(self)) + if (cur + step >= (size_t)PyByteArray_GET_SIZE(self)) lim = PyByteArray_GET_SIZE(self) - cur - 1; memmove(self->ob_bytes + cur - i, @@ -664,7 +664,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } /* Move the tail of the bytes, in one chunk */ cur = start + slicelen*step; - if (cur < PyByteArray_GET_SIZE(self)) { + if (cur < (size_t)PyByteArray_GET_SIZE(self)) { memmove(self->ob_bytes + cur - slicelen, self->ob_bytes + cur, PyByteArray_GET_SIZE(self) - cur); @@ -844,13 +844,14 @@ bytearray_repr(PyByteArrayObject *self) const char *quote_postfix = ")"; Py_ssize_t length = Py_SIZE(self); /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */ - size_t newsize = 14 + 4 * length; + size_t newsize; PyObject *v; - if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) { + 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 = PyUnicode_FromUnicode(NULL, newsize); if (v == NULL) { return NULL; diff --git a/Objects/listobject.c b/Objects/listobject.c index a97d47506f..88e22911f0 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -126,11 +126,11 @@ PyList_New(Py_ssize_t size) PyErr_BadInternalCall(); return NULL; } - nbytes = size * sizeof(PyObject *); /* Check for overflow without an actual overflow, * which can cause compiler to optimise out */ - if (size > PY_SIZE_MAX / sizeof(PyObject *)) + if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *)) return PyErr_NoMemory(); + nbytes = size * sizeof(PyObject *); if (numfree) { numfree--; op = free_list[numfree]; @@ -1343,7 +1343,7 @@ merge_getmem(MergeState *ms, Py_ssize_t need) * we don't care what's in the block. */ merge_freemem(ms); - if (need > PY_SSIZE_T_MAX / sizeof(PyObject*)) { + if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) { PyErr_NoMemory(); return -1; } @@ -2456,7 +2456,8 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) step = -step; } - assert(slicelength <= PY_SIZE_MAX / sizeof(PyObject*)); + assert((size_t)slicelength <= + PY_SIZE_MAX / sizeof(PyObject*)); garbage = (PyObject**) PyMem_MALLOC(slicelength*sizeof(PyObject*)); @@ -2472,13 +2473,13 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) and then tail end of the list that was not covered by the slice */ for (cur = start, i = 0; - cur < stop; + cur < (size_t)stop; cur += step, i++) { Py_ssize_t lim = step - 1; garbage[i] = PyList_GET_ITEM(self, cur); - if (cur + step >= Py_SIZE(self)) { + if (cur + step >= (size_t)Py_SIZE(self)) { lim = Py_SIZE(self) - cur - 1; } @@ -2487,7 +2488,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) lim * sizeof(PyObject *)); } cur = start + slicelength*step; - if (cur < Py_SIZE(self)) { + if (cur < (size_t)Py_SIZE(self)) { memmove(self->ob_item + cur - slicelength, self->ob_item + cur, (Py_SIZE(self) - cur) * -- cgit v1.2.1 From 6838121c3eaa591b57b4625f72c7ee6b6011574d Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 22 Feb 2010 16:34:50 +0000 Subject: Merged revisions 78319 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78319 | ezio.melotti | 2010-02-22 18:30:58 +0200 (Mon, 22 Feb 2010) | 1 line #7482: clarify error message in case of division by zero of float and complex numbers. ........ --- Objects/complexobject.c | 2 +- Objects/floatobject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 73183676a6..4821d1e3a2 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -504,7 +504,7 @@ complex_div(PyObject *v, PyObject *w) quot = c_quot(a, b); PyFPE_END_PROTECT(quot) if (errno == EDOM) { - PyErr_SetString(PyExc_ZeroDivisionError, "complex division"); + PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); return NULL; } return PyComplex_FromCComplex(quot); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 33196ff476..238022b3bc 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -570,7 +570,7 @@ float_div(PyObject *v, PyObject *w) #ifdef Py_NAN if (b == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "float division"); + "float division by zero"); return NULL; } #endif -- cgit v1.2.1 From 6c0bca895c9a0dc6c1cadcb6a5775292ca5ba1ad Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 22 Feb 2010 18:54:44 +0000 Subject: Merged revisions 78329 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78329 | eric.smith | 2010-02-22 13:33:47 -0500 (Mon, 22 Feb 2010) | 1 line Issue #7988: Fix default alignment to be right aligned for complex.__format__. Now it matches other numeric types. ........ --- Objects/stringlib/formatter.h | 50 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index f4a3ea3d58..1bd7acb03c 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -141,6 +141,26 @@ typedef struct { 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 %d\n", format->width); + printf("internal format spec: thousands_separators %d\n", + format->thousands_separators); + printf("internal format spec: precision %d\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. @@ -151,7 +171,8 @@ static int parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, Py_ssize_t format_spec_len, InternalFormatSpec *format, - char default_type) + char default_type, + char default_align) { STRINGLIB_CHAR *ptr = format_spec; STRINGLIB_CHAR *end = format_spec + format_spec_len; @@ -162,7 +183,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, Py_ssize_t consumed; format->fill_char = '\0'; - format->align = '\0'; + format->align = default_align; format->alternate = 0; format->sign = '\0'; format->width = -1; @@ -296,14 +317,19 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align, *n_total = nchars; } - /* figure out how much leading space we need, based on the + /* 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 + 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; } @@ -505,9 +531,13 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, case '=': spec->n_spadding = n_padding; break; + case '>': + spec->n_lpadding = n_padding; + break; default: - /* Handles '>', plus catch-all just in case. */ + /* Shouldn't get here, but treat it as '>' */ spec->n_lpadding = n_padding; + assert(0); break; } } @@ -1190,7 +1220,7 @@ format_complex_internal(PyObject *value, /* 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 = '\0'; + tmp_format.align = '<'; tmp_format.width = -1; /* Calculate how much memory we'll need. */ @@ -1266,7 +1296,7 @@ FORMAT_STRING(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 's')) + &format, 's', '<')) goto done; /* type conversion? */ @@ -1306,7 +1336,7 @@ format_int_or_long(PyObject* obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 'd')) + &format, 'd', '>')) goto done; /* type conversion? */ @@ -1417,7 +1447,7 @@ FORMAT_FLOAT(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, '\0')) + &format, '\0', '>')) goto done; /* type conversion? */ @@ -1465,7 +1495,7 @@ FORMAT_COMPLEX(PyObject *obj, /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, '\0')) + &format, '\0', '>')) goto done; /* type conversion? */ -- cgit v1.2.1 From 16669f4446d9527a216441ef6dee216e74a5b1a4 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Tue, 23 Feb 2010 00:22:24 +0000 Subject: Merged revisions 78349 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78349 | eric.smith | 2010-02-22 19:11:16 -0500 (Mon, 22 Feb 2010) | 1 line Issue #6902: Fix problem with built-in types format incorrectly with 0 padding. ........ --- Objects/stringlib/formatter.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 1bd7acb03c..a807b97fa8 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -151,10 +151,10 @@ DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) 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 %d\n", format->width); + 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 %d\n", format->precision); + printf("internal format spec: precision %zd\n", format->precision); printf("internal format spec: type %c\n", format->type); printf("\n"); } @@ -181,6 +181,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, the input string */ Py_ssize_t consumed; + int align_specified = 0; format->fill_char = '\0'; format->align = default_align; @@ -196,10 +197,12 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, if (end-ptr >= 2 && is_alignment_token(ptr[1])) { format->align = ptr[1]; format->fill_char = ptr[0]; + align_specified = 1; ptr += 2; } else if (end-ptr >= 1 && is_alignment_token(ptr[0])) { format->align = ptr[0]; + align_specified = 1; ++ptr; } @@ -219,7 +222,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, /* The special case for 0-padding (backwards compat) */ if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') { format->fill_char = '0'; - if (format->align == '\0') { + if (!align_specified) { format->align = '='; } ++ptr; @@ -495,7 +498,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, /* min_width can go negative, that's okay. format->width == -1 means we don't care. */ - if (format->fill_char == '0') + if (format->fill_char == '0' && format->align == '=') spec->n_min_width = format->width - n_non_digit_non_padding; else spec->n_min_width = 0; -- cgit v1.2.1 From ca740934f87997fb58d50ca714b61a056b468b12 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Wed, 24 Feb 2010 15:42:29 +0000 Subject: Merged revisions 78418 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78418 | eric.smith | 2010-02-24 09:15:36 -0500 (Wed, 24 Feb 2010) | 1 line Issue #7309: Unchecked pointer access when converting UnicodeEncodeError, UnicodeDecodeError, and UnicodeTranslateError to strings. ........ --- Objects/exceptions.c | 113 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 34 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 0e28f0fb70..7025b6f8aa 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1434,8 +1434,20 @@ static PyObject * UnicodeEncodeError_str(PyObject *self) { PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; - - if (uself->end==uself->start+1) { + PyObject *result = NULL; + PyObject *reason_str = NULL; + PyObject *encoding_str = NULL; + + /* 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]; const char *fmt; if (badchar <= 0xff) @@ -1444,21 +1456,25 @@ UnicodeEncodeError_str(PyObject *self) fmt = "'%U' codec can't encode character '\\u%04x' in position %zd: %U"; else fmt = "'%U' codec can't encode character '\\U%08x' in position %zd: %U"; - return PyUnicode_FromFormat( + result = PyUnicode_FromFormat( fmt, - ((PyUnicodeErrorObject *)self)->encoding, + encoding_str, badchar, uself->start, - ((PyUnicodeErrorObject *)self)->reason - ); + reason_str); } - return PyUnicode_FromFormat( - "'%U' codec can't encode characters in position %zd-%zd: %U", - ((PyUnicodeErrorObject *)self)->encoding, - uself->start, - uself->end-1, - ((PyUnicodeErrorObject *)self)->reason - ); + else { + result = PyUnicode_FromFormat( + "'%U' codec can't encode characters in position %zd-%zd: %U", + encoding_str, + uself->start, + uself->end-1, + reason_str); + } +done: + Py_XDECREF(reason_str); + Py_XDECREF(encoding_str); + return result; } static PyTypeObject _PyExc_UnicodeEncodeError = { @@ -1536,24 +1552,41 @@ static PyObject * UnicodeDecodeError_str(PyObject *self) { PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; - - if (uself->end==uself->start+1) { + PyObject *result = NULL; + PyObject *reason_str = NULL; + PyObject *encoding_str = NULL; + + /* 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 < PyBytes_GET_SIZE(uself->object) && uself->end == uself->start+1) { int byte = (int)(PyBytes_AS_STRING(((PyUnicodeErrorObject *)self)->object)[uself->start]&0xff); - return PyUnicode_FromFormat( + result = PyUnicode_FromFormat( "'%U' codec can't decode byte 0x%02x in position %zd: %U", - ((PyUnicodeErrorObject *)self)->encoding, + encoding_str, byte, uself->start, - ((PyUnicodeErrorObject *)self)->reason - ); + reason_str); } - return PyUnicode_FromFormat( - "'%U' codec can't decode bytes in position %zd-%zd: %U", - ((PyUnicodeErrorObject *)self)->encoding, - uself->start, - uself->end-1, - ((PyUnicodeErrorObject *)self)->reason - ); + else { + result = PyUnicode_FromFormat( + "'%U' codec can't decode bytes in position %zd-%zd: %U", + encoding_str, + uself->start, + uself->end-1, + reason_str + ); + } +done: + Py_XDECREF(reason_str); + Py_XDECREF(encoding_str); + return result; } static PyTypeObject _PyExc_UnicodeDecodeError = { @@ -1617,8 +1650,16 @@ static PyObject * UnicodeTranslateError_str(PyObject *self) { PyUnicodeErrorObject *uself = (PyUnicodeErrorObject *)self; + PyObject *result = NULL; + PyObject *reason_str = NULL; - if (uself->end==uself->start+1) { + /* 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]; const char *fmt; if (badchar <= 0xff) @@ -1631,15 +1672,19 @@ UnicodeTranslateError_str(PyObject *self) fmt, badchar, uself->start, - uself->reason + reason_str ); + } else { + result = PyUnicode_FromFormat( + "can't translate characters in position %zd-%zd: %U", + uself->start, + uself->end-1, + reason_str + ); } - return PyUnicode_FromFormat( - "can't translate characters in position %zd-%zd: %U", - uself->start, - uself->end-1, - uself->reason - ); +done: + Py_XDECREF(reason_str); + return result; } static PyTypeObject _PyExc_UnicodeTranslateError = { -- cgit v1.2.1 From 8a88b1296a08a9c7514392812bef0817ee67ae20 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 25 Feb 2010 01:22:28 +0000 Subject: plug reference leak --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 7025b6f8aa..b432d6bab2 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1668,7 +1668,7 @@ UnicodeTranslateError_str(PyObject *self) fmt = "can't translate character '\\u%04x' in position %zd: %U"; else fmt = "can't translate character '\\U%08x' in position %zd: %U"; - return PyUnicode_FromFormat( + result = PyUnicode_FromFormat( fmt, badchar, uself->start, -- cgit v1.2.1 From c9836ad9fec5c327ecd951649c49ed97b8bf12cf Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 27 Feb 2010 08:33:11 +0000 Subject: Update a comment with more details. --- Objects/unicodeobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 79b0aa7457..3ee90b58dd 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1609,7 +1609,8 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) } /* Convert the argument to a bytes object, according to the file - system encoding */ + system encoding. The addr param must be a PyObject**. + This is designed to be used with "O&" in PyArg_Parse APIs. */ int PyUnicode_FSConverter(PyObject* arg, void* addr) -- cgit v1.2.1 From a57a70eb28f52541f403f2124a97c1d6147e1633 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 1 Mar 2010 04:08:34 +0000 Subject: Merged revisions 78515-78516,78522 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78515 | georg.brandl | 2010-02-28 20:19:17 +0200 (Sun, 28 Feb 2010) | 1 line #8030: make builtin type docstrings more consistent: use "iterable" instead of "seq(uence)", use "new" to show that set() always returns a new object. ........ r78516 | georg.brandl | 2010-02-28 20:26:37 +0200 (Sun, 28 Feb 2010) | 1 line The set types can also be called without arguments. ........ r78522 | ezio.melotti | 2010-03-01 01:59:00 +0200 (Mon, 01 Mar 2010) | 1 line #8030: more docstring fix for builtin types. ........ --- Objects/dictobject.c | 8 ++++---- Objects/listobject.c | 4 ++-- Objects/setobject.c | 6 ++++-- Objects/tupleobject.c | 8 ++++---- 4 files changed, 14 insertions(+), 12 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 03f2010ed5..1d36e1d4dc 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2100,12 +2100,12 @@ dict_iter(PyDictObject *dict) } PyDoc_STRVAR(dictionary_doc, -"dict() -> new empty dictionary.\n" +"dict() -> new empty dictionary\n" "dict(mapping) -> new dictionary initialized from a mapping object's\n" -" (key, value) pairs.\n" -"dict(seq) -> new dictionary initialized as if via:\n" +" (key, value) pairs\n" +"dict(iterable) -> new dictionary initialized as if via:\n" " d = {}\n" -" for k, v in seq:\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)"); diff --git a/Objects/listobject.c b/Objects/listobject.c index 88e22911f0..ae8721e653 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2357,8 +2357,8 @@ static PySequenceMethods list_as_sequence = { }; PyDoc_STRVAR(list_doc, -"list() -> new list\n" -"list(sequence) -> new list initialized from sequence's items"); +"list() -> new empty list\n" +"list(iterable) -> new list initialized from iterable's items"); static PyObject * list_subscript(PyListObject* self, PyObject* item) diff --git a/Objects/setobject.c b/Objects/setobject.c index b296f9f329..7ea8e32374 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -2090,7 +2090,8 @@ static PyNumberMethods set_as_number = { }; PyDoc_STRVAR(set_doc, -"set(iterable) --> set object\n\ +"set() -> new empty set object\n\ +set(iterable) -> new set object\n\ \n\ Build an unordered collection of unique elements."); @@ -2187,7 +2188,8 @@ static PyNumberMethods frozenset_as_number = { }; PyDoc_STRVAR(frozenset_doc, -"frozenset(iterable) --> frozenset object\n\ +"frozenset() -> empty frozenset object\n\ +frozenset(iterable) -> frozenset object\n\ \n\ Build an immutable unordered collection of unique elements."); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 884174dca4..9145b58806 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -656,10 +656,10 @@ tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(tuple_doc, -"tuple() -> an empty tuple\n" -"tuple(sequence) -> tuple initialized from sequence's items\n" -"\n" -"If the argument is a tuple, the return value is the same object."); +"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 */ -- cgit v1.2.1 From 1fe05e96ecf7cec6d9f5515c5784221d132081f1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 12 Mar 2010 17:00:41 +0000 Subject: Issue #6697: use %U format instead of _PyUnicode_AsString(), because _PyUnicode_AsString() was not checked for error (NULL). The unicode string is no more truncated to 200 or 400 *bytes*. --- Objects/funcobject.c | 4 ++-- Objects/typeobject.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 16851a942d..35fc32d659 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -295,9 +295,9 @@ func_set_code(PyFunctionObject *op, PyObject *value) PyTuple_GET_SIZE(op->func_closure)); if (nclosure != nfree) { PyErr_Format(PyExc_ValueError, - "%s() requires a code object with %zd free vars," + "%U() requires a code object with %zd free vars," " not %zd", - _PyUnicode_AsString(op->func_name), + op->func_name, nclosure, nfree); return -1; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index be4b6f861e..7fd4cc85e8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1295,10 +1295,15 @@ check_duplicates(PyObject *list) 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 %.400s", - o ? _PyUnicode_AsString(o) : "?"); - Py_XDECREF(o); + if (o != NULL) { + PyErr_Format(PyExc_TypeError, + "duplicate base class %U", + o); + Py_DECREF(o); + } else { + PyErr_SetString(PyExc_TypeError, + "duplicate base class"); + } return -1; } } -- cgit v1.2.1 From f6beb89b6a4bf2c4b64838e4eeb8c118c33d841c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 12 Mar 2010 17:17:58 +0000 Subject: Issue #6697: catch _PyUnicode_AsString() errors in getattr() and setattr() builtin functions. --- Objects/object.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index b0a54719a0..a332c6c85e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -799,8 +799,12 @@ PyObject_GetAttr(PyObject *v, PyObject *name) } if (tp->tp_getattro != NULL) return (*tp->tp_getattro)(v, name); - if (tp->tp_getattr != NULL) - return (*tp->tp_getattr)(v, _PyUnicode_AsString(name)); + if (tp->tp_getattr != NULL) { + char *name_str = _PyUnicode_AsString(name); + if (name_str == NULL) + return NULL; + return (*tp->tp_getattr)(v, name_str); + } PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%U'", tp->tp_name, name); @@ -840,7 +844,10 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) return err; } if (tp->tp_setattr != NULL) { - err = (*tp->tp_setattr)(v, _PyUnicode_AsString(name), value); + char *name_str = _PyUnicode_AsString(name); + if (name_str == NULL) + return -1; + err = (*tp->tp_setattr)(v, name_str, value); Py_DECREF(name); return err; } @@ -1019,8 +1026,8 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) } PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, _PyUnicode_AsString(name)); + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); done: Py_DECREF(name); return res; -- cgit v1.2.1 From b5491fb1e1dfc73ebbe9dbd054efc73a526d056a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 13 Mar 2010 00:19:17 +0000 Subject: Merged revisions 78886 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78886 | victor.stinner | 2010-03-13 01:13:22 +0100 (sam., 13 mars 2010) | 2 lines Issue #7818: set().test_c_api() doesn't expect a set('abc'), modify the set. ........ --- Objects/setobject.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 7ea8e32374..c3eabf536b 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -2360,11 +2360,25 @@ test_c_api(PySetObject *so) PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x; PyObject *ob = (PyObject *)so; long hash; + PyObject *str; - /* Verify preconditions and exercise type/size checks */ + /* Verify preconditions */ assert(PyAnySet_Check(ob)); assert(PyAnySet_CheckExact(ob)); assert(!PyFrozenSet_CheckExact(ob)); + + /* so.clear(); so |= set("abc"); */ + str = PyUnicode_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); -- cgit v1.2.1 From 81ab44551ac17d31f13993f81a92c5807499b740 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 13 Mar 2010 09:48:39 +0000 Subject: Issue #7845: Make 1j.__le__(2j) return NotImplemented rather than raising TypeError. --- Objects/complexobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 4821d1e3a2..0e55bc323c 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -625,10 +625,8 @@ complex_richcompare(PyObject *v, PyObject *w, int op) TO_COMPLEX(w, j); if (op != Py_EQ && op != Py_NE) { - /* XXX Should eventually return NotImplemented */ - PyErr_SetString(PyExc_TypeError, - "no ordering relation is defined for complex numbers"); - return NULL; + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) -- cgit v1.2.1 From 84afda5e821f701ebae309f95b063f1e5e32e998 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 13 Mar 2010 11:34:40 +0000 Subject: Issue #8014: Fix PyLong_As methods not to produce an internal error on non-integer input: they now raise TypeError instead. This is needed for attributes declared via PyMemberDefs. --- Objects/longobject.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index ce87084e28..d182e7ce30 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -435,10 +435,15 @@ PyLong_AsSsize_t(PyObject *vv) { Py_ssize_t i; int sign; - if (vv == NULL || !PyLong_Check(vv)) { + if (vv == NULL) { PyErr_BadInternalCall(); return -1; } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { @@ -485,10 +490,15 @@ PyLong_AsUnsignedLong(PyObject *vv) unsigned long x, prev; Py_ssize_t i; - if (vv == NULL || !PyLong_Check(vv)) { + if (vv == NULL) { PyErr_BadInternalCall(); - return (unsigned long) -1; + return (unsigned long)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long)-1; } + v = (PyLongObject *)vv; i = Py_SIZE(v); x = 0; @@ -523,10 +533,15 @@ PyLong_AsSize_t(PyObject *vv) size_t x, prev; Py_ssize_t i; - if (vv == NULL || !PyLong_Check(vv)) { + if (vv == NULL) { PyErr_BadInternalCall(); - return (unsigned long) -1; + return (size_t) -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (size_t)-1; } + v = (PyLongObject *)vv; i = Py_SIZE(v); x = 0; -- cgit v1.2.1 From 227334cb2eacf4a9087140ef7726d6408b4798e5 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 14 Mar 2010 06:49:55 +0000 Subject: * Replaces the internals of the subprocess module from fork through exec on POSIX systems with a C extension module. This is required in order for the subprocess module to be made thread safe. The pure python implementation is retained so that it can continue to be used if for some reason the _posixsubprocess extension module is not available. The unittest executes tests on both code paths to guarantee compatibility. * Moves PyLong_FromPid and PyLong_AsPid from posixmodule.c into longobject.h. Code reviewed by jeffrey.yasskin at http://codereview.appspot.com/223077/show --- Objects/abstract.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index d4cba74798..952ad40329 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2722,3 +2722,63 @@ PyIter_Next(PyObject *iter) PyErr_Clear(); return result; } + + +/* + * Flatten a sequence of bytes() objects into a C array of + * NULL terminated string pointers with a NULL char* terminating the array. + * (ie: an argv or env list) + * + * Memory allocated for the returned list is allocated using malloc() and MUST + * be freed by the caller using a free() loop or _Py_FreeCharPArray(). + */ +char *const * +_PySequence_BytesToCharpArray(PyObject* self) +{ + char **array; + Py_ssize_t i, argc; + + argc = PySequence_Size(self); + if (argc == -1) + return NULL; + + array = malloc((argc + 1) * sizeof(char *)); + if (array == NULL) { + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < argc; ++i) { + char *data; + PyObject *item = PySequence_GetItem(self, i); + data = PyBytes_AsString(item); + if (data == NULL) { + /* NULL terminate before freeing. */ + array[i] = NULL; + goto fail; + } + array[i] = strdup(data); + if (!array[i]) { + PyErr_NoMemory(); + goto fail; + } + } + array[argc] = NULL; + + return array; + +fail: + _Py_FreeCharPArray(array); + return NULL; +} + + +/* Free's a NULL terminated char** array of C strings. */ +void +_Py_FreeCharPArray(char *const array[]) +{ + Py_ssize_t i; + for (i = 0; array[i] != NULL; ++i) { + free(array[i]); + } + free((void*)array); +} -- cgit v1.2.1 From e27b8a3cefed396df66c5dc7ae4f032b4d6993bb Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 15 Mar 2010 06:07:42 +0000 Subject: * Fix the refcount leak in _PySequence_BytesToCharpArray from r78946. * Also fixes a potential extra DECREF of an arg in the error case within _posixsubprocess.fork_exec() by not reusing the process_args variable. --- Objects/abstract.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 952ad40329..cd5a9fd299 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2737,6 +2737,7 @@ _PySequence_BytesToCharpArray(PyObject* self) { char **array; Py_ssize_t i, argc; + PyObject *item = NULL; argc = PySequence_Size(self); if (argc == -1) @@ -2749,7 +2750,7 @@ _PySequence_BytesToCharpArray(PyObject* self) } for (i = 0; i < argc; ++i) { char *data; - PyObject *item = PySequence_GetItem(self, i); + item = PySequence_GetItem(self, i); data = PyBytes_AsString(item); if (data == NULL) { /* NULL terminate before freeing. */ @@ -2761,12 +2762,14 @@ _PySequence_BytesToCharpArray(PyObject* self) PyErr_NoMemory(); goto fail; } + Py_DECREF(item); } array[argc] = NULL; return array; fail: + Py_XDECREF(item); _Py_FreeCharPArray(array); return NULL; } -- cgit v1.2.1 From 7ecbae18b21572e4d38362a23844cab1b94e03d7 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Thu, 18 Mar 2010 22:11:01 +0000 Subject: Merged revisions 79059 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79059 | florent.xicluna | 2010-03-18 22:50:06 +0100 (jeu, 18 mar 2010) | 2 lines Issue #8024: Update the Unicode database to 5.2 ........ --- Objects/unicodetype_db.h | 2153 +++++++++++++++++++++++++--------------------- 1 file changed, 1192 insertions(+), 961 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 00a43e8014..8c8955cbaa 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -64,11 +64,13 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 10795, 0, 0, 0, 1921}, {0, 65373, 0, 0, 0, 1921}, {0, 10792, 0, 0, 0, 1921}, + {10815, 0, 10815, 0, 0, 1801}, {0, 65341, 0, 0, 0, 1921}, {0, 69, 0, 0, 0, 1921}, {0, 71, 0, 0, 0, 1921}, {10783, 0, 10783, 0, 0, 1801}, {10780, 0, 10780, 0, 0, 1801}, + {10782, 0, 10782, 0, 0, 1801}, {65326, 0, 65326, 0, 0, 1801}, {65330, 0, 65330, 0, 0, 1801}, {65331, 0, 65331, 0, 0, 1801}, @@ -175,6 +177,8 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 54756, 0, 0, 0, 1921}, {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, + {0, 54754, 0, 0, 0, 1921}, + {0, 54721, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, {0, 0, 0, 0, 0, 5889}, {42877, 7545, 42877, 0, 0, 3969}, @@ -185,508 +189,508 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { /* 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, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, - 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 63, 64, 65, 66, 63, - 63, 63, 67, 68, 69, 63, 63, 63, 63, 63, 63, 70, 16, 71, 72, 73, 74, 75, - 76, 63, 77, 78, 79, 80, 81, 82, 83, 63, 63, 84, 85, 40, 40, 40, 40, 40, - 40, 86, 40, 40, 40, 40, 40, 87, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 88, 89, 90, 91, 40, 40, 40, 92, 40, 40, - 40, 93, 94, 40, 40, 40, 40, 40, 95, 40, 40, 40, 96, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 97, 98, 99, 40, 40, 40, 40, 40, 40, 100, 101, 40, 40, - 40, 40, 40, 40, 40, 40, 102, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 40, 40, 104, 40, 40, 40, 40, - 100, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 105, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 106, 107, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 109, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 110, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 111, 40, 40, 112, 113, 114, 115, 116, 117, 118, 16, 119, 16, - 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 120, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 123, 124, 125, - 126, 127, 128, 40, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 16, - 139, 140, 141, 142, 143, 16, 16, 16, 16, 16, 16, 144, 16, 145, 16, 146, - 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, 40, 40, 40, 40, 40, 40, 147, 16, 148, 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, 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, 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, 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, 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, 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, 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, - 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, 63, - 149, 150, 151, 152, 16, 153, 16, 154, 155, 156, 157, 158, 159, 160, 161, - 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, 16, 16, 16, 16, 162, 163, 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, 164, 165, 166, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 86, 167, 40, 168, 169, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 170, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 171, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 172, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 173, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 174, 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, 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, - 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, 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, 40, 170, 40, 40, 175, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 176, 16, - 177, 178, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 179, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 179, + 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, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, + 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 17, 143, 144, 145, 146, 147, 17, 17, 17, 17, 17, 17, 148, 17, 149, 17, + 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 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, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 155, 17, 156, + 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, 157, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 158, 159, 160, 161, 17, 162, 17, 163, 164, 165, 166, 167, 168, + 169, 170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 171, 172, 173, + 174, 175, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 176, 177, 178, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 179, 34, 180, 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, 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, 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, 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, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 186, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 187, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 182, 34, 34, 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, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 189, 17, 190, 191, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 192, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 192, }; static unsigned char index2[] = { @@ -720,11 +724,11 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 58, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26, - 27, 60, 61, 19, 19, 26, 27, 62, 63, 64, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 65, 66, 19, 67, 68, 19, 69, 69, 19, 70, 19, 71, 19, 19, 19, 19, - 69, 19, 19, 72, 19, 19, 19, 19, 73, 74, 19, 75, 19, 19, 19, 74, 19, 76, - 77, 19, 19, 78, 19, 19, 19, 19, 19, 19, 19, 79, 19, 19, 80, 19, 19, 80, - 19, 19, 19, 19, 80, 81, 82, 82, 83, 19, 19, 19, 19, 19, 84, 19, 50, 19, + 27, 60, 61, 62, 62, 26, 27, 63, 64, 65, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 66, 67, 68, 69, 70, 19, 71, 71, 19, 72, 19, 73, 19, 19, 19, 19, + 71, 19, 19, 74, 19, 19, 19, 19, 75, 76, 19, 77, 19, 19, 19, 76, 19, 78, + 79, 19, 19, 80, 19, 19, 19, 19, 19, 19, 19, 81, 19, 19, 82, 19, 19, 82, + 19, 19, 19, 19, 82, 83, 84, 84, 85, 19, 19, 19, 19, 19, 86, 19, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, @@ -734,40 +738,40 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 85, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 87, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 86, - 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 87, 17, 88, 88, 88, 0, 89, 0, 90, 90, + 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 88, + 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 89, 17, 90, 90, 90, 0, 91, 0, 92, 92, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 91, 92, 92, 92, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 93, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 94, 95, 95, 96, 97, 98, 99, 99, 99, 100, 101, - 102, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 103, 104, 105, 19, 106, 107, 5, 26, 27, 108, - 26, 27, 19, 58, 58, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 93, 94, 94, 94, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 95, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 96, 97, 97, 98, 99, 100, 101, 101, 101, 102, 103, + 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 105, 106, 107, 19, 108, 109, 5, 26, 27, 110, + 26, 27, 19, 58, 58, 58, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 5, 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 110, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 111, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 112, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 50, 5, 5, 5, 5, 5, 5, 0, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0, @@ -800,29 +804,35 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17, 17, + 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 0, 50, 17, 17, 17, 17, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 0, 50, 17, 17, 17, 17, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 5, 24, 5, 0, 0, 0, - 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, - 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, + 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, + 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, + 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, + 0, 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, @@ -872,14 +882,14 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 114, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 116, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, - 50, 114, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 116, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, @@ -893,7 +903,7 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -903,55 +913,49 @@ static unsigned char index2[] = { 17, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, - 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 116, 117, 118, 119, 120, 121, 122, 123, 124, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 118, 119, 120, 121, 122, 123, 124, 125, 126, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -963,101 +967,106 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 5, 5, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 5, 5, 5, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 7, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 17, 17, 17, 17, 17, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 50, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, + 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, - 0, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 50, 126, 19, 19, 19, 127, 19, 19, 19, 19, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 19, 19, 50, 128, 19, 19, 19, 129, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, @@ -1065,48 +1074,50 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 19, 19, 19, 19, 19, 128, 19, 19, 129, 19, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 130, + 19, 19, 131, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 130, 130, - 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, - 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, - 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, - 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, - 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, - 131, 131, 131, 0, 0, 19, 130, 19, 130, 19, 130, 19, 130, 0, 131, 0, 131, - 0, 131, 0, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, - 131, 131, 131, 131, 131, 132, 132, 133, 133, 133, 133, 134, 134, 135, - 135, 136, 136, 137, 137, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, - 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, 130, 130, - 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, - 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 19, - 139, 19, 0, 19, 19, 131, 131, 140, 140, 141, 5, 142, 5, 5, 5, 19, 139, - 19, 0, 19, 19, 143, 143, 143, 143, 141, 5, 5, 5, 130, 130, 19, 19, 0, 0, - 19, 19, 131, 131, 144, 144, 0, 5, 5, 5, 130, 130, 19, 19, 19, 105, 19, - 19, 131, 131, 145, 145, 108, 5, 5, 5, 0, 0, 19, 139, 19, 0, 19, 19, 146, - 146, 147, 147, 141, 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 148, 19, 0, 0, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 19, - 148, 23, 20, 21, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 0, 50, 50, - 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 5, 99, 5, 5, 5, 5, 99, 5, 5, 19, 99, 99, 99, 19, 19, 99, 99, 99, 19, 5, - 99, 5, 5, 155, 99, 99, 99, 99, 99, 5, 5, 5, 5, 5, 5, 99, 5, 156, 5, 99, - 5, 157, 158, 99, 99, 155, 19, 99, 99, 159, 99, 19, 50, 50, 50, 50, 19, 5, - 5, 19, 19, 99, 99, 5, 5, 5, 5, 5, 99, 19, 19, 19, 19, 5, 5, 5, 5, 160, 5, - 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 125, 125, 125, 26, 27, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 132, 132, 132, 132, 132, 132, + 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, + 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, 132, 132, 132, 132, + 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, + 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, + 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, + 19, 132, 19, 132, 19, 132, 19, 132, 0, 133, 0, 133, 0, 133, 0, 133, 132, + 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, + 133, 134, 134, 135, 135, 135, 135, 136, 136, 137, 137, 138, 138, 139, + 139, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, + 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, + 140, 140, 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, + 140, 140, 140, 140, 140, 140, 140, 140, 132, 132, 19, 141, 19, 0, 19, 19, + 133, 133, 142, 142, 143, 5, 144, 5, 5, 5, 19, 141, 19, 0, 19, 19, 145, + 145, 145, 145, 143, 5, 5, 5, 132, 132, 19, 19, 0, 0, 19, 19, 133, 133, + 146, 146, 0, 5, 5, 5, 132, 132, 19, 19, 19, 107, 19, 19, 133, 133, 147, + 147, 110, 5, 5, 5, 0, 0, 19, 141, 19, 0, 19, 19, 148, 148, 149, 149, 143, + 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, + 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 150, 50, 0, 0, + 151, 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 50, 150, 23, 20, 21, 151, + 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 101, 5, 5, 5, 5, + 101, 5, 5, 19, 101, 101, 101, 19, 19, 101, 101, 101, 19, 5, 101, 5, 5, + 157, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 101, 5, 158, 5, 101, 5, + 159, 160, 101, 101, 157, 19, 101, 101, 161, 101, 19, 50, 50, 50, 50, 19, + 5, 5, 19, 19, 101, 101, 5, 5, 5, 5, 5, 101, 19, 19, 19, 19, 5, 5, 5, 5, + 162, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 127, 127, 127, 26, 27, 127, 127, 127, 127, 24, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1120,135 +1131,135 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, - 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, - 151, 152, 153, 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 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, 148, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 148, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 151, 152, 153, 154, 155, + 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, + 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, + 21, 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 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, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 150, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, + 150, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, - 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, 149, 150, 151, 152, 153, - 154, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, + 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, 20, 21, 151, 152, 153, 154, + 155, 156, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 26, 27, 165, 166, 167, - 168, 169, 26, 27, 26, 27, 26, 27, 170, 171, 172, 0, 19, 26, 27, 19, 26, - 27, 19, 19, 19, 19, 19, 19, 50, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 24, 5, 5, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 26, 27, 167, 168, + 169, 170, 171, 26, 27, 26, 27, 26, 27, 172, 173, 174, 175, 19, 26, 27, + 19, 26, 27, 19, 19, 19, 19, 19, 19, 50, 176, 176, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 19, 5, 5, 5, 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 24, 5, 5, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 86, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 88, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 125, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, - 125, 125, 125, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 127, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 17, 17, 17, 17, 17, 17, 5, 50, + 50, 50, 50, 50, 5, 5, 127, 127, 127, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, + 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, - 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 5, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, - 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 5, 5, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1257,7 +1268,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1266,56 +1277,56 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 174, - 50, 50, 174, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 178, 50, 50, 178, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 174, 50, 174, 174, 174, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 178, 178, 50, 50, 50, 50, + 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 178, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 174, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1323,7 +1334,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1331,24 +1342,25 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 178, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 174, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1359,175 +1371,196 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 19, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, - 26, 27, 175, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, + 19, 19, 26, 27, 26, 27, 179, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, + 5, 5, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 17, - 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, - 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 17, 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, + 50, 5, 5, 5, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50, - 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 17, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, + 50, 50, 17, 17, 50, 50, 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 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, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, + 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1544,8 +1577,8 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, - 86, 86, 86, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, + 88, 88, 88, 88, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1559,13 +1592,13 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 86, 5, 5, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, 88, 5, 5, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, - 0, 0, 86, 50, 86, 50, 86, 0, 86, 50, 86, 50, 86, 50, 86, 50, 86, 50, 50, + 0, 0, 88, 50, 88, 50, 88, 0, 88, 50, 88, 50, 88, 50, 88, 50, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1581,7 +1614,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 114, 114, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 116, 116, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, @@ -1602,11 +1635,11 @@ static unsigned char index2[] = { 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1622,22 +1655,22 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 125, 50, 50, 50, 50, 50, 50, 50, 50, 125, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 127, 50, 50, 50, 50, 50, 50, 50, 50, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 5, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1649,20 +1682,46 @@ static unsigned char index2[] = { 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, 50, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 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, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, + 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 151, 24, 24, 24, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, - 24, 24, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, - 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, + 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, - 23, 20, 21, 149, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, + 1, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1670,15 +1729,21 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 155, 155, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 155, 155, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 157, 157, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 157, 157, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1706,96 +1771,119 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 0, 99, - 99, 0, 0, 99, 0, 0, 99, 99, 0, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, - 99, 99, 99, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 0, 101, + 101, 0, 0, 101, 0, 0, 101, 101, 0, 0, 101, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, + 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 0, 99, 99, - 99, 99, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, + 19, 101, 101, 0, 101, 101, 101, 101, 0, 0, 101, 101, 101, 101, 101, 101, + 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 0, 99, - 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 101, 101, 0, 101, 101, 101, 101, 0, 101, 101, 101, 101, 101, + 0, 101, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, + 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, + 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, - 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, + 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, + 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, + 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 19, 0, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 19, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 150, 150, 23, 20, 21, 151, 152, 153, 154, 155, 156, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 5, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, + 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1806,32 +1894,32 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1842,26 +1930,32 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 17, 17, 17, 17, 17, 17, 17, + 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1874,13 +1968,13 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -1915,20 +2009,26 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -1939,6 +2039,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E2: case 0x1D7EC: case 0x1D7F6: + case 0x1F100: + case 0x1F101: #endif return (double) 0.0; case 0x0031: @@ -1948,7 +2050,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C1: case 0x0967: case 0x09E7: - case 0x09F4: case 0x0A67: case 0x0AE7: case 0x0B67: @@ -1969,6 +2070,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1811: case 0x1947: case 0x19D1: + case 0x19DA: + case 0x1A81: + case 0x1A91: case 0x1B51: case 0x1BB1: case 0x1C41: @@ -1994,9 +2098,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2007,8 +2114,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2021,29 +2133,41 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2055,11 +2179,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2092,8 +2222,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2111,8 +2245,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2128,7 +2266,10 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1014D: case 0x10154: case 0x10171: + case 0x1085E: case 0x10A47: + case 0x10B5F: + case 0x10B7F: #endif return (double) 1000.0; case 0x137C: @@ -2138,6 +2279,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1012B: case 0x10155: + case 0x1085F: #endif return (double) 10000.0; case 0x2188: @@ -2215,7 +2357,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C2: case 0x0968: case 0x09E8: - case 0x09F5: case 0x0A68: case 0x0AE8: case 0x0B68: @@ -2236,6 +2377,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1812: case 0x1948: case 0x19D2: + case 0x1A82: + case 0x1A92: case 0x1B52: case 0x1BB2: case 0x1C42: @@ -2263,9 +2406,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2276,7 +2422,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1015E: case 0x103D2: case 0x104A2: + case 0x10859: + case 0x1091A: case 0x10A41: + case 0x10B59: + case 0x10B79: + case 0x10E61: case 0x12400: case 0x12416: case 0x1241F: @@ -2292,12 +2443,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2315,13 +2468,18 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 @@ -2357,7 +2515,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C3: case 0x0969: case 0x09E9: - case 0x09F6: case 0x0A69: case 0x0AE9: case 0x0B69: @@ -2378,6 +2535,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1813: case 0x1949: case 0x19D3: + case 0x1A83: + case 0x1A93: case 0x1B53: case 0x1BB3: case 0x1C43: @@ -2404,15 +2563,23 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2433,16 +2600,22 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2458,6 +2631,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x10112: case 0x10165: + case 0x10E6B: case 0x1D36B: case 0x20983: #endif @@ -2465,6 +2639,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1011B: case 0x1016B: + case 0x10E74: return (double) 300.0; #endif #ifdef Py_UNICODE_WIDE @@ -2499,7 +2674,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C4: case 0x096A: case 0x09EA: - case 0x09F7: case 0x0A6A: case 0x0AEA: case 0x0B6A: @@ -2518,6 +2692,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1814: case 0x194A: case 0x19D4: + case 0x1A84: + case 0x1A94: case 0x1B54: case 0x1BB4: case 0x1C44: @@ -2541,14 +2717,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2570,6 +2752,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E6: case 0x1D7F0: case 0x1D7FA: + case 0x1F105: case 0x20064: case 0x200E2: case 0x2626D: @@ -2582,6 +2765,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x534C: #ifdef Py_UNICODE_WIDE case 0x10113: + case 0x10E6C: case 0x1D36C: case 0x2098C: case 0x2099C: @@ -2589,6 +2773,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) return (double) 40.0; #ifdef Py_UNICODE_WIDE case 0x1011C: + case 0x10E75: return (double) 400.0; #endif #ifdef Py_UNICODE_WIDE @@ -2641,6 +2826,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1815: case 0x194B: case 0x19D5: + case 0x1A85: + case 0x1A95: case 0x1B55: case 0x1BB5: case 0x1C45: @@ -2664,9 +2851,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2677,6 +2867,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10173: case 0x10321: case 0x104A5: + case 0x10E64: case 0x12403: case 0x1240A: case 0x12410: @@ -2694,6 +2885,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E7: case 0x1D7F1: case 0x1D7FB: + case 0x1F106: case 0x20121: #endif return (double) 5.0; @@ -2722,6 +2914,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10169: case 0x10174: case 0x10323: + case 0x10A7E: + case 0x10E6D: case 0x1D36D: #endif return (double) 50.0; @@ -2737,6 +2931,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1016E: case 0x1016F: case 0x10170: + case 0x10E76: #endif return (double) 500.0; case 0x2181: @@ -2778,6 +2973,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1816: case 0x194C: case 0x19D6: + case 0x1A86: + case 0x1A96: case 0x1B56: case 0x1BB6: case 0x1C46: @@ -2801,15 +2998,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2823,17 +3024,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2868,6 +3072,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1817: case 0x194D: case 0x19D7: + case 0x1A87: + case 0x1A97: case 0x1B57: case 0x1BB7: case 0x1C47: @@ -2891,13 +3097,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2912,6 +3122,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E9: case 0x1D7F3: case 0x1D7FD: + case 0x1F108: case 0x20001: #endif return (double) 7.0; @@ -2922,11 +3133,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2961,6 +3174,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1818: case 0x194E: case 0x19D8: + case 0x1A88: + case 0x1A98: case 0x1B58: case 0x1BB8: case 0x1C48: @@ -2982,13 +3197,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3002,16 +3221,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -3046,6 +3268,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1819: case 0x194F: case 0x19D9: + case 0x1A89: + case 0x1A99: case 0x1B59: case 0x1BB9: case 0x1C49: @@ -3068,13 +3292,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3090,6 +3318,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7EB: case 0x1D7F5: case 0x1D7FF: + case 0x1F10A: case 0x2F890: #endif return (double) 9.0; @@ -3099,12 +3328,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 -- cgit v1.2.1 From 2c0a5f10dd876c4fbe38b2d50fe3600cccd87f12 Mon Sep 17 00:00:00 2001 From: Collin Winter Date: Thu, 18 Mar 2010 22:46:40 +0000 Subject: Merged revisions 79060 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79060 | collin.winter | 2010-03-18 14:54:01 -0700 (Thu, 18 Mar 2010) | 4 lines Add support for weak references to code objects. This will be used by an optimization in the incoming Python 3 JIT. Patch by Reid Kleckner! ........ --- Objects/codeobject.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index a772c56a5b..3e71e4cde3 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -108,6 +108,7 @@ PyCode_New(int argcount, int kwonlyargcount, Py_INCREF(lnotab); co->co_lnotab = lnotab; co->co_zombieframe = NULL; + co->co_weakreflist = NULL; } return co; } @@ -331,6 +332,8 @@ code_dealloc(PyCodeObject *co) 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); } @@ -462,7 +465,7 @@ PyTypeObject PyCode_Type = { 0, /* tp_traverse */ 0, /* tp_clear */ code_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ -- cgit v1.2.1 From ba9b2b205784cec187a6be978391ffd776a22707 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Fri, 19 Mar 2010 01:17:46 +0000 Subject: Revert Unicode UCD 5.2 upgrade in 3.x. It broke repr() for unicode objects, and gave failures in test_bigmem. Revert 79062, 79065 and 79083. --- Objects/unicodetype_db.h | 2153 +++++++++++++++++++++------------------------- 1 file changed, 961 insertions(+), 1192 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 8c8955cbaa..00a43e8014 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -64,13 +64,11 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 10795, 0, 0, 0, 1921}, {0, 65373, 0, 0, 0, 1921}, {0, 10792, 0, 0, 0, 1921}, - {10815, 0, 10815, 0, 0, 1801}, {0, 65341, 0, 0, 0, 1921}, {0, 69, 0, 0, 0, 1921}, {0, 71, 0, 0, 0, 1921}, {10783, 0, 10783, 0, 0, 1801}, {10780, 0, 10780, 0, 0, 1801}, - {10782, 0, 10782, 0, 0, 1801}, {65326, 0, 65326, 0, 0, 1801}, {65330, 0, 65330, 0, 0, 1801}, {65331, 0, 65331, 0, 0, 1801}, @@ -177,8 +175,6 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 54756, 0, 0, 0, 1921}, {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, - {0, 54754, 0, 0, 0, 1921}, - {0, 54721, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, {0, 0, 0, 0, 0, 5889}, {42877, 7545, 42877, 0, 0, 3969}, @@ -189,508 +185,508 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { /* 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, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, - 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 17, 143, 144, 145, 146, 147, 17, 17, 17, 17, 17, 17, 148, 17, 149, 17, - 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 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, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 155, 17, 156, - 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, 157, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 158, 159, 160, 161, 17, 162, 17, 163, 164, 165, 166, 167, 168, - 169, 170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 171, 172, 173, - 174, 175, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 176, 177, 178, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 179, 34, 180, 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, 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, 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, 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, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 186, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 187, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 182, 34, 34, 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, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 189, 17, 190, 191, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 192, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 192, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, + 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 63, 64, 65, 66, 63, + 63, 63, 67, 68, 69, 63, 63, 63, 63, 63, 63, 70, 16, 71, 72, 73, 74, 75, + 76, 63, 77, 78, 79, 80, 81, 82, 83, 63, 63, 84, 85, 40, 40, 40, 40, 40, + 40, 86, 40, 40, 40, 40, 40, 87, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 88, 89, 90, 91, 40, 40, 40, 92, 40, 40, + 40, 93, 94, 40, 40, 40, 40, 40, 95, 40, 40, 40, 96, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 97, 98, 99, 40, 40, 40, 40, 40, 40, 100, 101, 40, 40, + 40, 40, 40, 40, 40, 40, 102, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 40, 40, 104, 40, 40, 40, 40, + 100, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 105, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 106, 107, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 109, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 110, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 111, 40, 40, 112, 113, 114, 115, 116, 117, 118, 16, 119, 16, + 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 120, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 123, 124, 125, + 126, 127, 128, 40, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 16, + 139, 140, 141, 142, 143, 16, 16, 16, 16, 16, 16, 144, 16, 145, 16, 146, + 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, 40, 40, 40, 40, 40, 40, 147, 16, 148, 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, 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, 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, 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, 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, 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, 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, + 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, 63, + 149, 150, 151, 152, 16, 153, 16, 154, 155, 156, 157, 158, 159, 160, 161, + 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, 16, 16, 16, 16, 162, 163, 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, 164, 165, 166, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 86, 167, 40, 168, 169, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 170, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 171, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 172, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 173, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 174, 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, 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, + 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, 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, 40, 170, 40, 40, 175, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 176, 16, + 177, 178, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 179, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 179, }; static unsigned char index2[] = { @@ -724,11 +720,11 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 58, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26, - 27, 60, 61, 62, 62, 26, 27, 63, 64, 65, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 66, 67, 68, 69, 70, 19, 71, 71, 19, 72, 19, 73, 19, 19, 19, 19, - 71, 19, 19, 74, 19, 19, 19, 19, 75, 76, 19, 77, 19, 19, 19, 76, 19, 78, - 79, 19, 19, 80, 19, 19, 19, 19, 19, 19, 19, 81, 19, 19, 82, 19, 19, 82, - 19, 19, 19, 19, 82, 83, 84, 84, 85, 19, 19, 19, 19, 19, 86, 19, 50, 19, + 27, 60, 61, 19, 19, 26, 27, 62, 63, 64, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 65, 66, 19, 67, 68, 19, 69, 69, 19, 70, 19, 71, 19, 19, 19, 19, + 69, 19, 19, 72, 19, 19, 19, 19, 73, 74, 19, 75, 19, 19, 19, 74, 19, 76, + 77, 19, 19, 78, 19, 19, 19, 19, 19, 19, 19, 79, 19, 19, 80, 19, 19, 80, + 19, 19, 19, 19, 80, 81, 82, 82, 83, 19, 19, 19, 19, 19, 84, 19, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, @@ -738,40 +734,40 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 87, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 85, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 88, - 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 89, 17, 90, 90, 90, 0, 91, 0, 92, 92, + 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 86, + 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 87, 17, 88, 88, 88, 0, 89, 0, 90, 90, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 93, 94, 94, 94, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 95, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 96, 97, 97, 98, 99, 100, 101, 101, 101, 102, 103, - 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 105, 106, 107, 19, 108, 109, 5, 26, 27, 110, - 26, 27, 19, 58, 58, 58, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 91, 92, 92, 92, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 93, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 94, 95, 95, 96, 97, 98, 99, 99, 99, 100, 101, + 102, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 103, 104, 105, 19, 106, 107, 5, 26, 27, 108, + 26, 27, 19, 58, 58, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 5, 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 112, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 110, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 111, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 50, 5, 5, 5, 5, 5, 5, 0, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0, @@ -804,35 +800,29 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, - 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17, 17, - 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 50, 17, 17, 17, 17, 17, 0, 0, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 0, 0, 50, 17, 17, 17, 17, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, - 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, - 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, - 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, - 0, 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, + 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 5, 24, 5, 0, 0, 0, + 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, + 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, @@ -882,14 +872,14 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 116, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 114, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, - 50, 116, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 114, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, @@ -903,7 +893,7 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -913,160 +903,160 @@ static unsigned char index2[] = { 17, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, - 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 118, 119, 120, 121, 122, 123, 124, 125, 126, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 116, 117, 118, 119, 120, 121, 122, 123, 124, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 5, 5, 5, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 7, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 17, 17, 17, 17, 17, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 5, 5, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, + 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 50, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 17, 17, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, - 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, + 0, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 50, 128, 19, 19, 19, 129, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 50, 126, 19, 19, 19, 127, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, @@ -1074,51 +1064,49 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 130, - 19, 19, 131, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 19, 19, 19, 19, 19, 128, 19, 19, 129, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 132, 132, 132, 132, 132, 132, - 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, - 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, 132, 132, 132, 132, - 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, - 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, - 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, - 19, 132, 19, 132, 19, 132, 19, 132, 0, 133, 0, 133, 0, 133, 0, 133, 132, - 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, - 133, 134, 134, 135, 135, 135, 135, 136, 136, 137, 137, 138, 138, 139, - 139, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, - 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, - 140, 140, 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, - 140, 140, 140, 140, 140, 140, 140, 140, 132, 132, 19, 141, 19, 0, 19, 19, - 133, 133, 142, 142, 143, 5, 144, 5, 5, 5, 19, 141, 19, 0, 19, 19, 145, - 145, 145, 145, 143, 5, 5, 5, 132, 132, 19, 19, 0, 0, 19, 19, 133, 133, - 146, 146, 0, 5, 5, 5, 132, 132, 19, 19, 19, 107, 19, 19, 133, 133, 147, - 147, 110, 5, 5, 5, 0, 0, 19, 141, 19, 0, 19, 19, 148, 148, 149, 149, 143, - 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, - 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 150, 50, 0, 0, - 151, 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 50, 150, 23, 20, 21, 151, - 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 101, 5, 5, 5, 5, - 101, 5, 5, 19, 101, 101, 101, 19, 19, 101, 101, 101, 19, 5, 101, 5, 5, - 157, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 101, 5, 158, 5, 101, 5, - 159, 160, 101, 101, 157, 19, 101, 101, 161, 101, 19, 50, 50, 50, 50, 19, - 5, 5, 19, 19, 101, 101, 5, 5, 5, 5, 5, 101, 19, 19, 19, 19, 5, 5, 5, 5, - 162, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 127, 127, 127, 26, 27, 127, 127, 127, 127, 24, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 130, 130, + 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, + 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, + 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, + 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, + 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, + 131, 131, 131, 0, 0, 19, 130, 19, 130, 19, 130, 19, 130, 0, 131, 0, 131, + 0, 131, 0, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, + 131, 131, 131, 131, 131, 132, 132, 133, 133, 133, 133, 134, 134, 135, + 135, 136, 136, 137, 137, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, + 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, 130, 130, + 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, + 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 19, + 139, 19, 0, 19, 19, 131, 131, 140, 140, 141, 5, 142, 5, 5, 5, 19, 139, + 19, 0, 19, 19, 143, 143, 143, 143, 141, 5, 5, 5, 130, 130, 19, 19, 0, 0, + 19, 19, 131, 131, 144, 144, 0, 5, 5, 5, 130, 130, 19, 19, 19, 105, 19, + 19, 131, 131, 145, 145, 108, 5, 5, 5, 0, 0, 19, 139, 19, 0, 19, 19, 146, + 146, 147, 147, 141, 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 148, 19, 0, 0, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 19, + 148, 23, 20, 21, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 0, 50, 50, + 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 99, 5, 5, 5, 5, 99, 5, 5, 19, 99, 99, 99, 19, 19, 99, 99, 99, 19, 5, + 99, 5, 5, 155, 99, 99, 99, 99, 99, 5, 5, 5, 5, 5, 5, 99, 5, 156, 5, 99, + 5, 157, 158, 99, 99, 155, 19, 99, 99, 159, 99, 19, 50, 50, 50, 50, 19, 5, + 5, 19, 19, 99, 99, 5, 5, 5, 5, 5, 99, 19, 19, 19, 19, 5, 5, 5, 5, 160, 5, + 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 125, 125, 125, 26, 27, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1131,135 +1119,136 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 151, 152, 153, 154, 155, - 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, - 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, - 21, 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 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, 166, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 150, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, - 150, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, + 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, + 151, 152, 153, 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 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, 148, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 148, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, - 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, 20, 21, 151, 152, 153, 154, - 155, 156, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, + 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, 149, 150, 151, 152, 153, + 154, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 26, 27, 167, 168, - 169, 170, 171, 26, 27, 26, 27, 26, 27, 172, 173, 174, 175, 19, 26, 27, - 19, 26, 27, 19, 19, 19, 19, 19, 19, 50, 176, 176, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 19, 5, 5, 5, 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 24, 5, 5, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 26, 27, 165, 166, 167, + 168, 169, 26, 27, 26, 27, 26, 27, 170, 171, 172, 0, 19, 26, 27, 19, 26, + 27, 19, 19, 19, 19, 19, 19, 50, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, + 5, 5, 24, 5, 5, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, + 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 88, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 86, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 127, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 17, 17, 17, 17, 17, 17, 5, 50, - 50, 50, 50, 50, 5, 5, 127, 127, 127, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 125, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, + 125, 125, 125, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, - 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 5, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, + 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 5, 5, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, + 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1268,7 +1257,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1277,91 +1266,89 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 178, 50, 50, 178, 50, 50, 50, 178, 50, 178, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 174, + 50, 50, 174, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 178, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 178, 178, 50, 50, 50, 50, - 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 174, 50, 174, 174, 174, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 178, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 174, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 178, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 174, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1371,196 +1358,176 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, 26, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 19, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, - 19, 19, 26, 27, 26, 27, 179, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, - 5, 5, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, + 26, 27, 175, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 17, 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 17, + 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, + 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, + 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, - 50, 5, 5, 5, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 17, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, - 50, 50, 17, 17, 50, 50, 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, - 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1577,8 +1544,8 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, - 88, 88, 88, 88, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, + 86, 86, 86, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1592,13 +1559,13 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, 88, 5, 5, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 86, 5, 5, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, - 0, 0, 88, 50, 88, 50, 88, 0, 88, 50, 88, 50, 88, 50, 88, 50, 88, 50, 50, + 0, 0, 86, 50, 86, 50, 86, 0, 86, 50, 86, 50, 86, 50, 86, 50, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1614,7 +1581,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 116, 116, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 114, 114, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, @@ -1635,11 +1602,11 @@ static unsigned char index2[] = { 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1655,22 +1622,22 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 127, 50, 50, 50, 50, 50, 50, 50, 50, 127, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 125, 50, 50, 50, 50, 50, 50, 50, 50, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 5, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1682,46 +1649,20 @@ static unsigned char index2[] = { 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, 50, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 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, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, - 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 151, 24, 24, 24, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, - 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, + 24, 24, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, - 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, + 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, - 1, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, + 23, 20, 21, 149, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1729,21 +1670,15 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 157, 157, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 157, 157, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 155, 155, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 155, 155, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1771,119 +1706,96 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, + 0, 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 0, 101, - 101, 0, 0, 101, 0, 0, 101, 101, 0, 0, 101, 101, 101, 101, 0, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, - 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, + 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 0, 99, + 99, 0, 0, 99, 0, 0, 99, 99, 0, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, + 99, 99, 99, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 101, 101, 0, 101, 101, 101, 101, 0, 0, 101, 101, 101, 101, 101, 101, - 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 0, 99, 99, + 99, 99, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 101, 101, 0, 101, 101, 101, 101, 0, 101, 101, 101, 101, 101, - 0, 101, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, + 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 0, 99, + 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, - 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, + 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, + 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, - 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, + 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 19, 0, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 19, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 150, 23, 20, 21, 151, 152, 153, 154, 155, 156, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, - 5, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, - 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1894,32 +1806,32 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1930,32 +1842,26 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1968,13 +1874,13 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 0, 0, + 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 @@ -2009,26 +1915,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2039,8 +1939,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E2: case 0x1D7EC: case 0x1D7F6: - case 0x1F100: - case 0x1F101: #endif return (double) 0.0; case 0x0031: @@ -2050,6 +1948,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C1: case 0x0967: case 0x09E7: + case 0x09F4: case 0x0A67: case 0x0AE7: case 0x0B67: @@ -2070,9 +1969,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1811: case 0x1947: case 0x19D1: - case 0x19DA: - case 0x1A81: - case 0x1A91: case 0x1B51: case 0x1BB1: case 0x1C41: @@ -2098,12 +1994,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2114,13 +2007,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2133,41 +2021,29 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2179,17 +2055,11 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2222,12 +2092,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2245,12 +2111,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2266,10 +2128,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1014D: case 0x10154: case 0x10171: - case 0x1085E: case 0x10A47: - case 0x10B5F: - case 0x10B7F: #endif return (double) 1000.0; case 0x137C: @@ -2279,7 +2138,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1012B: case 0x10155: - case 0x1085F: #endif return (double) 10000.0; case 0x2188: @@ -2357,6 +2215,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C2: case 0x0968: case 0x09E8: + case 0x09F5: case 0x0A68: case 0x0AE8: case 0x0B68: @@ -2377,8 +2236,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1812: case 0x1948: case 0x19D2: - case 0x1A82: - case 0x1A92: case 0x1B52: case 0x1BB2: case 0x1C42: @@ -2406,12 +2263,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2422,12 +2276,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1015E: case 0x103D2: case 0x104A2: - case 0x10859: - case 0x1091A: case 0x10A41: - case 0x10B59: - case 0x10B79: - case 0x10E61: case 0x12400: case 0x12416: case 0x1241F: @@ -2443,14 +2292,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2468,18 +2315,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 @@ -2515,6 +2357,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C3: case 0x0969: case 0x09E9: + case 0x09F6: case 0x0A69: case 0x0AE9: case 0x0B69: @@ -2535,8 +2378,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1813: case 0x1949: case 0x19D3: - case 0x1A83: - case 0x1A93: case 0x1B53: case 0x1BB3: case 0x1C43: @@ -2563,23 +2404,15 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2600,22 +2433,16 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2631,7 +2458,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x10112: case 0x10165: - case 0x10E6B: case 0x1D36B: case 0x20983: #endif @@ -2639,7 +2465,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1011B: case 0x1016B: - case 0x10E74: return (double) 300.0; #endif #ifdef Py_UNICODE_WIDE @@ -2674,6 +2499,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C4: case 0x096A: case 0x09EA: + case 0x09F7: case 0x0A6A: case 0x0AEA: case 0x0B6A: @@ -2692,8 +2518,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1814: case 0x194A: case 0x19D4: - case 0x1A84: - case 0x1A94: case 0x1B54: case 0x1BB4: case 0x1C44: @@ -2717,20 +2541,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2752,7 +2570,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E6: case 0x1D7F0: case 0x1D7FA: - case 0x1F105: case 0x20064: case 0x200E2: case 0x2626D: @@ -2765,7 +2582,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x534C: #ifdef Py_UNICODE_WIDE case 0x10113: - case 0x10E6C: case 0x1D36C: case 0x2098C: case 0x2099C: @@ -2773,7 +2589,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) return (double) 40.0; #ifdef Py_UNICODE_WIDE case 0x1011C: - case 0x10E75: return (double) 400.0; #endif #ifdef Py_UNICODE_WIDE @@ -2826,8 +2641,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1815: case 0x194B: case 0x19D5: - case 0x1A85: - case 0x1A95: case 0x1B55: case 0x1BB5: case 0x1C45: @@ -2851,12 +2664,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2867,7 +2677,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10173: case 0x10321: case 0x104A5: - case 0x10E64: case 0x12403: case 0x1240A: case 0x12410: @@ -2885,7 +2694,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E7: case 0x1D7F1: case 0x1D7FB: - case 0x1F106: case 0x20121: #endif return (double) 5.0; @@ -2914,8 +2722,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10169: case 0x10174: case 0x10323: - case 0x10A7E: - case 0x10E6D: case 0x1D36D: #endif return (double) 50.0; @@ -2931,7 +2737,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1016E: case 0x1016F: case 0x10170: - case 0x10E76: #endif return (double) 500.0; case 0x2181: @@ -2973,8 +2778,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1816: case 0x194C: case 0x19D6: - case 0x1A86: - case 0x1A96: case 0x1B56: case 0x1BB6: case 0x1C46: @@ -2998,19 +2801,15 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3024,20 +2823,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -3072,8 +2868,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1817: case 0x194D: case 0x19D7: - case 0x1A87: - case 0x1A97: case 0x1B57: case 0x1BB7: case 0x1C47: @@ -3097,17 +2891,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3122,7 +2912,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E9: case 0x1D7F3: case 0x1D7FD: - case 0x1F108: case 0x20001: #endif return (double) 7.0; @@ -3133,13 +2922,11 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -3174,8 +2961,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1818: case 0x194E: case 0x19D8: - case 0x1A88: - case 0x1A98: case 0x1B58: case 0x1BB8: case 0x1C48: @@ -3197,17 +2982,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3221,19 +3002,16 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -3268,8 +3046,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1819: case 0x194F: case 0x19D9: - case 0x1A89: - case 0x1A99: case 0x1B59: case 0x1BB9: case 0x1C49: @@ -3292,17 +3068,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3318,7 +3090,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7EB: case 0x1D7F5: case 0x1D7FF: - case 0x1F10A: case 0x2F890: #endif return (double) 9.0; @@ -3328,14 +3099,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 -- cgit v1.2.1 From 03b168d2d52637d68587d9dd3ecb11e9c78d1a83 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 19 Mar 2010 12:38:03 +0000 Subject: Remove out-of-date comment about making ints and longs hash equal. --- Objects/longobject.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index d182e7ce30..781e34f99d 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2560,9 +2560,6 @@ long_hash(PyLongObject *v) Py_ssize_t i; int sign; - /* This is designed so that Python ints and longs with the - same value hash to the same value, otherwise comparisons - of mapping keys will turn out weird */ i = Py_SIZE(v); switch(i) { case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; -- cgit v1.2.1 From ae19416bbf9866f25491e22d98d6baf4d7941739 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Fri, 19 Mar 2010 13:37:08 +0000 Subject: Fixed a failure in test_bigmem. Merged revision 79059 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79059 | florent.xicluna | 2010-03-18 22:50:06 +0100 (jeu, 18 mar 2010) | 2 lines Issue #8024: Update the Unicode database to 5.2 ........ --- Objects/unicodetype_db.h | 2153 +++++++++++++++++++++++++--------------------- 1 file changed, 1192 insertions(+), 961 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 00a43e8014..8c8955cbaa 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -64,11 +64,13 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 10795, 0, 0, 0, 1921}, {0, 65373, 0, 0, 0, 1921}, {0, 10792, 0, 0, 0, 1921}, + {10815, 0, 10815, 0, 0, 1801}, {0, 65341, 0, 0, 0, 1921}, {0, 69, 0, 0, 0, 1921}, {0, 71, 0, 0, 0, 1921}, {10783, 0, 10783, 0, 0, 1801}, {10780, 0, 10780, 0, 0, 1801}, + {10782, 0, 10782, 0, 0, 1801}, {65326, 0, 65326, 0, 0, 1801}, {65330, 0, 65330, 0, 0, 1801}, {65331, 0, 65331, 0, 0, 1801}, @@ -175,6 +177,8 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 54756, 0, 0, 0, 1921}, {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, + {0, 54754, 0, 0, 0, 1921}, + {0, 54721, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, {0, 0, 0, 0, 0, 5889}, {42877, 7545, 42877, 0, 0, 3969}, @@ -185,508 +189,508 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { /* 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, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, - 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 63, 64, 65, 66, 63, - 63, 63, 67, 68, 69, 63, 63, 63, 63, 63, 63, 70, 16, 71, 72, 73, 74, 75, - 76, 63, 77, 78, 79, 80, 81, 82, 83, 63, 63, 84, 85, 40, 40, 40, 40, 40, - 40, 86, 40, 40, 40, 40, 40, 87, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 88, 89, 90, 91, 40, 40, 40, 92, 40, 40, - 40, 93, 94, 40, 40, 40, 40, 40, 95, 40, 40, 40, 96, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 97, 98, 99, 40, 40, 40, 40, 40, 40, 100, 101, 40, 40, - 40, 40, 40, 40, 40, 40, 102, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 40, 40, 104, 40, 40, 40, 40, - 100, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 103, 40, 40, 40, 40, 40, 40, 105, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 106, 107, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 108, 109, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 110, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 111, 40, 40, 112, 113, 114, 115, 116, 117, 118, 16, 119, 16, - 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 120, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 123, 124, 125, - 126, 127, 128, 40, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 16, - 139, 140, 141, 142, 143, 16, 16, 16, 16, 16, 16, 144, 16, 145, 16, 146, - 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, 40, 40, 40, 40, 40, 40, 147, 16, 148, 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, 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, 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, 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, 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, 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, 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, - 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, 63, - 149, 150, 151, 152, 16, 153, 16, 154, 155, 156, 157, 158, 159, 160, 161, - 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, 16, 16, 16, 16, 162, 163, 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, 164, 165, 166, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 86, 167, 40, 168, 169, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 170, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 171, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 172, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 173, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 174, 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, 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, - 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, 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, 40, 170, 40, 40, 175, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 176, 16, - 177, 178, 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, 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, - 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, 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, 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, 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, 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, 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, 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, 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, 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, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 179, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 179, + 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, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, + 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 17, 143, 144, 145, 146, 147, 17, 17, 17, 17, 17, 17, 148, 17, 149, 17, + 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 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, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 155, 17, 156, + 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, 157, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 158, 159, 160, 161, 17, 162, 17, 163, 164, 165, 166, 167, 168, + 169, 170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 171, 172, 173, + 174, 175, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 176, 177, 178, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 179, 34, 180, 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, 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, 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, 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, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 186, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 187, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 182, 34, 34, 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, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 189, 17, 190, 191, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 192, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 192, }; static unsigned char index2[] = { @@ -720,11 +724,11 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 58, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26, - 27, 60, 61, 19, 19, 26, 27, 62, 63, 64, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 65, 66, 19, 67, 68, 19, 69, 69, 19, 70, 19, 71, 19, 19, 19, 19, - 69, 19, 19, 72, 19, 19, 19, 19, 73, 74, 19, 75, 19, 19, 19, 74, 19, 76, - 77, 19, 19, 78, 19, 19, 19, 19, 19, 19, 19, 79, 19, 19, 80, 19, 19, 80, - 19, 19, 19, 19, 80, 81, 82, 82, 83, 19, 19, 19, 19, 19, 84, 19, 50, 19, + 27, 60, 61, 62, 62, 26, 27, 63, 64, 65, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 66, 67, 68, 69, 70, 19, 71, 71, 19, 72, 19, 73, 19, 19, 19, 19, + 71, 19, 19, 74, 19, 19, 19, 19, 75, 76, 19, 77, 19, 19, 19, 76, 19, 78, + 79, 19, 19, 80, 19, 19, 19, 19, 19, 19, 19, 81, 19, 19, 82, 19, 19, 82, + 19, 19, 19, 19, 82, 83, 84, 84, 85, 19, 19, 19, 19, 19, 86, 19, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, @@ -734,40 +738,40 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 85, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 87, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 86, - 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 87, 17, 88, 88, 88, 0, 89, 0, 90, 90, + 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 88, + 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 89, 17, 90, 90, 90, 0, 91, 0, 92, 92, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 91, 92, 92, 92, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 93, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 94, 95, 95, 96, 97, 98, 99, 99, 99, 100, 101, - 102, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 103, 104, 105, 19, 106, 107, 5, 26, 27, 108, - 26, 27, 19, 58, 58, 58, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 93, 94, 94, 94, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 95, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 96, 97, 97, 98, 99, 100, 101, 101, 101, 102, 103, + 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 105, 106, 107, 19, 108, 109, 5, 26, 27, 110, + 26, 27, 19, 58, 58, 58, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 5, 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 110, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 111, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 112, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 50, 5, 5, 5, 5, 5, 5, 0, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0, @@ -800,29 +804,35 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17, 17, + 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 0, 50, 17, 17, 17, 17, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 0, 50, 17, 17, 17, 17, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 5, 24, 5, 0, 0, 0, - 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, - 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, + 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, + 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, + 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, + 0, 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, @@ -872,14 +882,14 @@ static unsigned char index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 114, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 116, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, - 50, 114, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 116, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, @@ -893,7 +903,7 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -903,55 +913,49 @@ static unsigned char index2[] = { 17, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, - 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 116, 117, 118, 119, 120, 121, 122, 123, 124, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 118, 119, 120, 121, 122, 123, 124, 125, 126, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -963,101 +967,106 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 5, 5, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 5, 5, 5, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 7, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 17, 17, 17, 17, 17, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 50, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, + 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, - 0, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 50, 126, 19, 19, 19, 127, 19, 19, 19, 19, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 19, 19, 50, 128, 19, 19, 19, 129, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, @@ -1065,48 +1074,50 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 19, 19, 19, 19, 19, 128, 19, 19, 129, 19, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 130, + 19, 19, 131, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 130, 130, - 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, - 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, - 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, - 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, - 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, 131, - 131, 131, 131, 0, 0, 19, 130, 19, 130, 19, 130, 19, 130, 0, 131, 0, 131, - 0, 131, 0, 131, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, - 131, 131, 131, 131, 131, 132, 132, 133, 133, 133, 133, 134, 134, 135, - 135, 136, 136, 137, 137, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, - 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, 130, 130, - 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 130, 130, - 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, 130, 130, 19, - 139, 19, 0, 19, 19, 131, 131, 140, 140, 141, 5, 142, 5, 5, 5, 19, 139, - 19, 0, 19, 19, 143, 143, 143, 143, 141, 5, 5, 5, 130, 130, 19, 19, 0, 0, - 19, 19, 131, 131, 144, 144, 0, 5, 5, 5, 130, 130, 19, 19, 19, 105, 19, - 19, 131, 131, 145, 145, 108, 5, 5, 5, 0, 0, 19, 139, 19, 0, 19, 19, 146, - 146, 147, 147, 141, 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 148, 19, 0, 0, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 19, - 148, 23, 20, 21, 149, 150, 151, 152, 153, 154, 5, 5, 5, 5, 5, 0, 50, 50, - 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 5, 99, 5, 5, 5, 5, 99, 5, 5, 19, 99, 99, 99, 19, 19, 99, 99, 99, 19, 5, - 99, 5, 5, 155, 99, 99, 99, 99, 99, 5, 5, 5, 5, 5, 5, 99, 5, 156, 5, 99, - 5, 157, 158, 99, 99, 155, 19, 99, 99, 159, 99, 19, 50, 50, 50, 50, 19, 5, - 5, 19, 19, 99, 99, 5, 5, 5, 5, 5, 99, 19, 19, 19, 19, 5, 5, 5, 5, 160, 5, - 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 125, 125, 125, 26, 27, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 132, 132, 132, 132, 132, 132, + 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, + 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, 132, 132, 132, 132, + 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, + 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, + 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, + 19, 132, 19, 132, 19, 132, 19, 132, 0, 133, 0, 133, 0, 133, 0, 133, 132, + 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, + 133, 134, 134, 135, 135, 135, 135, 136, 136, 137, 137, 138, 138, 139, + 139, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, + 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, + 140, 140, 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, + 140, 140, 140, 140, 140, 140, 140, 140, 132, 132, 19, 141, 19, 0, 19, 19, + 133, 133, 142, 142, 143, 5, 144, 5, 5, 5, 19, 141, 19, 0, 19, 19, 145, + 145, 145, 145, 143, 5, 5, 5, 132, 132, 19, 19, 0, 0, 19, 19, 133, 133, + 146, 146, 0, 5, 5, 5, 132, 132, 19, 19, 19, 107, 19, 19, 133, 133, 147, + 147, 110, 5, 5, 5, 0, 0, 19, 141, 19, 0, 19, 19, 148, 148, 149, 149, 143, + 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, + 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 150, 50, 0, 0, + 151, 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 50, 150, 23, 20, 21, 151, + 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 101, 5, 5, 5, 5, + 101, 5, 5, 19, 101, 101, 101, 19, 19, 101, 101, 101, 19, 5, 101, 5, 5, + 157, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 101, 5, 158, 5, 101, 5, + 159, 160, 101, 101, 157, 19, 101, 101, 161, 101, 19, 50, 50, 50, 50, 19, + 5, 5, 19, 19, 101, 101, 5, 5, 5, 5, 5, 101, 19, 19, 19, 19, 5, 5, 5, 5, + 162, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 127, 127, 127, 26, 27, 127, 127, 127, 127, 24, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1120,135 +1131,135 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, - 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 149, 150, - 151, 152, 153, 154, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 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, 148, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 148, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 151, 152, 153, 154, 155, + 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, + 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, + 21, 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 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, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 150, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, + 150, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 23, 20, 21, 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, - 149, 150, 151, 152, 153, 154, 24, 23, 20, 21, 149, 150, 151, 152, 153, - 154, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, + 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, 20, 21, 151, 152, 153, 154, + 155, 156, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 26, 27, 165, 166, 167, - 168, 169, 26, 27, 26, 27, 26, 27, 170, 171, 172, 0, 19, 26, 27, 19, 26, - 27, 19, 19, 19, 19, 19, 19, 50, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 24, 5, 5, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 26, 27, 167, 168, + 169, 170, 171, 26, 27, 26, 27, 26, 27, 172, 173, 174, 175, 19, 26, 27, + 19, 26, 27, 19, 19, 19, 19, 19, 19, 50, 176, 176, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 19, 5, 5, 5, 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 24, 5, 5, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 86, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 88, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 125, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, - 125, 125, 125, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 127, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 17, 17, 17, 17, 17, 17, 5, 50, + 50, 50, 50, 50, 5, 5, 127, 127, 127, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, + 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, - 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 5, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, - 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 5, 5, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1257,7 +1268,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1266,56 +1277,56 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 174, - 50, 50, 174, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 178, 50, 50, 178, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 174, 50, 174, 174, 174, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 178, 178, 50, 50, 50, 50, + 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 178, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 174, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1323,7 +1334,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1331,24 +1342,25 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 178, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 174, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1359,175 +1371,196 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 178, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, + 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 19, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, - 26, 27, 175, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, + 19, 19, 26, 27, 26, 27, 179, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, + 5, 5, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 17, - 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, - 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 17, 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, + 50, 5, 5, 5, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50, - 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 17, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, + 50, 50, 17, 17, 50, 50, 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 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, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 174, - 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, + 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 174, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1544,8 +1577,8 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, - 86, 86, 86, 86, 86, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, + 88, 88, 88, 88, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1559,13 +1592,13 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 86, 86, 5, 5, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, 88, 5, 5, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, - 0, 0, 86, 50, 86, 50, 86, 0, 86, 50, 86, 50, 86, 50, 86, 50, 86, 50, 50, + 0, 0, 88, 50, 88, 50, 88, 0, 88, 50, 88, 50, 88, 50, 88, 50, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1581,7 +1614,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 114, 114, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 116, 116, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, @@ -1602,11 +1635,11 @@ static unsigned char index2[] = { 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1622,22 +1655,22 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 125, 50, 50, 50, 50, 50, 50, 50, 50, 125, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 127, 50, 50, 50, 50, 50, 50, 50, 50, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 5, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1649,20 +1682,46 @@ static unsigned char index2[] = { 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, 50, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 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, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, + 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 151, 24, 24, 24, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, - 24, 24, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, - 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, + 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, - 23, 20, 21, 149, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, + 1, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1670,15 +1729,21 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 155, 155, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 155, 155, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 157, 157, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 157, 157, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1706,96 +1771,119 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 0, 99, - 99, 0, 0, 99, 0, 0, 99, 99, 0, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, - 99, 99, 99, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 0, 101, + 101, 0, 0, 101, 0, 0, 101, 101, 0, 0, 101, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, + 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 0, 99, 99, - 99, 99, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, + 19, 101, 101, 0, 101, 101, 101, 101, 0, 0, 101, 101, 101, 101, 101, 101, + 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 99, 99, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 0, 99, - 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 0, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 101, 101, 0, 101, 101, 101, 101, 0, 101, 101, 101, 101, 101, + 0, 101, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 19, 19, + 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, + 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, - 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, + 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 5, 19, 19, 19, + 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, + 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 99, 19, 0, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 19, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 150, 150, 23, 20, 21, 151, 152, 153, 154, 155, 156, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, + 5, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 174, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, + 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1806,32 +1894,32 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, + 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1842,26 +1930,32 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 174, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 17, 17, 17, 17, 17, 17, 17, + 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1874,13 +1968,13 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -1915,20 +2009,26 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -1939,6 +2039,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E2: case 0x1D7EC: case 0x1D7F6: + case 0x1F100: + case 0x1F101: #endif return (double) 0.0; case 0x0031: @@ -1948,7 +2050,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C1: case 0x0967: case 0x09E7: - case 0x09F4: case 0x0A67: case 0x0AE7: case 0x0B67: @@ -1969,6 +2070,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1811: case 0x1947: case 0x19D1: + case 0x19DA: + case 0x1A81: + case 0x1A91: case 0x1B51: case 0x1BB1: case 0x1C41: @@ -1994,9 +2098,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2007,8 +2114,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2021,29 +2133,41 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2055,11 +2179,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2092,8 +2222,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2111,8 +2245,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2128,7 +2266,10 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1014D: case 0x10154: case 0x10171: + case 0x1085E: case 0x10A47: + case 0x10B5F: + case 0x10B7F: #endif return (double) 1000.0; case 0x137C: @@ -2138,6 +2279,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1012B: case 0x10155: + case 0x1085F: #endif return (double) 10000.0; case 0x2188: @@ -2215,7 +2357,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C2: case 0x0968: case 0x09E8: - case 0x09F5: case 0x0A68: case 0x0AE8: case 0x0B68: @@ -2236,6 +2377,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1812: case 0x1948: case 0x19D2: + case 0x1A82: + case 0x1A92: case 0x1B52: case 0x1BB2: case 0x1C42: @@ -2263,9 +2406,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2276,7 +2422,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1015E: case 0x103D2: case 0x104A2: + case 0x10859: + case 0x1091A: case 0x10A41: + case 0x10B59: + case 0x10B79: + case 0x10E61: case 0x12400: case 0x12416: case 0x1241F: @@ -2292,12 +2443,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2315,13 +2468,18 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 @@ -2357,7 +2515,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C3: case 0x0969: case 0x09E9: - case 0x09F6: case 0x0A69: case 0x0AE9: case 0x0B69: @@ -2378,6 +2535,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1813: case 0x1949: case 0x19D3: + case 0x1A83: + case 0x1A93: case 0x1B53: case 0x1BB3: case 0x1C43: @@ -2404,15 +2563,23 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2433,16 +2600,22 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2458,6 +2631,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x10112: case 0x10165: + case 0x10E6B: case 0x1D36B: case 0x20983: #endif @@ -2465,6 +2639,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #ifdef Py_UNICODE_WIDE case 0x1011B: case 0x1016B: + case 0x10E74: return (double) 300.0; #endif #ifdef Py_UNICODE_WIDE @@ -2499,7 +2674,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x07C4: case 0x096A: case 0x09EA: - case 0x09F7: case 0x0A6A: case 0x0AEA: case 0x0B6A: @@ -2518,6 +2692,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1814: case 0x194A: case 0x19D4: + case 0x1A84: + case 0x1A94: case 0x1B54: case 0x1BB4: case 0x1C44: @@ -2541,14 +2717,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2570,6 +2752,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E6: case 0x1D7F0: case 0x1D7FA: + case 0x1F105: case 0x20064: case 0x200E2: case 0x2626D: @@ -2582,6 +2765,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x534C: #ifdef Py_UNICODE_WIDE case 0x10113: + case 0x10E6C: case 0x1D36C: case 0x2098C: case 0x2099C: @@ -2589,6 +2773,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) return (double) 40.0; #ifdef Py_UNICODE_WIDE case 0x1011C: + case 0x10E75: return (double) 400.0; #endif #ifdef Py_UNICODE_WIDE @@ -2641,6 +2826,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1815: case 0x194B: case 0x19D5: + case 0x1A85: + case 0x1A95: case 0x1B55: case 0x1BB5: case 0x1C45: @@ -2664,9 +2851,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2677,6 +2867,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10173: case 0x10321: case 0x104A5: + case 0x10E64: case 0x12403: case 0x1240A: case 0x12410: @@ -2694,6 +2885,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E7: case 0x1D7F1: case 0x1D7FB: + case 0x1F106: case 0x20121: #endif return (double) 5.0; @@ -2722,6 +2914,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10169: case 0x10174: case 0x10323: + case 0x10A7E: + case 0x10E6D: case 0x1D36D: #endif return (double) 50.0; @@ -2737,6 +2931,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1016E: case 0x1016F: case 0x10170: + case 0x10E76: #endif return (double) 500.0; case 0x2181: @@ -2778,6 +2973,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1816: case 0x194C: case 0x19D6: + case 0x1A86: + case 0x1A96: case 0x1B56: case 0x1BB6: case 0x1C46: @@ -2801,15 +2998,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2823,17 +3024,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2868,6 +3072,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1817: case 0x194D: case 0x19D7: + case 0x1A87: + case 0x1A97: case 0x1B57: case 0x1BB7: case 0x1C47: @@ -2891,13 +3097,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2912,6 +3122,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7E9: case 0x1D7F3: case 0x1D7FD: + case 0x1F108: case 0x20001: #endif return (double) 7.0; @@ -2922,11 +3133,13 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -2961,6 +3174,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1818: case 0x194E: case 0x19D8: + case 0x1A88: + case 0x1A98: case 0x1B58: case 0x1BB8: case 0x1C48: @@ -2982,13 +3197,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3002,16 +3221,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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 @@ -3046,6 +3268,8 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1819: case 0x194F: case 0x19D9: + case 0x1A89: + case 0x1A99: case 0x1B59: case 0x1BB9: case 0x1C49: @@ -3068,13 +3292,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3090,6 +3318,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7EB: case 0x1D7F5: case 0x1D7FF: + case 0x1F10A: case 0x2F890: #endif return (double) 9.0; @@ -3099,12 +3328,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) #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 -- cgit v1.2.1 From eb26a23f84a3f066c596c6d15ab6e3aa018f3104 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 22 Mar 2010 12:50:40 +0000 Subject: Merged revisions 79278,79280 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79278 | victor.stinner | 2010-03-22 13:24:37 +0100 (lun., 22 mars 2010) | 2 lines Issue #1583863: An unicode subclass can now override the __str__ method ........ r79280 | victor.stinner | 2010-03-22 13:36:28 +0100 (lun., 22 mars 2010) | 5 lines Fix the NEWS about my last commit: an unicode subclass can now override the __unicode__ method (and not the __str__ method). Simplify also the testcase. ........ --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 3ee90b58dd..28b8c66295 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9124,7 +9124,7 @@ PyObject *PyUnicode_Format(PyObject *format, case 's': case 'r': case 'a': - if (PyUnicode_Check(v) && c == 's') { + if (PyUnicode_CheckExact(v) && c == 's') { temp = v; Py_INCREF(temp); } -- cgit v1.2.1 From 6f7f79138b7a1b6e3bb499e70449921b05c116d2 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Tue, 30 Mar 2010 19:34:18 +0000 Subject: Merged revisions 79494,79496 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79494 | florent.xicluna | 2010-03-30 10:24:06 +0200 (mar, 30 mar 2010) | 2 lines #7643: Unicode codepoints VT (0x0B) and FF (0x0C) are linebreaks according to Unicode Standard Annex #14. ........ r79496 | florent.xicluna | 2010-03-30 18:29:03 +0200 (mar, 30 mar 2010) | 2 lines Highlight the change of behavior related to r79494. Now VT and FF are linebreaks. ........ --- Objects/unicodeobject.c | 8 +++++--- Objects/unicodetype_db.h | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 28b8c66295..a409b2263b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -126,9 +126,9 @@ static const char unicode_default_encoding[] = "utf-8"; /* Fast detection of the most frequent whitespace characters */ const unsigned char _Py_ascii_whitespace[] = { 0, 0, 0, 0, 0, 0, 0, 0, -/* case 0x0009: * HORIZONTAL TABULATION */ +/* case 0x0009: * CHARACTER TABULATION */ /* case 0x000A: * LINE FEED */ -/* case 0x000B: * VERTICAL TABULATION */ +/* case 0x000B: * LINE TABULATION */ /* case 0x000C: * FORM FEED */ /* case 0x000D: * CARRIAGE RETURN */ 0, 1, 1, 1, 1, 1, 0, 0, @@ -163,8 +163,10 @@ static PyObject *unicode_encode_call_errorhandler(const char *errors, 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, 0, 0, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x001C, * FILE SEPARATOR */ /* 0x001D, * GROUP SEPARATOR */ diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 8c8955cbaa..424a317219 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -694,7 +694,7 @@ static unsigned char index1[] = { }; static unsigned char index2[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, @@ -3395,13 +3395,16 @@ int _PyUnicode_IsWhitespace(register const Py_UNICODE ch) #endif } -/* Returns 1 for Unicode characters having the category 'Zl', - * 'Zp' or type 'B', 0 otherwise. +/* 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: -- cgit v1.2.1 From 25adc5318176b4109a5a38974f4c0ccae36c40da Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 5 Apr 2010 18:09:39 +0000 Subject: Merged revisions 79804 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79804 | mark.dickinson | 2010-04-05 19:07:51 +0100 (Mon, 05 Apr 2010) | 5 lines Use a more robust infinity check in _Py_HashDouble. This fixes a test_decimal failure on FreeBSD 8.0. (modf apparently doesn't follow C99 Annex F on FreeBSD.) ........ --- Objects/object.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index a332c6c85e..0b22e380e7 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -656,15 +656,15 @@ _Py_HashDouble(double v) * of mapping keys will turn out weird. */ + if (Py_IS_INFINITY(v)) + /* can't convert to long int -- arbitrary */ + v = v < 0 ? -271828.0 : 314159.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 */ - if (Py_IS_INFINITY(intpart)) - /* can't convert to long int -- arbitrary */ - v = v < 0 ? -271828.0 : 314159.0; plong = PyLong_FromDouble(v); if (plong == NULL) return -1; -- cgit v1.2.1 From c44f58aaa4b6903231ad4bcea2fcac6a4d42c371 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 6 Apr 2010 10:29:17 +0000 Subject: Merged revisions 79809 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79809 | mark.dickinson | 2010-04-05 19:54:51 +0100 (Mon, 05 Apr 2010) | 1 line Use a better NaN test in _Py_HashDouble as well. ........ --- Objects/object.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 0b22e380e7..4d3d6590cc 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -656,9 +656,12 @@ _Py_HashDouble(double v) * of mapping keys will turn out weird. */ - if (Py_IS_INFINITY(v)) - /* can't convert to long int -- arbitrary */ - v = v < 0 ? -271828.0 : 314159.0; + 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. */ -- cgit v1.2.1 From f882577cd6d2ccad52457a14060e9bc845c042a5 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 6 Apr 2010 16:53:17 +0000 Subject: Merged revisions 79843-79844 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79843 | mark.dickinson | 2010-04-06 17:46:09 +0100 (Tue, 06 Apr 2010) | 4 lines Issue #8259: Get rid of 'outrageous left shift count' error when left-shifting an integer by more than 2**31 on a 64-bit machine. Also convert shift counts to a Py_ssize_t instead of a C long. ........ r79844 | mark.dickinson | 2010-04-06 17:47:55 +0100 (Tue, 06 Apr 2010) | 1 line Misc/NEWS entry for r79843. ........ --- Objects/longobject.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 781e34f99d..93f5611df9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3779,8 +3779,7 @@ static PyObject * long_rshift(PyLongObject *a, PyLongObject *b) { PyLongObject *z = NULL; - long shiftby; - Py_ssize_t newsize, wordshift, loshift, hishift, i, j; + Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j; digit lomask, himask; CHECK_BINOP(a, b); @@ -3799,8 +3798,7 @@ long_rshift(PyLongObject *a, PyLongObject *b) Py_DECREF(a2); } else { - - shiftby = PyLong_AsLong((PyObject *)b); + shiftby = PyLong_AsSsize_t((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) goto rshift_error; if (shiftby < 0) { @@ -3841,27 +3839,21 @@ long_lshift(PyObject *v, PyObject *w) PyLongObject *a = (PyLongObject*)v; PyLongObject *b = (PyLongObject*)w; PyLongObject *z = NULL; - long shiftby; - Py_ssize_t oldsize, newsize, wordshift, remshift, i, j; + Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j; twodigits accum; CHECK_BINOP(a, b); - shiftby = PyLong_AsLong((PyObject *)b); + shiftby = PyLong_AsSsize_t((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) goto lshift_error; if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); goto lshift_error; } - if ((long)(int)shiftby != shiftby) { - PyErr_SetString(PyExc_ValueError, - "outrageous left shift count"); - goto lshift_error; - } /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ - wordshift = (int)shiftby / PyLong_SHIFT; - remshift = (int)shiftby - wordshift * PyLong_SHIFT; + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby - wordshift * PyLong_SHIFT; oldsize = ABS(Py_SIZE(a)); newsize = oldsize + wordshift; -- cgit v1.2.1 From c88bac548f095a6ee8d53e558c1e70d59fba9d7d Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 6 Apr 2010 19:02:54 +0000 Subject: Merged revisions 79856 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79856 | mark.dickinson | 2010-04-06 19:58:54 +0100 (Tue, 06 Apr 2010) | 1 line Silence a 'comparison between signed and unsigned integer expressions' gcc warning. ........ --- Objects/longobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 93f5611df9..2b5328d27a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2428,7 +2428,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) break; } } - assert(1 <= x_size && x_size <= sizeof(x_digits)/sizeof(digit)); + assert(1 <= x_size && x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit))); /* Round, and convert to double. */ x_digits[0] += half_even_correction[x_digits[0] & 7]; -- cgit v1.2.1 From 706c6d030cbb50be11d1665ee0e07bed00a7f761 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Wed, 7 Apr 2010 08:49:55 +0000 Subject: Merged revisions 79885 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r79885 | stefan.krah | 2010-04-07 10:24:44 +0200 (Wed, 07 Apr 2010) | 1 line Issue #8328: Silence Visual Studio warnings. ........ --- Objects/longobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 2b5328d27a..13e9721f36 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1111,7 +1111,7 @@ PyLong_FromSize_t(size_t ival) int ndigits = 0; if (ival < PyLong_BASE) - return PyLong_FromLong(ival); + return PyLong_FromLong((long)ival); /* Count the number of Python digits. */ t = ival; while (t) { @@ -2405,7 +2405,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) while (x_size < shift_digits) x_digits[x_size++] = 0; rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, - shift_bits); + (int)shift_bits); x_size += a_size; x_digits[x_size++] = rem; } @@ -2413,7 +2413,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; rem = v_rshift(x_digits, a->ob_digit + shift_digits, - a_size - shift_digits, shift_bits); + a_size - shift_digits, (int)shift_bits); x_size = a_size - shift_digits; /* For correct rounding below, we need the least significant bit of x to be 'sticky' for this shift: if any of the bits @@ -2475,7 +2475,7 @@ PyLong_AsDouble(PyObject *v) "long int too large to convert to float"); return -1.0; } - return ldexp(x, exponent); + return ldexp(x, (int)exponent); } /* Methods */ @@ -3492,9 +3492,9 @@ long_true_divide(PyObject *v, PyObject *w) /* Check whether ldexp result will overflow a double. */ if (shift + x_bits >= DBL_MAX_EXP && - (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, x_bits))) + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits))) goto overflow; - result = ldexp(dx, shift); + result = ldexp(dx, (int)shift); success: return PyFloat_FromDouble(negate ? -result : result); @@ -4362,7 +4362,7 @@ long_bit_length(PyLongObject *v) Py_DECREF(result); result = y; - x = (PyLongObject *)PyLong_FromLong(msd_bits); + x = (PyLongObject *)PyLong_FromLong((long)msd_bits); if (x == NULL) goto error; y = (PyLongObject *)long_add(result, x); -- cgit v1.2.1 From d5942f9a685f76792caabddd39bc7554a0ce0f10 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 16 Apr 2010 22:51:37 +0000 Subject: Merged revisions 80126 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r80126 | benjamin.peterson | 2010-04-16 17:35:38 -0500 (Fri, 16 Apr 2010) | 1 line have a clear error when passing something > sys.maxsize to bytearray ........ --- Objects/bytearrayobject.c | 18 +++++++++++------- Objects/bytesobject.c | 12 +++++++----- 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 8f833d8efd..4d32ea70f3 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -753,14 +753,18 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) } /* Is it an int? */ - count = PyNumber_AsSsize_t(arg, PyExc_ValueError); - if (count == -1 && PyErr_Occurred()) - PyErr_Clear(); - else { - if (count < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); + count = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (count == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) return -1; - } + else + 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; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 890d0447df..a05bf03d56 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2545,15 +2545,17 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return new; } /* Is it an integer? */ - size = PyNumber_AsSsize_t(x, PyExc_ValueError); + size = PyNumber_AsSsize_t(x, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; PyErr_Clear(); } + else if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } else { - if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } new = PyBytes_FromStringAndSize(NULL, size); if (new == NULL) { return NULL; -- cgit v1.2.1 From 536990faff3f1e1e2e0a70df04ad9a847e598fa2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 16 Apr 2010 23:00:53 +0000 Subject: Merged revisions 80129 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r80129 | benjamin.peterson | 2010-04-16 17:52:44 -0500 (Fri, 16 Apr 2010) | 1 line tiny simplification ........ --- Objects/bytearrayobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 4d32ea70f3..165ccae9f4 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -757,8 +757,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) if (count == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) return -1; - else - PyErr_Clear(); + PyErr_Clear(); } else if (count < 0) { PyErr_SetString(PyExc_ValueError, "negative count"); -- cgit v1.2.1 From 406b18d8d4789192c40a402492aa09041063bd2a Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 18 Apr 2010 20:26:14 +0000 Subject: Issue 8420: Fix ref counting problem in set_repr(). --- Objects/setobject.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index c3eabf536b..944744183c 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -601,10 +601,8 @@ set_repr(PySetObject *so) listrepr = PyObject_Repr(keys); Py_DECREF(keys); - if (listrepr == NULL) { - Py_DECREF(keys); + if (listrepr == NULL) goto done; - } newsize = PyUnicode_GET_SIZE(listrepr); result = PyUnicode_FromUnicode(NULL, newsize); if (result) { -- cgit v1.2.1 From 8bf1f271e6766fb129dba3f6c43d89a79e8f4da5 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 18 Apr 2010 23:05:22 +0000 Subject: Issue 8436: set.__init__ accepts keyword args --- Objects/setobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 944744183c..aaa483878e 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1978,6 +1978,8 @@ set_init(PySetObject *self, PyObject *args, PyObject *kwds) 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); -- cgit v1.2.1 From f1ec829ee06a4cda6212c36406850b9e06704368 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Apr 2010 12:08:36 +0000 Subject: Issue #8485: PyUnicode_FSConverter() doesn't accept bytearray object anymore, you have to convert your bytearray filenames to bytes --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a409b2263b..6b04afc0aa 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1624,7 +1624,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) Py_DECREF(*(PyObject**)addr); return 1; } - if (PyBytes_Check(arg) || PyByteArray_Check(arg)) { + if (PyBytes_Check(arg)) { output = arg; Py_INCREF(output); } -- cgit v1.2.1 From 06d08e865fb70c27a69247afb8d1e8ecda74b8d1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Apr 2010 19:38:16 +0000 Subject: Issue #8092: Fix PyUnicode_EncodeUTF8() to support error handler producing unicode string (eg. backslashreplace) --- Objects/unicodeobject.c | 127 ++++++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 47 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6b04afc0aa..e5c0751f7b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -159,6 +159,12 @@ static PyObject *unicode_encode_call_errorhandler(const char *errors, const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject, Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos); +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); + /* Same for linebreaks */ static unsigned char ascii_linebreak[] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -2542,61 +2548,88 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s, /* Encode Latin-1 */ *p++ = (char)(0xc0 | (ch >> 6)); *p++ = (char)(0x80 | (ch & 0x3f)); - } - else { - /* Encode UCS2 Unicode ordinals */ - if (ch < 0x10000) { + } else if (0xD800 <= ch && ch <= 0xDFFF) { #ifndef Py_UNICODE_WIDE - /* 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 */ - } + /* Special case: check for high and low surrogate */ + if (ch <= 0xDBFF && i != size && 0xDC00 <= s[i] && s[i] <= 0xDFFF) { + Py_UCS4 ch2 = s[i]; + /* Combine the two surrogates to form a UCS4 value */ + ch = ((ch - 0xD800) << 10 | (ch2 - 0xDC00)) + 0x10000; + i++; + + /* 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)); + #endif - if (ch >= 0xd800 && ch <= 0xdfff) { - Py_ssize_t newpos; - PyObject *rep; - char *prep; - int k; - rep = unicode_encode_call_errorhandler - (errors, &errorHandler, "utf-8", "surrogates not allowed", - s, size, &exc, i-1, i, &newpos); - if (!rep) - goto error; - /* Implementation limitations: only support error handler that return - bytes, and only support up to four replacement bytes. */ - if (!PyBytes_Check(rep)) { - PyErr_SetString(PyExc_TypeError, "error handler should have returned bytes"); - Py_DECREF(rep); + } else { + Py_ssize_t newpos; + PyObject *rep; + Py_ssize_t repsize, k; + rep = unicode_encode_call_errorhandler + (errors, &errorHandler, "utf-8", "surrogates not allowed", + s, size, &exc, i-1, i, &newpos); + if (!rep) + goto error; + + if (PyBytes_Check(rep)) + repsize = PyBytes_GET_SIZE(rep); + else + repsize = PyUnicode_GET_SIZE(rep); + + if (repsize > 4) { + Py_ssize_t offset; + + if (result == NULL) + offset = p - stackbuf; + else + offset = p - PyBytes_AS_STRING(result); + + if (nallocated > PY_SSIZE_T_MAX - repsize + 4) { + /* integer overflow */ + PyErr_NoMemory(); goto error; } - if (PyBytes_Size(rep) > 4) { - PyErr_SetString(PyExc_TypeError, "error handler returned too many bytes"); - Py_DECREF(rep); - goto error; + nallocated += repsize - 4; + if (result != NULL) { + if (_PyBytes_Resize(&result, nallocated) < 0) + goto error; + } else { + result = PyBytes_FromStringAndSize(NULL, nallocated); + if (result == NULL) + goto error; + Py_MEMCPY(PyBytes_AS_STRING(result), stackbuf, offset); } - prep = PyBytes_AsString(rep); - for(k = PyBytes_Size(rep); k > 0; k--) + p = PyBytes_AS_STRING(result) + offset; + } + + if (PyBytes_Check(rep)) { + char *prep = PyBytes_AS_STRING(rep); + for(k = repsize; k > 0; k--) *p++ = *prep++; - Py_DECREF(rep); - continue; - + } else /* rep is unicode */ { + Py_UNICODE *prep = PyUnicode_AS_UNICODE(rep); + Py_UNICODE c; + + for(k=0; k> 12)); - *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); - *p++ = (char)(0x80 | (ch & 0x3f)); - continue; + Py_DECREF(rep); } -#ifndef Py_UNICODE_WIDE - encodeUCS4: -#endif + } else if (ch < 0x10000) { + *p++ = (char)(0xe0 | (ch >> 12)); + *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); + *p++ = (char)(0x80 | (ch & 0x3f)); + } else /* ch >= 0x10000 */ { /* Encode UCS4 Unicode ordinals */ *p++ = (char)(0xf0 | (ch >> 18)); *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); -- cgit v1.2.1 From f6fddde5515b6bf7e504b245d982cda0eb0a7666 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 22 Apr 2010 20:01:57 +0000 Subject: Fix my previous commit (r80382) for wide build (unicodeobject.c) --- Objects/unicodeobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e5c0751f7b..ae401a6b62 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2562,9 +2562,8 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s, *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *p++ = (char)(0x80 | (ch & 0x3f)); - -#endif } else { +#endif Py_ssize_t newpos; PyObject *rep; Py_ssize_t repsize, k; @@ -2624,7 +2623,9 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s, } } Py_DECREF(rep); +#ifndef Py_UNICODE_WIDE } +#endif } else if (ch < 0x10000) { *p++ = (char)(0xe0 | (ch >> 12)); *p++ = (char)(0x80 | ((ch >> 6) & 0x3f)); -- cgit v1.2.1 From bb5f3669f8ead9897f824bf97375348d120eb008 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 24 Apr 2010 18:21:17 +0000 Subject: prevent the dict constructor from accepting non-string keyword args #8419 This adds PyArg_ValidateKeywordArguments, which checks that keyword arguments are all strings, using an optimized method if possible. --- Objects/dictobject.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1d36e1d4dc..5433ff743b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -458,6 +458,21 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash) return 0; } +int +_PyDict_HasOnlyStringKeys(PyObject *dict) +{ + Py_ssize_t pos = 0; + PyObject *key, *value; + assert(PyDict_CheckExact(dict)); + /* Shortcut */ + if (((PyDictObject *)dict)->ma_lookup == lookdict_unicode) + return 1; + while (PyDict_Next(dict, &pos, &key, &value)) + if (!PyUnicode_Check(key)) + return 0; + return 1; +} + #ifdef SHOW_TRACK_COUNT #define INCREASE_TRACK_COUNT \ (count_tracked++, count_untracked--); @@ -1386,8 +1401,12 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methnam else result = PyDict_MergeFromSeq2(self, arg, 1); } - if (result == 0 && kwds != NULL) - result = PyDict_Merge(self, kwds, 1); + if (result == 0 && kwds != NULL) { + if (PyArg_ValidateKeywordArguments(kwds)) + result = PyDict_Merge(self, kwds, 1); + else + result = -1; + } return result; } -- cgit v1.2.1 From e3f7dba3cfd863bc52cfa05e24b46184ae72815c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 25 Apr 2010 21:54:00 +0000 Subject: condense condition --- Objects/unicodeobject.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ae401a6b62..3851008a88 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6784,10 +6784,7 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) return ((int)id[i] < (int)str[i]) ? -1 : 1; /* This check keeps Python strings that end in '\0' from comparing equal to C strings identical up to that point. */ - if (PyUnicode_GET_SIZE(uni) != i) - /* We'll say the Python string is longer. */ - return 1; - if (id[i]) + if (PyUnicode_GET_SIZE(uni) != i || id[i]) return 1; /* uni is longer */ if (str[i]) return -1; /* str is longer */ -- cgit v1.2.1 From 392c0fce4d06a3b39df1c3d5ac3d8c0a61ba98f9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 28 Apr 2010 17:26:19 +0000 Subject: Don't decode/recode the unicode filename in SyntaxError_str() * Rewrite my_basename() to use unicode * Use '%U' format --- Objects/exceptions.c | 54 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index b432d6bab2..64e21418bb 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -959,20 +959,27 @@ SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *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; +static PyObject* +my_basename(PyObject *name) +{ + Py_UNICODE *unicode; + Py_ssize_t i, size, offset; + + unicode = PyUnicode_AS_UNICODE(name); + size = PyUnicode_GET_SIZE(name); + offset = 0; + for(i=0; i < size; i++) { + if (unicode[i] == SEP) + offset = i + 1; + } + if (offset != 0) { + return PyUnicode_FromUnicode( + PyUnicode_AS_UNICODE(name) + offset, + size - offset); + } else { + Py_INCREF(name); + return name; } - return result; } @@ -980,7 +987,8 @@ static PyObject * SyntaxError_str(PySyntaxErrorObject *self) { int have_lineno = 0; - char *filename = 0; + PyObject *filename; + PyObject *result; /* Below, we always ignore overflow errors, just printing -1. Still, we cannot allow an OverflowError to be raised, so we need to call PyLong_AsLongAndOverflow. */ @@ -990,7 +998,11 @@ SyntaxError_str(PySyntaxErrorObject *self) lineno here */ if (self->filename && PyUnicode_Check(self->filename)) { - filename = _PyUnicode_AsString(self->filename); + filename = my_basename(self->filename); + if (filename == NULL) + return NULL; + } else { + filename = NULL; } have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno); @@ -998,18 +1010,20 @@ SyntaxError_str(PySyntaxErrorObject *self) return PyObject_Str(self->msg ? self->msg : Py_None); if (filename && have_lineno) - return PyUnicode_FromFormat("%S (%s, line %ld)", + result = PyUnicode_FromFormat("%S (%U, line %ld)", self->msg ? self->msg : Py_None, - my_basename(filename), + filename, PyLong_AsLongAndOverflow(self->lineno, &overflow)); else if (filename) - return PyUnicode_FromFormat("%S (%s)", + result = PyUnicode_FromFormat("%S (%U)", self->msg ? self->msg : Py_None, - my_basename(filename)); + filename); else /* only have_lineno */ - return PyUnicode_FromFormat("%S (line %ld)", + result = PyUnicode_FromFormat("%S (line %ld)", self->msg ? self->msg : Py_None, PyLong_AsLongAndOverflow(self->lineno, &overflow)); + Py_XDECREF(filename); + return result; } static PyMemberDef SyntaxError_members[] = { -- cgit v1.2.1 From ac0af911cf4e10fe26faa2d45b6c097f4ca47174 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Apr 2010 00:22:08 +0000 Subject: Simplify PyUnicode_FSConverter(): remove reference to PyByteArray PyByteArray is no more supported --- Objects/unicodeobject.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 3851008a88..369306e368 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1638,7 +1638,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) arg = PyUnicode_FromObject(arg); if (!arg) return 0; - output = PyUnicode_AsEncodedObject(arg, + output = PyUnicode_AsEncodedObject(arg, Py_FileSystemDefaultEncoding, "surrogateescape"); Py_DECREF(arg); @@ -1650,14 +1650,8 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) return 0; } } - if (PyBytes_Check(output)) { - size = PyBytes_GET_SIZE(output); - data = PyBytes_AS_STRING(output); - } - else { - size = PyByteArray_GET_SIZE(output); - data = PyByteArray_AS_STRING(output); - } + size = PyBytes_GET_SIZE(output); + data = PyBytes_AS_STRING(output); if (size != strlen(data)) { PyErr_SetString(PyExc_TypeError, "embedded NUL character"); Py_DECREF(output); -- cgit v1.2.1 From 6b2ed38f5c13a048426f07f9862fceaa904c79b6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Apr 2010 16:37:52 +0000 Subject: PyUnicode_DecodeFSDefaultAndSize() uses surrogateescape error handler This function is only used to decode Python module filenames, but Python doesn't support surrogates in modules filenames yet. So nobody noticed this minor bug. --- Objects/unicodeobject.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 369306e368..23b322f304 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1600,19 +1600,19 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, "replace"); + return PyUnicode_DecodeMBCS(s, size, "surrogateescape"); } #elif defined(__APPLE__) if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { - return PyUnicode_DecodeUTF8(s, size, "replace"); + return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); } #endif return PyUnicode_Decode(s, size, Py_FileSystemDefaultEncoding, - "replace"); + "surrogateescape"); } else { - return PyUnicode_DecodeUTF8(s, size, "replace"); + return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); } } -- cgit v1.2.1 From b7497e0f69fc0cbd497f8ca90f0dd7fdfdfcebbe Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Apr 2010 16:48:45 +0000 Subject: PyFile_FromFd() uses PyUnicode_DecodeFSDefault() instead of PyUnicode_FromString() to support surrogates in the filename and use the right encoding --- Objects/fileobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 85e87d701f..bbed57bc1b 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -41,7 +41,7 @@ PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, if (stream == NULL) return NULL; if (name != NULL) { - nameobj = PyUnicode_FromString(name); + nameobj = PyUnicode_DecodeFSDefault(name); if (nameobj == NULL) PyErr_Clear(); else { -- cgit v1.2.1 From 8cc1fda6b8c2d74a3abd2b8a007880656add8997 Mon Sep 17 00:00:00 2001 From: Jeffrey Yasskin Date: Mon, 3 May 2010 19:29:34 +0000 Subject: Make (most of) Python's tests pass under Thread Sanitizer. http://code.google.com/p/data-race-test/wiki/ThreadSanitizer is a dynamic data race detector that runs on top of valgrind. With this patch, the binaries at http://code.google.com/p/data-race-test/wiki/ThreadSanitizer#Binaries pass many but not all of the Python tests. All of regrtest still passes outside of tsan. I've implemented part of the C1x atomic types so that we can explicitly mark variables that are used across threads, and get defined behavior as compilers advance. I've added tsan's client header and implementation to the codebase in dynamic_annotations.{h,c} (docs at http://code.google.com/p/data-race-test/wiki/DynamicAnnotations). Unfortunately, I haven't been able to get helgrind and drd to give sensible error messages, even when I use their client annotations, so I'm not supporting them. --- Objects/dictobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 5433ff743b..2eddc8648e 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -734,7 +734,8 @@ PyDict_GetItem(PyObject *op, PyObject *key) 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; + tstate = (PyThreadState*)_Py_atomic_load_relaxed( + &_PyThreadState_Current); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb; -- cgit v1.2.1 From 257bd4447c4fe98e1d26deaf6b7d7cf031603955 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 May 2010 00:41:18 +0000 Subject: code_repr(): use %U to format the filename Avoid useless unicode decoding/recoding of the filename. --- Objects/codeobject.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 3e71e4cde3..ad2068bb2a 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -340,16 +340,20 @@ code_dealloc(PyCodeObject *co) static PyObject * code_repr(PyCodeObject *co) { - int lineno = -1; - char *filename = "???"; - + int lineno; if (co->co_firstlineno != 0) lineno = co->co_firstlineno; - if (co->co_filename && PyUnicode_Check(co->co_filename)) - filename = _PyUnicode_AsString(co->co_filename); - return PyUnicode_FromFormat( - "", - co->co_name, co, filename, lineno); + else + lineno = -1; + if (co->co_filename && PyUnicode_Check(co->co_filename)) { + return PyUnicode_FromFormat( + "", + co->co_name, co, co->co_filename, lineno); + } else { + return PyUnicode_FromFormat( + "", + co->co_name, co, lineno); + } } static PyObject * -- cgit v1.2.1 From a239fb82c76e68f7147eb81fb8eeb77b7765753b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 May 2010 00:50:12 +0000 Subject: module_repr(): use %U to format the file name Avoid useless encode/decode of the filename --- Objects/moduleobject.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index c1dd228abf..feac861b5c 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -191,8 +191,8 @@ PyModule_GetName(PyObject *m) return _PyUnicode_AsString(nameobj); } -const char * -PyModule_GetFilename(PyObject *m) +static PyObject* +module_getfilename(PyObject *m) { PyObject *d; PyObject *fileobj; @@ -208,6 +208,16 @@ PyModule_GetFilename(PyObject *m) PyErr_SetString(PyExc_SystemError, "module filename missing"); return NULL; } + return fileobj; +} + +const char * +PyModule_GetFilename(PyObject *m) +{ + PyObject *fileobj; + fileobj = module_getfilename(m); + if (fileobj == NULL) + return NULL; return _PyUnicode_AsString(fileobj); } @@ -327,19 +337,19 @@ static PyObject * module_repr(PyModuleObject *m) { const char *name; - const char *filename; + PyObject *filename; name = PyModule_GetName((PyObject *)m); if (name == NULL) { PyErr_Clear(); name = "?"; } - filename = PyModule_GetFilename((PyObject *)m); + filename = module_getfilename((PyObject *)m); if (filename == NULL) { PyErr_Clear(); return PyUnicode_FromFormat("", name); } - return PyUnicode_FromFormat("", name, filename); + return PyUnicode_FromFormat("", name, filename); } static int -- cgit v1.2.1 From b19b28c5263a3244bd0e871cd85dec9ac522095e Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 8 May 2010 08:03:09 +0000 Subject: Merged revisions 80961 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r80961 | mark.dickinson | 2010-05-08 09:01:19 +0100 (Sat, 08 May 2010) | 2 lines Issue #8659: Remove redundant ABS calls. Thanks Daniel Stutzbach. ........ --- Objects/longobject.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 13e9721f36..2229aed2f3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2492,10 +2492,7 @@ long_compare(PyLongObject *a, PyLongObject *b) Py_ssize_t sign; if (Py_SIZE(a) != Py_SIZE(b)) { - if (ABS(Py_SIZE(a)) == 0 && ABS(Py_SIZE(b)) == 0) - sign = 0; - else - sign = Py_SIZE(a) - Py_SIZE(b); + sign = Py_SIZE(a) - Py_SIZE(b); } else { Py_ssize_t i = ABS(Py_SIZE(a)); @@ -3772,7 +3769,7 @@ long_abs(PyLongObject *v) static int long_bool(PyLongObject *v) { - return ABS(Py_SIZE(v)) != 0; + return Py_SIZE(v) != 0; } static PyObject * -- cgit v1.2.1 From 567b94adaaceb622c33f9be1998735dfb95f1707 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 May 2010 15:52:27 +0000 Subject: Recorded merge of revisions 81029 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........ --- Objects/abstract.c | 3810 +++++++-------- Objects/boolobject.c | 226 +- Objects/bytes_methods.c | 314 +- Objects/bytesobject.c | 4652 +++++++++--------- Objects/cellobject.c | 240 +- Objects/classobject.c | 888 ++-- Objects/codeobject.c | 906 ++-- Objects/complexobject.c | 1612 +++---- Objects/descrobject.c | 1866 ++++---- Objects/dictobject.c | 4100 ++++++++-------- Objects/enumobject.c | 566 +-- Objects/exceptions.c | 44 +- Objects/fileobject.c | 744 +-- Objects/floatobject.c | 3800 +++++++-------- Objects/frameobject.c | 1436 +++--- Objects/funcobject.c | 1324 +++--- Objects/genobject.c | 596 +-- Objects/iterobject.c | 328 +- Objects/listobject.c | 4234 ++++++++--------- Objects/longobject.c | 7490 ++++++++++++++--------------- Objects/methodobject.c | 396 +- Objects/moduleobject.c | 642 +-- Objects/object.c | 2452 +++++----- Objects/obmalloc.c | 2146 ++++----- Objects/rangeobject.c | 254 +- Objects/setobject.c | 3606 +++++++------- Objects/sliceobject.c | 518 +- Objects/stringlib/eq.h | 22 +- Objects/stringlib/string_format.h | 174 +- Objects/structseq.c | 822 ++-- Objects/tupleobject.c | 1472 +++--- Objects/typeobject.c | 9524 ++++++++++++++++++------------------- Objects/weakrefobject.c | 116 +- 33 files changed, 30660 insertions(+), 30660 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index cd5a9fd299..5a904b44d1 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -12,17 +12,17 @@ static PyObject * type_error(const char *msg, PyObject *obj) { - PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name); - return NULL; + 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; + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_SystemError, + "null argument to internal routine"); + return NULL; } /* Operations on any object */ @@ -30,37 +30,37 @@ null_error(void) PyObject * PyObject_Type(PyObject *o) { - PyObject *v; + PyObject *v; - if (o == NULL) - return null_error(); - v = (PyObject *)o->ob_type; - Py_INCREF(v); - return 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; + PySequenceMethods *m; - if (o == NULL) { - null_error(); - return -1; - } + if (o == NULL) { + null_error(); + return -1; + } - m = o->ob_type->tp_as_sequence; - if (m && m->sq_length) - return m->sq_length(o); + m = o->ob_type->tp_as_sequence; + if (m && m->sq_length) + return m->sq_length(o); - return PyMapping_Size(o); + return PyMapping_Size(o); } #undef PyObject_Length Py_ssize_t PyObject_Length(PyObject *o) { - return PyObject_Size(o); + return PyObject_Size(o); } #define PyObject_Length PyObject_Size @@ -74,149 +74,149 @@ PyObject_Length(PyObject *o) 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)) - return -1; - PyErr_Clear(); - } - - /* 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)) - return -1; - PyErr_Clear(); - return defaultvalue; - } - rv = PyLong_Check(ro) ? PyLong_AsSsize_t(ro) : defaultvalue; - Py_DECREF(ro); - return rv; + 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)) + return -1; + PyErr_Clear(); + } + + /* 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)) + return -1; + PyErr_Clear(); + return defaultvalue; + } + rv = PyLong_Check(ro) ? PyLong_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); - } + 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 is not subscriptable", o); + return type_error("'%.200s' object is not subscriptable", 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; + 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; + 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; + PyObject *okey; + int ret; - if (o == NULL || key == NULL) { - null_error(); - return -1; - } - okey = PyUnicode_FromString(key); - if (okey == NULL) - return -1; - ret = PyObject_DelItem(o, okey); - Py_DECREF(okey); - return ret; + if (o == NULL || key == NULL) { + null_error(); + return -1; + } + okey = PyUnicode_FromString(key); + if (okey == NULL) + return -1; + ret = PyObject_DelItem(o, okey); + Py_DECREF(okey); + return ret; } /* We release the buffer right after use of this function which could @@ -224,104 +224,104 @@ PyObject_DelItemString(PyObject *o, char *key) */ int PyObject_AsCharBuffer(PyObject *obj, - const char **buffer, - Py_ssize_t *buffer_len) -{ - PyBufferProcs *pb; - Py_buffer view; - - if (obj == NULL || buffer == NULL || buffer_len == NULL) { - null_error(); - return -1; - } - pb = obj->ob_type->tp_as_buffer; - if (pb == NULL || pb->bf_getbuffer == NULL) { - PyErr_SetString(PyExc_TypeError, - "expected an object with the buffer interface"); - return -1; - } - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; - - *buffer = view.buf; - *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); - return 0; + const char **buffer, + Py_ssize_t *buffer_len) +{ + PyBufferProcs *pb; + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (pb == NULL || pb->bf_getbuffer == NULL) { + PyErr_SetString(PyExc_TypeError, + "expected an object with the buffer interface"); + return -1; + } + if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; + + *buffer = view.buf; + *buffer_len = view.len; + if (pb->bf_releasebuffer != NULL) + (*pb->bf_releasebuffer)(obj, &view); + Py_XDECREF(view.obj); + return 0; } int PyObject_CheckReadBuffer(PyObject *obj) { - PyBufferProcs *pb = obj->ob_type->tp_as_buffer; - Py_buffer view; + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + Py_buffer view; - if (pb == NULL || - pb->bf_getbuffer == NULL) - return 0; - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { - PyErr_Clear(); - return 0; - } - PyBuffer_Release(&view); - return 1; + if (pb == NULL || + pb->bf_getbuffer == NULL) + return 0; + if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { + PyErr_Clear(); + return 0; + } + PyBuffer_Release(&view); + return 1; } int PyObject_AsReadBuffer(PyObject *obj, - const void **buffer, - Py_ssize_t *buffer_len) -{ - PyBufferProcs *pb; - Py_buffer view; - - if (obj == NULL || buffer == NULL || buffer_len == NULL) { - null_error(); - return -1; - } - pb = obj->ob_type->tp_as_buffer; - if (pb == NULL || - pb->bf_getbuffer == NULL) { - PyErr_SetString(PyExc_TypeError, - "expected an object with a buffer interface"); - return -1; - } - - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; - - *buffer = view.buf; - *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); - return 0; + const void **buffer, + Py_ssize_t *buffer_len) +{ + PyBufferProcs *pb; + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (pb == NULL || + pb->bf_getbuffer == NULL) { + PyErr_SetString(PyExc_TypeError, + "expected an object with a buffer interface"); + return -1; + } + + if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; + + *buffer = view.buf; + *buffer_len = view.len; + if (pb->bf_releasebuffer != NULL) + (*pb->bf_releasebuffer)(obj, &view); + Py_XDECREF(view.obj); + return 0; } int PyObject_AsWriteBuffer(PyObject *obj, - void **buffer, - Py_ssize_t *buffer_len) -{ - PyBufferProcs *pb; - Py_buffer view; - - if (obj == NULL || buffer == NULL || buffer_len == NULL) { - null_error(); - return -1; - } - pb = obj->ob_type->tp_as_buffer; - if (pb == NULL || - pb->bf_getbuffer == NULL || - ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { - PyErr_SetString(PyExc_TypeError, - "expected an object with a writable buffer interface"); - return -1; - } - - *buffer = view.buf; - *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); - return 0; + void **buffer, + Py_ssize_t *buffer_len) +{ + PyBufferProcs *pb; + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = obj->ob_type->tp_as_buffer; + if (pb == NULL || + pb->bf_getbuffer == NULL || + ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { + PyErr_SetString(PyExc_TypeError, + "expected an object with a writable buffer interface"); + return -1; + } + + *buffer = view.buf; + *buffer_len = view.len; + if (pb->bf_releasebuffer != NULL) + (*pb->bf_releasebuffer)(obj, &view); + Py_XDECREF(view.obj); + return 0; } /* Buffer C-API for Python 3.0 */ @@ -329,119 +329,119 @@ int PyObject_AsWriteBuffer(PyObject *obj, int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (!PyObject_CheckBuffer(obj)) { - PyErr_Format(PyExc_TypeError, - "'%100s' does not support the buffer interface", - Py_TYPE(obj)->tp_name); - return -1; - } - return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); + if (!PyObject_CheckBuffer(obj)) { + PyErr_Format(PyExc_TypeError, + "'%100s' does not support 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; + Py_ssize_t sd, dim; + int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return (view->ndim == 1); + 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; indim; i++) { - dim = view->shape[i]; - if (dim == 0) return 1; - if (view->strides[i] != sd) return 0; - sd *= dim; - } - return 1; + sd = view->itemsize; + if (view->ndim == 1) return (view->shape[0] == 1 || + sd == view->strides[0]); + for (i=0; indim; 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; + Py_ssize_t sd, dim; + int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return 1; + 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; + 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 (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; + 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; + 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 _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape) { - int k; + int k; - for (k=0; k=0; k--) { - if (index[k] < shape[k]-1) { - index[k]++; - break; - } - else { - index[k] = 0; - } - } + 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 @@ -452,242 +452,242 @@ _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape) int PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort) { - int k; - void (*addone)(int, Py_ssize_t *, 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 */ - - /* XXX(nnorwitz): need to check for overflow! */ - indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); - if (indices == NULL) { - PyErr_NoMemory(); - return -1; - } - for (k=0; kndim;k++) { - indices[k] = 0; - } - - if (fort == 'F') { - addone = _add_one_to_index_F; - } - else { - addone = _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--) { - addone(view->ndim, indices, view->shape); - ptr = PyBuffer_GetPointer(view, indices); - memcpy(dest, ptr, view->itemsize); - dest += view->itemsize; - } - PyMem_Free(indices); - return 0; + int k; + void (*addone)(int, Py_ssize_t *, 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 */ + + /* XXX(nnorwitz): need to check for overflow! */ + indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); + if (indices == NULL) { + PyErr_NoMemory(); + return -1; + } + for (k=0; kndim;k++) { + indices[k] = 0; + } + + if (fort == 'F') { + addone = _add_one_to_index_F; + } + else { + addone = _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--) { + addone(view->ndim, indices, view->shape); + ptr = PyBuffer_GetPointer(view, indices); + memcpy(dest, ptr, view->itemsize); + dest += view->itemsize; + } + 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 *, 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 */ - - /* XXX(nnorwitz): need to check for overflow! */ - indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); - if (indices == NULL) { - PyErr_NoMemory(); - return -1; - } - for (k=0; kndim;k++) { - indices[k] = 0; - } - - if (fort == 'F') { - addone = _add_one_to_index_F; - } - else { - addone = _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--) { - addone(view->ndim, indices, view->shape); - ptr = PyBuffer_GetPointer(view, indices); - memcpy(ptr, src, view->itemsize); - src += view->itemsize; - } - - PyMem_Free(indices); - return 0; + int k; + void (*addone)(int, Py_ssize_t *, 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 */ + + /* XXX(nnorwitz): need to check for overflow! */ + indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); + if (indices == NULL) { + PyErr_NoMemory(); + return -1; + } + for (k=0; kndim;k++) { + indices[k] = 0; + } + + if (fort == 'F') { + addone = _add_one_to_index_F; + } + else { + addone = _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--) { + addone(view->ndim, indices, view->shape); + ptr = PyBuffer_GetPointer(view, indices); + memcpy(ptr, src, view->itemsize); + src += view->itemsize; + } + + 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=0; k--) { - strides[k] = sd; - sd *= shape[k]; - } - } - return; + Py_ssize_t *strides, int itemsize, + char fort) +{ + int k; + Py_ssize_t sd; + + sd = itemsize; + if (fort == 'F') { + for (k=0; 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; + 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 *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 * @@ -700,41 +700,41 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* Initialize cached value */ if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; + /* Initialize static variable needed by _PyType_Lookup */ + str__format__ = PyUnicode_FromString("__format__"); + if (str__format__ == NULL) + goto done; } /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } /* Make sure the type is initialized. float gets initialized late */ if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; + if (PyType_Ready(Py_TYPE(obj)) < 0) + goto done; /* Find the (unbound!) __format__ method (a borrowed reference) */ meth = _PyType_Lookup(Py_TYPE(obj), str__format__); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); - goto done; + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); + goto done; } /* And call it, binding it to the value */ result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: @@ -746,24 +746,24 @@ done: 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); + 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 */ #define NB_SLOT(x) offsetof(PyNumberMethods, x) #define NB_BINOP(nb_methods, slot) \ - (*(binaryfunc*)(& ((char*)nb_methods)[slot])) + (*(binaryfunc*)(& ((char*)nb_methods)[slot])) #define NB_TERNOP(nb_methods, slot) \ - (*(ternaryfunc*)(& ((char*)nb_methods)[slot])) + (*(ternaryfunc*)(& ((char*)nb_methods)[slot])) /* Calling scheme used for binary operations: Order operations are tried until either a valid result or error: - w.op(v,w)[*], v.op(v,w), w.op(v,w) + w.op(v,w)[*], v.op(v,w), w.op(v,w) [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of v->ob_type @@ -772,62 +772,62 @@ PyNumber_Check(PyObject *o) 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) - 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) { - 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 */ - } - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + PyObject *x; + binaryfunc slotv = NULL; + binaryfunc slotw = NULL; + + if (v->ob_type->tp_as_number != NULL) + 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) { + 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 */ + } + 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; + 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; + 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; } @@ -835,86 +835,86 @@ binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name) Calling scheme used for ternary operations: Order operations are tried until either a valid result or error: - v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) + v.op(v,w,z), w.op(v,w,z), z.op(v,w,z) */ 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) - slotv = NB_TERNOP(mv, op_slot); - if (w->ob_type != v->ob_type && - mw != NULL) { - 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) { - 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 (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; + 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) + slotv = NB_TERNOP(mv, op_slot); + if (w->ob_type != v->ob_type && + mw != NULL) { + 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) { + 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 (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); \ + return binary_op(v, w, NB_SLOT(op), op_name); \ } BINARY_FUNC(PyNumber_Or, nb_or, "|") @@ -928,75 +928,75 @@ 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; + 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); + 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 *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) { - return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); + return binary_op(v, w, NB_SLOT(nb_floor_divide), "//"); } PyObject * PyNumber_TrueDivide(PyObject *v, PyObject *w) { - return binary_op(v, w, NB_SLOT(nb_true_divide), "/"); + 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), "%"); + 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()"); + return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()"); } /* Binary in-place operators */ @@ -1018,37 +1018,37 @@ PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) 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) { - 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); + PyNumberMethods *mv = v->ob_type->tp_as_number; + if (mv != NULL) { + 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) + 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; + 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); \ - } + 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, "^=") @@ -1060,84 +1060,84 @@ INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") PyObject * PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) { - return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide), - NB_SLOT(nb_floor_divide), "//="); + return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide), + NB_SLOT(nb_floor_divide), "//="); } PyObject * PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) { - return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide), - NB_SLOT(nb_true_divide), "/="); + 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; - 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 *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; + 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) { - 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 *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) { + 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), "%="); + return binary_iop(v, w, NB_SLOT(nb_inplace_remainder), + NB_SLOT(nb_remainder), "%="); } PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { - if (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), "**="); - } + if (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), "**="); + } } @@ -1146,57 +1146,57 @@ PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) PyObject * PyNumber_Negative(PyObject *o) { - PyNumberMethods *m; + 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); + 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); + return type_error("bad operand type for unary -: '%.200s'", o); } PyObject * PyNumber_Positive(PyObject *o) { - PyNumberMethods *m; + 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); + 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); + return type_error("bad operand type for unary +: '%.200s'", o); } PyObject * PyNumber_Invert(PyObject *o) { - PyNumberMethods *m; + 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); + 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); + return type_error("bad operand type for unary ~: '%.200s'", o); } PyObject * PyNumber_Absolute(PyObject *o) { - PyNumberMethods *m; + 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); + 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); + return type_error("bad operand type for abs(): '%.200s'", o); } /* Return a Python Int or Long from the object item @@ -1206,30 +1206,30 @@ PyNumber_Absolute(PyObject *o) PyObject * PyNumber_Index(PyObject *item) { - PyObject *result = NULL; - if (item == NULL) - return null_error(); - if (PyLong_Check(item)) { - Py_INCREF(item); - return item; - } - if (PyIndex_Check(item)) { - result = item->ob_type->tp_as_number->nb_index(item); - if (result && !PyLong_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__index__ returned non-int " - "(type %.200s)", - result->ob_type->tp_name); - Py_DECREF(result); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, - "'%.200s' object cannot be interpreted " - "as an integer", item->ob_type->tp_name); - } - return result; + PyObject *result = NULL; + if (item == NULL) + return null_error(); + if (PyLong_Check(item)) { + Py_INCREF(item); + return item; + } + if (PyIndex_Check(item)) { + result = item->ob_type->tp_as_number->nb_index(item); + if (result && !PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-int " + "(type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + } + else { + PyErr_Format(PyExc_TypeError, + "'%.200s' object cannot be interpreted " + "as an integer", item->ob_type->tp_name); + } + return result; } /* Return an error on Overflow only if err is not NULL*/ @@ -1237,79 +1237,79 @@ PyNumber_Index(PyObject *item) 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 PyLong_AsSsize_t() returns without error. */ - result = PyLong_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); - } + Py_ssize_t result; + PyObject *runerr; + PyObject *value = PyNumber_Index(item); + if (value == NULL) + return -1; + + /* We're done if PyLong_AsSsize_t() returns without error. */ + result = PyLong_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; + Py_DECREF(value); + return result; } PyObject * _PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format) { - static PyObject *int_name = NULL; - if (int_name == NULL) { - int_name = PyUnicode_InternFromString("__int__"); - if (int_name == NULL) - return NULL; - } - - if (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 && !PyLong_Check(integral)) { - goto non_integral_error; - } - } - return integral; + static PyObject *int_name = NULL; + if (int_name == NULL) { + int_name = PyUnicode_InternFromString("__int__"); + if (int_name == NULL) + return NULL; + } + + if (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 && !PyLong_Check(integral)) { + goto non_integral_error; + } + } + return integral; non_integral_error: - PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name); - Py_DECREF(integral); - return NULL; + PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name); + Py_DECREF(integral); + return NULL; } @@ -1317,134 +1317,134 @@ non_integral_error: 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 int()"); - Py_DECREF(x); - return NULL; - } - return x; + 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 int()"); + 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 = PyUnicode_InternFromString("__trunc__"); - if (trunc_name == NULL) - return NULL; - } - - if (o == NULL) - return null_error(); - if (PyLong_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 */ - PyObject *res = m->nb_int(o); - if (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 (PyLong_Check(o)) /* An int subclass without nb_int */ - 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)"); - return int_instance; - } - PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */ - - if (PyBytes_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(PyBytes_AS_STRING(o), - PyBytes_GET_SIZE(o)); - if (PyUnicode_Check(o)) - /* The above check is done in PyLong_FromUnicode(). */ - return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), - PyUnicode_GET_SIZE(o), - 10); - if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return long_from_string(buffer, buffer_len); - - return type_error("int() argument must be a string or a " - "number, not '%.200s'", 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 = PyUnicode_InternFromString("__trunc__"); + if (trunc_name == NULL) + return NULL; + } + + if (o == NULL) + return null_error(); + if (PyLong_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 */ + PyObject *res = m->nb_int(o); + if (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 (PyLong_Check(o)) /* An int subclass without nb_int */ + 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)"); + return int_instance; + } + PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */ + + if (PyBytes_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(PyBytes_AS_STRING(o), + PyBytes_GET_SIZE(o)); + if (PyUnicode_Check(o)) + /* The above check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); + if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) + return long_from_string(buffer, buffer_len); + + return type_error("int() 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); + 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); } PyObject * PyNumber_ToBase(PyObject *n, int base) { - PyObject *res = NULL; - PyObject *index = PyNumber_Index(n); + PyObject *res = NULL; + PyObject *index = PyNumber_Index(n); - if (!index) - return NULL; - if (PyLong_Check(index)) - res = _PyLong_Format(index, base); - 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; + if (!index) + return NULL; + if (PyLong_Check(index)) + res = _PyLong_Format(index, base); + 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; } @@ -1453,507 +1453,507 @@ PyNumber_ToBase(PyObject *n, int base) int PySequence_Check(PyObject *s) { - if (PyDict_Check(s)) - return 0; - return s != NULL && s->ob_type->tp_as_sequence && - s->ob_type->tp_as_sequence->sq_item != NULL; + if (PyDict_Check(s)) + return 0; + return s != NULL && s->ob_type->tp_as_sequence && + s->ob_type->tp_as_sequence->sq_item != NULL; } Py_ssize_t PySequence_Size(PyObject *s) { - PySequenceMethods *m; + PySequenceMethods *m; - if (s == NULL) { - null_error(); - return -1; - } + if (s == NULL) { + null_error(); + return -1; + } - m = s->ob_type->tp_as_sequence; - if (m && m->sq_length) - return m->sq_length(s); + 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; + 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); + return PySequence_Size(s); } #define PySequence_Length PySequence_Size PyObject * PySequence_Concat(PyObject *s, PyObject *o) { - PySequenceMethods *m; + PySequenceMethods *m; - if (s == NULL || o == NULL) - return null_error(); + 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); + 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); + /* 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 = PyLong_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); + 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 = PyLong_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; + PySequenceMethods *m; - if (s == NULL || o == NULL) - return null_error(); + if (s == NULL || o == NULL) + return null_error(); - m = s->ob_type->tp_as_sequence; - if (m && m->sq_inplace_concat) - return m->sq_inplace_concat(s, o); - if (m && m->sq_concat) - return m->sq_concat(s, o); + m = s->ob_type->tp_as_sequence; + if (m && 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); + 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 && 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 = PyLong_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); + PySequenceMethods *m; + + if (o == NULL) + return null_error(); + + m = o->ob_type->tp_as_sequence; + if (m && 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 = PyLong_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); - } + 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); + return type_error("'%.200s' object does not support indexing", s); } PyObject * PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) { - PyMappingMethods *mp; + PyMappingMethods *mp; - if (!s) return null_error(); + if (!s) return null_error(); - mp = s->ob_type->tp_as_mapping; - if (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; - } + mp = s->ob_type->tp_as_mapping; + if (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); + return type_error("'%.200s' object is unsliceable", s); } int PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) { - PySequenceMethods *m; + PySequenceMethods *m; - if (s == NULL) { - null_error(); - return -1; - } + 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); - } + 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; + type_error("'%.200s' object does not support item assignment", s); + return -1; } int PySequence_DelItem(PyObject *s, Py_ssize_t i) { - PySequenceMethods *m; + PySequenceMethods *m; - if (s == NULL) { - null_error(); - return -1; - } + 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); - } + 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; + 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) { - PyMappingMethods *mp; + PyMappingMethods *mp; - if (s == NULL) { - null_error(); - return -1; - } + if (s == NULL) { + null_error(); + return -1; + } - mp = s->ob_type->tp_as_mapping; - if (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; - } + mp = s->ob_type->tp_as_mapping; + if (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; + 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) { - PyMappingMethods *mp; + PyMappingMethods *mp; - if (s == NULL) { - null_error(); - return -1; - } + if (s == NULL) { + null_error(); + return -1; + } - mp = s->ob_type->tp_as_mapping; - if (mp->mp_ass_subscript) { - int res; - PyObject *slice = _PySlice_FromIndices(i1, i2); - if (!slice) - return -1; - res = mp->mp_ass_subscript(s, slice, NULL); - Py_DECREF(slice); - return res; - } - type_error("'%.200s' object doesn't support slice deletion", s); - return -1; + mp = s->ob_type->tp_as_mapping; + if (mp->mp_ass_subscript) { + int res; + PyObject *slice = _PySlice_FromIndices(i1, i2); + if (!slice) + return -1; + res = mp->mp_ass_subscript(s, slice, NULL); + Py_DECREF(slice); + return res; + } + 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; + 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; + Py_XDECREF(result); + Py_DECREF(it); + return NULL; } PyObject * PySequence_List(PyObject *v) { - PyObject *result; /* result list */ - PyObject *rv; /* return value from PyList_Extend */ + PyObject *result; /* result list */ + PyObject *rv; /* return value from PyList_Extend */ - if (v == NULL) - return null_error(); + if (v == NULL) + return null_error(); - result = PyList_New(0); - if (result == NULL) - return NULL; + 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; + 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; + PyObject *it; - if (v == NULL) - return null_error(); + if (v == NULL) + return null_error(); - if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { - Py_INCREF(v); - return v; - } + 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; - } + 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); + v = PySequence_List(it); + Py_DECREF(it); - return v; + 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_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 */ + 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 */ + n = -1; + /* fall through */ Done: - Py_DECREF(it); - return n; + Py_DECREF(it); + return n; } @@ -1961,7 +1961,7 @@ Done: Py_ssize_t PySequence_Count(PyObject *s, PyObject *o) { - return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT); + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT); } /* Return -1 if error; 1 if ob in seq; 0 if ob not in seq. @@ -1970,12 +1970,12 @@ PySequence_Count(PyObject *s, PyObject *o) int PySequence_Contains(PyObject *seq, PyObject *ob) { - Py_ssize_t result; - 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); + Py_ssize_t result; + 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 */ @@ -1983,13 +1983,13 @@ PySequence_Contains(PyObject *seq, PyObject *ob) int PySequence_In(PyObject *w, PyObject *v) { - return PySequence_Contains(w, v); + return PySequence_Contains(w, v); } Py_ssize_t PySequence_Index(PyObject *s, PyObject *o) { - return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX); + return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX); } /* Operations on mappings */ @@ -1997,145 +1997,145 @@ PySequence_Index(PyObject *s, PyObject *o) int PyMapping_Check(PyObject *o) { - return o && o->ob_type->tp_as_mapping && - o->ob_type->tp_as_mapping->mp_subscript; + return o && o->ob_type->tp_as_mapping && + o->ob_type->tp_as_mapping->mp_subscript; } Py_ssize_t PyMapping_Size(PyObject *o) { - PyMappingMethods *m; + PyMappingMethods *m; - if (o == NULL) { - null_error(); - return -1; - } + if (o == NULL) { + null_error(); + return -1; + } - m = o->ob_type->tp_as_mapping; - if (m && m->mp_length) - return m->mp_length(o); + 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; + 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); + return PyMapping_Size(o); } #define PyMapping_Length PyMapping_Size PyObject * PyMapping_GetItemString(PyObject *o, char *key) { - PyObject *okey, *r; + PyObject *okey, *r; - if (key == NULL) - return null_error(); + if (key == NULL) + return null_error(); - okey = PyUnicode_FromString(key); - if (okey == NULL) - return NULL; - r = PyObject_GetItem(o, okey); - Py_DECREF(okey); - return r; + okey = PyUnicode_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; + PyObject *okey; + int r; - if (key == NULL) { - null_error(); - return -1; - } + if (key == NULL) { + null_error(); + return -1; + } - okey = PyUnicode_FromString(key); - if (okey == NULL) - return -1; - r = PyObject_SetItem(o, okey, value); - Py_DECREF(okey); - return r; + okey = PyUnicode_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; + PyObject *v; - v = PyMapping_GetItemString(o, key); - if (v) { - Py_DECREF(v); - return 1; - } - PyErr_Clear(); - return 0; + 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; + PyObject *v; - v = PyObject_GetItem(o, key); - if (v) { - Py_DECREF(v); - return 1; - } - PyErr_Clear(); - return 0; + v = PyObject_GetItem(o, key); + if (v) { + Py_DECREF(v); + return 1; + } + PyErr_Clear(); + return 0; } PyObject * PyMapping_Keys(PyObject *o) { - PyObject *keys; - PyObject *fast; + PyObject *keys; + PyObject *fast; - if (PyDict_CheckExact(o)) - return PyDict_Keys(o); - keys = PyObject_CallMethod(o, "keys", NULL); - if (keys == NULL) - return NULL; - fast = PySequence_Fast(keys, "o.keys() are not iterable"); - Py_DECREF(keys); - return fast; + if (PyDict_CheckExact(o)) + return PyDict_Keys(o); + keys = PyObject_CallMethod(o, "keys", NULL); + if (keys == NULL) + return NULL; + fast = PySequence_Fast(keys, "o.keys() are not iterable"); + Py_DECREF(keys); + return fast; } PyObject * PyMapping_Items(PyObject *o) { - PyObject *items; - PyObject *fast; + PyObject *items; + PyObject *fast; - if (PyDict_CheckExact(o)) - return PyDict_Items(o); - items = PyObject_CallMethod(o, "items", NULL); - if (items == NULL) - return NULL; - fast = PySequence_Fast(items, "o.items() are not iterable"); - Py_DECREF(items); - return fast; + if (PyDict_CheckExact(o)) + return PyDict_Items(o); + items = PyObject_CallMethod(o, "items", NULL); + if (items == NULL) + return NULL; + fast = PySequence_Fast(items, "o.items() are not iterable"); + Py_DECREF(items); + return fast; } PyObject * PyMapping_Values(PyObject *o) { - PyObject *values; - PyObject *fast; + PyObject *values; + PyObject *fast; - if (PyDict_CheckExact(o)) - return PyDict_Values(o); - values = PyObject_CallMethod(o, "values", NULL); - if (values == NULL) - return NULL; - fast = PySequence_Fast(values, "o.values() are not iterable"); - Py_DECREF(values); - return fast; + if (PyDict_CheckExact(o)) + return PyDict_Values(o); + values = PyObject_CallMethod(o, "values", NULL); + if (values == NULL) + return NULL; + fast = PySequence_Fast(values, "o.values() are not iterable"); + Py_DECREF(values); + return fast; } /* Operations on callable objects */ @@ -2145,253 +2145,253 @@ PyMapping_Values(PyObject *o) PyObject * PyObject_CallObject(PyObject *o, PyObject *a) { - return PyEval_CallObjectWithKeywords(o, a, NULL); + 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; + 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; + PyObject *retval; - if (args == NULL) - return NULL; + if (args == NULL) + return NULL; - if (!PyTuple_Check(args)) { - PyObject *a; + 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); + 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); + Py_DECREF(args); - return retval; + return retval; } PyObject * PyObject_CallFunction(PyObject *callable, char *format, ...) { - va_list va; - PyObject *args; + va_list va; + PyObject *args; - if (callable == NULL) - return null_error(); + 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); + 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); + return call_function_tail(callable, args); } PyObject * _PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...) { - va_list va; - PyObject *args; + va_list va; + PyObject *args; - if (callable == NULL) - return null_error(); + 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); + 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); + 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; + va_list va; + PyObject *args; + PyObject *func = NULL; + PyObject *retval = NULL; - if (o == NULL || name == NULL) - return null_error(); + if (o == NULL || name == NULL) + return null_error(); - func = PyObject_GetAttrString(o, name); - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); - return 0; - } + func = PyObject_GetAttrString(o, name); + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, name); + return 0; + } - if (!PyCallable_Check(func)) { - type_error("attribute of type '%.200s' is not callable", func); - goto exit; - } + 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); + 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); + retval = call_function_tail(func, args); exit: - /* args gets consumed in call_function_tail */ - Py_XDECREF(func); + /* args gets consumed in call_function_tail */ + Py_XDECREF(func); - return retval; + return retval; } PyObject * _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...) { - va_list va; - PyObject *args; - PyObject *func = NULL; - PyObject *retval = NULL; + va_list va; + PyObject *args; + PyObject *func = NULL; + PyObject *retval = NULL; - if (o == NULL || name == NULL) - return null_error(); + if (o == NULL || name == NULL) + return null_error(); - func = PyObject_GetAttrString(o, name); - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); - return 0; - } + func = PyObject_GetAttrString(o, name); + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, name); + return 0; + } - if (!PyCallable_Check(func)) { - type_error("attribute of type '%.200s' is not callable", func); - goto exit; - } + 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); + 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); + retval = call_function_tail(func, args); exit: - /* args gets consumed in call_function_tail */ - Py_XDECREF(func); + /* args gets consumed in call_function_tail */ + Py_XDECREF(func); - return retval; + return retval; } static PyObject * objargs_mktuple(va_list va) { - int i, n = 0; - va_list countva; - PyObject *result, *tmp; + int i, n = 0; + va_list countva; + PyObject *result, *tmp; #ifdef VA_LIST_IS_ARRAY - memcpy(countva, va, sizeof(va_list)); + memcpy(countva, va, sizeof(va_list)); #else #ifdef __va_copy - __va_copy(countva, va); + __va_copy(countva, va); #else - countva = va; + 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; + 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; + PyObject *args, *tmp; + va_list vargs; - if (callable == NULL || name == NULL) - return null_error(); + if (callable == NULL || name == NULL) + return null_error(); - callable = PyObject_GetAttr(callable, name); - if (callable == NULL) - return NULL; + 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); + /* 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; + return tmp; } PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...) { - PyObject *args, *tmp; - va_list vargs; + PyObject *args, *tmp; + va_list vargs; - if (callable == NULL) - return null_error(); + 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); + /* 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; + return tmp; } @@ -2415,7 +2415,7 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...) * 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 + * 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 @@ -2426,282 +2426,282 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...) static PyObject * abstract_get_bases(PyObject *cls) { - static PyObject *__bases__ = NULL; - PyObject *bases; - - if (__bases__ == NULL) { - __bases__ = PyUnicode_InternFromString("__bases__"); - if (__bases__ == NULL) - return NULL; - } - Py_ALLOW_RECURSION - bases = PyObject_GetAttr(cls, __bases__); - Py_END_ALLOW_RECURSION - if (bases == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) - PyErr_Clear(); - return NULL; - } - if (!PyTuple_Check(bases)) { - Py_DECREF(bases); - return NULL; - } - return bases; + static PyObject *__bases__ = NULL; + PyObject *bases; + + if (__bases__ == NULL) { + __bases__ = PyUnicode_InternFromString("__bases__"); + if (__bases__ == NULL) + return NULL; + } + Py_ALLOW_RECURSION + bases = PyObject_GetAttr(cls, __bases__); + Py_END_ALLOW_RECURSION + 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; - } + 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; + 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__ = PyUnicode_InternFromString("__class__"); - if (__class__ == NULL) - return -1; - } - - 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; + PyObject *icls; + static PyObject *__class__ = NULL; + int retval = 0; + + if (__class__ == NULL) { + __class__ = PyUnicode_InternFromString("__class__"); + if (__class__ == NULL) + return -1; + } + + 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; - PyObject *checker; - - /* 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; - } - - 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 + static PyObject *name = NULL; + PyObject *checker; + + /* 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; + } + + 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) { - if (PyType_Check(cls) && PyType_Check(derived)) { - /* Fast path (non-recursive) */ - return PyType_IsSubtype((PyTypeObject *)derived, (PyTypeObject *)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; + if (PyType_Check(cls) && PyType_Check(derived)) { + /* Fast path (non-recursive) */ + return PyType_IsSubtype((PyTypeObject *)derived, (PyTypeObject *)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; - return abstract_issubclass(derived, cls); + return abstract_issubclass(derived, cls); } int PyObject_IsSubclass(PyObject *derived, PyObject *cls) { - static PyObject *name = NULL; - PyObject *checker; - - 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; - } - - 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); + static PyObject *name = NULL; + PyObject *checker; + + 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; + } + + 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); + return recursive_isinstance(inst, cls); } int _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls) { - return recursive_issubclass(derived, cls); + return recursive_issubclass(derived, cls); } PyObject * PyObject_GetIter(PyObject *o) { - PyTypeObject *t = o->ob_type; - getiterfunc f = NULL; - 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; - } + PyTypeObject *t = o->ob_type; + getiterfunc f = NULL; + 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. @@ -2709,18 +2709,18 @@ PyObject_GetIter(PyObject *o) * 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. + * 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; + PyObject *result; + result = (*iter->ob_type->tp_iternext)(iter); + if (result == NULL && + PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + return result; } @@ -2735,43 +2735,43 @@ PyIter_Next(PyObject *iter) char *const * _PySequence_BytesToCharpArray(PyObject* self) { - char **array; - Py_ssize_t i, argc; - PyObject *item = NULL; - - argc = PySequence_Size(self); - if (argc == -1) - return NULL; - - array = malloc((argc + 1) * sizeof(char *)); - if (array == NULL) { - PyErr_NoMemory(); - return NULL; - } - for (i = 0; i < argc; ++i) { - char *data; - item = PySequence_GetItem(self, i); - data = PyBytes_AsString(item); - if (data == NULL) { - /* NULL terminate before freeing. */ - array[i] = NULL; - goto fail; - } - array[i] = strdup(data); - if (!array[i]) { - PyErr_NoMemory(); - goto fail; - } - Py_DECREF(item); - } - array[argc] = NULL; - - return array; + char **array; + Py_ssize_t i, argc; + PyObject *item = NULL; + + argc = PySequence_Size(self); + if (argc == -1) + return NULL; + + array = malloc((argc + 1) * sizeof(char *)); + if (array == NULL) { + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < argc; ++i) { + char *data; + item = PySequence_GetItem(self, i); + data = PyBytes_AsString(item); + if (data == NULL) { + /* NULL terminate before freeing. */ + array[i] = NULL; + goto fail; + } + array[i] = strdup(data); + if (!array[i]) { + PyErr_NoMemory(); + goto fail; + } + Py_DECREF(item); + } + array[argc] = NULL; + + return array; fail: - Py_XDECREF(item); - _Py_FreeCharPArray(array); - return NULL; + Py_XDECREF(item); + _Py_FreeCharPArray(array); + return NULL; } @@ -2779,9 +2779,9 @@ fail: void _Py_FreeCharPArray(char *const array[]) { - Py_ssize_t i; - for (i = 0; array[i] != NULL; ++i) { - free(array[i]); - } - free((void*)array); + Py_ssize_t i; + for (i = 0; array[i] != NULL; ++i) { + free(array[i]); + } + free((void*)array); } diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 3d55543077..31510bb07d 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -11,30 +11,30 @@ static PyObject *true_str = NULL; static PyObject * bool_repr(PyObject *self) { - PyObject *s; - - if (self == Py_True) - s = true_str ? true_str : - (true_str = PyUnicode_InternFromString("True")); - else - s = false_str ? false_str : - (false_str = PyUnicode_InternFromString("False")); - Py_XINCREF(s); - return s; + PyObject *s; + + if (self == Py_True) + s = true_str ? true_str : + (true_str = PyUnicode_InternFromString("True")); + else + s = false_str ? false_str : + (false_str = PyUnicode_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; + 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 */ @@ -42,16 +42,16 @@ PyObject *PyBool_FromLong(long ok) 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); + 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. */ @@ -59,25 +59,25 @@ bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * bool_and(PyObject *a, PyObject *b) { - if (!PyBool_Check(a) || !PyBool_Check(b)) - return PyLong_Type.tp_as_number->nb_and(a, b); - return PyBool_FromLong((a == Py_True) & (b == Py_True)); + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_and(a, b); + return PyBool_FromLong((a == Py_True) & (b == Py_True)); } static PyObject * bool_or(PyObject *a, PyObject *b) { - if (!PyBool_Check(a) || !PyBool_Check(b)) - return PyLong_Type.tp_as_number->nb_or(a, b); - return PyBool_FromLong((a == Py_True) | (b == Py_True)); + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_or(a, b); + return PyBool_FromLong((a == Py_True) | (b == Py_True)); } static PyObject * bool_xor(PyObject *a, PyObject *b) { - if (!PyBool_Check(a) || !PyBool_Check(b)) - return PyLong_Type.tp_as_number->nb_xor(a, b); - return PyBool_FromLong((a == Py_True) ^ (b == Py_True)); + if (!PyBool_Check(a) || !PyBool_Check(b)) + return PyLong_Type.tp_as_number->nb_xor(a, b); + return PyBool_FromLong((a == Py_True) ^ (b == Py_True)); } /* Doc string */ @@ -92,93 +92,93 @@ 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_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_bool */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - bool_and, /* nb_and */ - bool_xor, /* nb_xor */ - bool_or, /* nb_or */ - 0, /* nb_int */ - 0, /* nb_reserved */ - 0, /* nb_float */ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 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 */ - 0, /* nb_index */ + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + 0, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + bool_and, /* nb_and */ + bool_xor, /* nb_xor */ + bool_or, /* nb_or */ + 0, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 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 */ + 0, /* nb_index */ }; /* The type object for bool. Note that this cannot be subclassed! */ PyTypeObject PyBool_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bool", - sizeof(struct _longobject), - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - bool_repr, /* tp_repr */ - &bool_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - bool_repr, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* 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 */ - &PyLong_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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bool", + sizeof(struct _longobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + bool_repr, /* tp_repr */ + &bool_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + bool_repr, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* 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 */ + &PyLong_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 */ struct _longobject _Py_FalseStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 0) - { 0 } + PyVarObject_HEAD_INIT(&PyBool_Type, 0) + { 0 } }; struct _longobject _Py_TrueStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 1) - { 1 } + PyVarObject_HEAD_INIT(&PyBool_Type, 1) + { 1 } }; diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 6908eb853f..215a1fac0f 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -24,7 +24,7 @@ _Py_bytes_isspace(const char *cptr, Py_ssize_t len) e = p + len; for (; p < e; p++) { - if (!Py_ISSPACE(*p)) + if (!Py_ISSPACE(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -46,16 +46,16 @@ _Py_bytes_isalpha(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1 && Py_ISALPHA(*p)) - Py_RETURN_TRUE; + Py_RETURN_TRUE; /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + Py_RETURN_FALSE; e = p + len; for (; p < e; p++) { - if (!Py_ISALPHA(*p)) - Py_RETURN_FALSE; + if (!Py_ISALPHA(*p)) + Py_RETURN_FALSE; } Py_RETURN_TRUE; } @@ -76,16 +76,16 @@ _Py_bytes_isalnum(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1 && Py_ISALNUM(*p)) - Py_RETURN_TRUE; + Py_RETURN_TRUE; /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + Py_RETURN_FALSE; e = p + len; for (; p < e; p++) { - if (!Py_ISALNUM(*p)) - Py_RETURN_FALSE; + if (!Py_ISALNUM(*p)) + Py_RETURN_FALSE; } Py_RETURN_TRUE; } @@ -106,16 +106,16 @@ _Py_bytes_isdigit(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1 && Py_ISDIGIT(*p)) - Py_RETURN_TRUE; + Py_RETURN_TRUE; /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + Py_RETURN_FALSE; e = p + len; for (; p < e; p++) { - if (!Py_ISDIGIT(*p)) - Py_RETURN_FALSE; + if (!Py_ISDIGIT(*p)) + Py_RETURN_FALSE; } Py_RETURN_TRUE; } @@ -137,19 +137,19 @@ _Py_bytes_islower(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(Py_ISLOWER(*p)); + return PyBool_FromLong(Py_ISLOWER(*p)); /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + 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; + if (Py_ISUPPER(*p)) + Py_RETURN_FALSE; + else if (!cased && Py_ISLOWER(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -171,19 +171,19 @@ _Py_bytes_isupper(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(Py_ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + 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; + if (Py_ISLOWER(*p)) + Py_RETURN_FALSE; + else if (!cased && Py_ISUPPER(*p)) + cased = 1; } return PyBool_FromLong(cased); } @@ -207,32 +207,32 @@ _Py_bytes_istitle(const char *cptr, Py_ssize_t len) /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(Py_ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) - Py_RETURN_FALSE; + 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; + 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); } @@ -246,23 +246,23 @@ 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; + Py_ssize_t i; /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (!newobj) - return NULL; + newobj = PyBytes_FromStringAndSize(NULL, len); + if (!newobj) + return NULL; - s = PyBytes_AS_STRING(newobj); + s = PyBytes_AS_STRING(newobj); */ - Py_MEMCPY(result, cptr, len); + 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); - } + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(result[i]); + if (Py_ISUPPER(c)) + result[i] = Py_TOLOWER(c); + } } @@ -274,23 +274,23 @@ 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; + Py_ssize_t i; /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (!newobj) - return NULL; + newobj = PyBytes_FromStringAndSize(NULL, len); + if (!newobj) + return NULL; - s = PyBytes_AS_STRING(newobj); + s = PyBytes_AS_STRING(newobj); */ - Py_MEMCPY(result, cptr, len); + 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); - } + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(result[i]); + if (Py_ISLOWER(c)) + result[i] = Py_TOUPPER(c); + } } @@ -303,29 +303,29 @@ 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; + Py_ssize_t i; + int previous_is_cased = 0; /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_AsString(newobj); + newobj = PyBytes_FromStringAndSize(NULL, len); + if (newobj == NULL) + return NULL; + s_new = PyBytes_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; - } + 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; + } } @@ -337,30 +337,30 @@ Return a copy of B with only its first character capitalized (ASCII)."); void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len) { - Py_ssize_t i; + Py_ssize_t i; /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_AsString(newobj); + newobj = PyBytes_FromStringAndSize(NULL, len); + if (newobj == NULL) + return NULL; + s_new = PyBytes_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++; - } + 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++; + } } @@ -373,26 +373,26 @@ to lowercase ASCII and vice versa."); void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len) { - Py_ssize_t i; + Py_ssize_t i; /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_AsString(newobj); + newobj = PyBytes_FromStringAndSize(NULL, len); + if (newobj == NULL) + return NULL; + s_new = PyBytes_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++; - } + 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++; + } } @@ -425,40 +425,40 @@ _getbuffer(PyObject *obj, Py_buffer *view) PyObject * _Py_bytes_maketrans(PyObject *args) { - PyObject *frm, *to, *res = NULL; - Py_buffer bfrm, bto; - Py_ssize_t i; - char *p; - - bfrm.len = -1; - bto.len = -1; - - if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) - return NULL; - if (_getbuffer(frm, &bfrm) < 0) - return NULL; - if (_getbuffer(to, &bto) < 0) - goto done; - if (bfrm.len != bto.len) { - PyErr_Format(PyExc_ValueError, - "maketrans arguments must have same length"); - goto done; - } - res = PyBytes_FromStringAndSize(NULL, 256); - if (!res) { - goto done; - } - p = PyBytes_AS_STRING(res); - for (i = 0; i < 256; i++) - p[i] = i; - for (i = 0; i < bfrm.len; i++) { - p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; - } + PyObject *frm, *to, *res = NULL; + Py_buffer bfrm, bto; + Py_ssize_t i; + char *p; + + bfrm.len = -1; + bto.len = -1; + + if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) + return NULL; + if (_getbuffer(frm, &bfrm) < 0) + return NULL; + if (_getbuffer(to, &bto) < 0) + goto done; + if (bfrm.len != bto.len) { + PyErr_Format(PyExc_ValueError, + "maketrans arguments must have same length"); + goto done; + } + res = PyBytes_FromStringAndSize(NULL, 256); + if (!res) { + goto done; + } + p = PyBytes_AS_STRING(res); + for (i = 0; i < 256; i++) + p[i] = i; + for (i = 0; i < bfrm.len; i++) { + p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + } done: - if (bfrm.len != -1) - PyBuffer_Release(&bfrm); - if (bto.len != -1) - PyBuffer_Release(&bto); - return res; + if (bfrm.len != -1) + PyBuffer_Release(&bfrm); + if (bto.len != -1) + PyBuffer_Release(&bto); + return res; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index a05bf03d56..8a15e89c9b 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -14,14 +14,14 @@ _getbuffer(PyObject *obj, Py_buffer *view) 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; + 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 -1; return view->len; } @@ -69,305 +69,305 @@ static PyBytesObject *nullstring; PyObject * PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) { - register PyBytesObject *op; - if (size < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to PyBytes_FromStringAndSize"); - return NULL; - } - if (size == 0 && (op = nullstring) != NULL) { + register PyBytesObject *op; + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyBytes_FromStringAndSize"); + return NULL; + } + if (size == 0 && (op = nullstring) != NULL) { #ifdef COUNT_ALLOCS - null_strings++; + null_strings++; #endif - Py_INCREF(op); - return (PyObject *)op; - } - if (size == 1 && str != NULL && - (op = characters[*str & UCHAR_MAX]) != NULL) - { + Py_INCREF(op); + return (PyObject *)op; + } + if (size == 1 && str != NULL && + (op = characters[*str & UCHAR_MAX]) != NULL) + { #ifdef COUNT_ALLOCS - one_strings++; + one_strings++; #endif - Py_INCREF(op); - return (PyObject *)op; - } - - if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { - PyErr_SetString(PyExc_OverflowError, - "byte string is too large"); - return NULL; - } - - /* Inline PyObject_NewVar */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); - if (op == NULL) - return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); - op->ob_shash = -1; - if (str != NULL) - Py_MEMCPY(op->ob_sval, str, size); - op->ob_sval[size] = '\0'; - /* share short strings */ - if (size == 0) { - nullstring = op; - Py_INCREF(op); - } else if (size == 1 && str != NULL) { - characters[*str & UCHAR_MAX] = op; - Py_INCREF(op); - } - return (PyObject *) op; + Py_INCREF(op); + return (PyObject *)op; + } + + if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too large"); + return NULL; + } + + /* Inline PyObject_NewVar */ + op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); + if (op == NULL) + return PyErr_NoMemory(); + PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + if (str != NULL) + Py_MEMCPY(op->ob_sval, str, size); + op->ob_sval[size] = '\0'; + /* share short strings */ + if (size == 0) { + nullstring = op; + Py_INCREF(op); + } else if (size == 1 && str != NULL) { + characters[*str & UCHAR_MAX] = op; + Py_INCREF(op); + } + return (PyObject *) op; } PyObject * PyBytes_FromString(const char *str) { - register size_t size; - register PyBytesObject *op; - - assert(str != NULL); - size = strlen(str); - if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { - PyErr_SetString(PyExc_OverflowError, - "byte string is too long"); - return NULL; - } - if (size == 0 && (op = nullstring) != NULL) { + register size_t size; + register PyBytesObject *op; + + assert(str != NULL); + size = strlen(str); + if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too long"); + return NULL; + } + if (size == 0 && (op = nullstring) != NULL) { #ifdef COUNT_ALLOCS - null_strings++; + null_strings++; #endif - Py_INCREF(op); - return (PyObject *)op; - } - if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { + Py_INCREF(op); + return (PyObject *)op; + } + if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { #ifdef COUNT_ALLOCS - one_strings++; + one_strings++; #endif - Py_INCREF(op); - return (PyObject *)op; - } - - /* Inline PyObject_NewVar */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); - if (op == NULL) - return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); - op->ob_shash = -1; - Py_MEMCPY(op->ob_sval, str, size+1); - /* share short strings */ - if (size == 0) { - nullstring = op; - Py_INCREF(op); - } else if (size == 1) { - characters[*str & UCHAR_MAX] = op; - Py_INCREF(op); - } - return (PyObject *) op; + Py_INCREF(op); + return (PyObject *)op; + } + + /* Inline PyObject_NewVar */ + op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); + if (op == NULL) + return PyErr_NoMemory(); + PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + Py_MEMCPY(op->ob_sval, str, size+1); + /* share short strings */ + if (size == 0) { + nullstring = op; + Py_INCREF(op); + } else if (size == 1) { + characters[*str & UCHAR_MAX] = op; + Py_INCREF(op); + } + return (PyObject *) op; } PyObject * PyBytes_FromFormatV(const char *format, va_list vargs) { - va_list count; - Py_ssize_t n = 0; - const char* f; - char *s; - PyObject* string; + 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)); + Py_MEMCPY(count, vargs, sizeof(va_list)); #else #ifdef __va_copy - __va_copy(count, vargs); + __va_copy(count, vargs); #else - count = vargs; + count = vargs; #endif #endif - /* step 1: figure out how large a buffer we need */ - for (f = format; *f; f++) { - if (*f == '%') { - const char* p = f; - while (*++f && *f != '%' && !ISALPHA(*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' || *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); - /* 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++; - } + /* step 1: figure out how large a buffer we need */ + for (f = format; *f; f++) { + if (*f == '%') { + const char* p = f; + while (*++f && *f != '%' && !ISALPHA(*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' || *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); + /* 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 = PyBytes_FromStringAndSize(NULL, n); - if (!string) - return NULL; - - s = PyBytes_AsString(string); - - for (f = format; *f; f++) { - if (*f == '%') { - const char* p = f++; - Py_ssize_t i; - int longflag = 0; - int size_tflag = 0; - /* parse the width.precision part (we're only - interested in the precision value, if any) */ - n = 0; - while (ISDIGIT(*f)) - n = (n*10) + *f++ - '0'; - if (*f == '.') { - f++; - n = 0; - while (ISDIGIT(*f)) - n = (n*10) + *f++ - '0'; - } - while (*f && *f != '%' && !ISALPHA(*f)) - f++; - /* 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': - if (longflag) - sprintf(s, "%ld", va_arg(vargs, long)); - 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)); - 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; - } + /* 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 = PyBytes_FromStringAndSize(NULL, n); + if (!string) + return NULL; + + s = PyBytes_AsString(string); + + for (f = format; *f; f++) { + if (*f == '%') { + const char* p = f++; + Py_ssize_t i; + int longflag = 0; + int size_tflag = 0; + /* parse the width.precision part (we're only + interested in the precision value, if any) */ + n = 0; + while (ISDIGIT(*f)) + n = (n*10) + *f++ - '0'; + if (*f == '.') { + f++; + n = 0; + while (ISDIGIT(*f)) + n = (n*10) + *f++ - '0'; + } + while (*f && *f != '%' && !ISALPHA(*f)) + f++; + /* 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': + if (longflag) + sprintf(s, "%ld", va_arg(vargs, long)); + 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)); + 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: - _PyBytes_Resize(&string, s - PyBytes_AS_STRING(string)); - return string; + _PyBytes_Resize(&string, s - PyBytes_AS_STRING(string)); + return string; } PyObject * PyBytes_FromFormat(const char *format, ...) { - PyObject* ret; - va_list vargs; + PyObject* ret; + va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); + va_start(vargs, format); #else - va_start(vargs); + va_start(vargs); #endif - ret = PyBytes_FromFormatV(format, vargs); - va_end(vargs); - return ret; + ret = PyBytes_FromFormatV(format, vargs); + va_end(vargs); + return ret; } static void bytes_dealloc(PyObject *op) { - Py_TYPE(op)->tp_free(op); + Py_TYPE(op)->tp_free(op); } /* Unescape a backslash-escaped string. If unicode is non-zero, @@ -376,135 +376,135 @@ bytes_dealloc(PyObject *op) specified encoding. */ PyObject *PyBytes_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 = PyBytes_FromStringAndSize((char *)NULL, newlen); - if (v == NULL) - return NULL; - p = buf = PyBytes_AsString(v); - end = s + len; - while (s < end) { - if (*s != '\\') { - non_esc: - 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(PyBytes_Check(w)); - r = PyBytes_AS_STRING(w); - rn = PyBytes_GET_SIZE(w); - Py_MEMCPY(p, r, rn); - p += rn; - Py_DECREF(w); - s = t; - } else { - *p++ = *s++; - } - 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(s[0]) && ISXDIGIT(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; - } - default: - *p++ = '\\'; - s--; - goto non_esc; /* an arbitry number of unescaped - UTF-8 bytes may follow. */ - } - } - if (p-buf < newlen) - _PyBytes_Resize(&v, p - buf); - return v; + 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 = PyBytes_FromStringAndSize((char *)NULL, newlen); + if (v == NULL) + return NULL; + p = buf = PyBytes_AsString(v); + end = s + len; + while (s < end) { + if (*s != '\\') { + non_esc: + 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(PyBytes_Check(w)); + r = PyBytes_AS_STRING(w); + rn = PyBytes_GET_SIZE(w); + Py_MEMCPY(p, r, rn); + p += rn; + Py_DECREF(w); + s = t; + } else { + *p++ = *s++; + } + 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(s[0]) && ISXDIGIT(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; + } + default: + *p++ = '\\'; + s--; + goto non_esc; /* an arbitry number of unescaped + UTF-8 bytes may follow. */ + } + } + if (p-buf < newlen) + _PyBytes_Resize(&v, p - buf); + return v; failed: - Py_DECREF(v); - return NULL; + Py_DECREF(v); + return NULL; } /* -------------------------------------------------------------------- */ @@ -513,50 +513,50 @@ PyObject *PyBytes_DecodeEscape(const char *s, Py_ssize_t PyBytes_Size(register PyObject *op) { - if (!PyBytes_Check(op)) { - PyErr_Format(PyExc_TypeError, - "expected bytes, %.200s found", Py_TYPE(op)->tp_name); - return -1; - } - return Py_SIZE(op); + if (!PyBytes_Check(op)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(op)->tp_name); + return -1; + } + return Py_SIZE(op); } char * PyBytes_AsString(register PyObject *op) { - if (!PyBytes_Check(op)) { - PyErr_Format(PyExc_TypeError, - "expected bytes, %.200s found", Py_TYPE(op)->tp_name); - return NULL; - } - return ((PyBytesObject *)op)->ob_sval; + if (!PyBytes_Check(op)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(op)->tp_name); + return NULL; + } + return ((PyBytesObject *)op)->ob_sval; } int PyBytes_AsStringAndSize(register PyObject *obj, - register char **s, - register Py_ssize_t *len) -{ - if (s == NULL) { - PyErr_BadInternalCall(); - return -1; - } - - if (!PyBytes_Check(obj)) { - PyErr_Format(PyExc_TypeError, - "expected bytes, %.200s found", Py_TYPE(obj)->tp_name); - return -1; - } - - *s = PyBytes_AS_STRING(obj); - if (len != NULL) - *len = PyBytes_GET_SIZE(obj); - else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { - PyErr_SetString(PyExc_TypeError, - "expected bytes with no null"); - return -1; - } - return 0; + register char **s, + register Py_ssize_t *len) +{ + if (s == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyBytes_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected bytes, %.200s found", Py_TYPE(obj)->tp_name); + return -1; + } + + *s = PyBytes_AS_STRING(obj); + if (len != NULL) + *len = PyBytes_GET_SIZE(obj); + else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { + PyErr_SetString(PyExc_TypeError, + "expected bytes with no null"); + return -1; + } + return 0; } /* -------------------------------------------------------------------- */ @@ -576,199 +576,199 @@ PyBytes_AsStringAndSize(register PyObject *obj, PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) { - static const char *hexdigits = "0123456789abcdef"; - register PyBytesObject* op = (PyBytesObject*) obj; - Py_ssize_t length = Py_SIZE(op); - size_t newsize = 3 + 4 * length; - PyObject *v; - if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) { - PyErr_SetString(PyExc_OverflowError, - "bytes object is too large to make repr"); - return NULL; - } - v = PyUnicode_FromUnicode(NULL, newsize); - if (v == NULL) { - return NULL; - } - else { - register Py_ssize_t i; - register Py_UNICODE c; - register Py_UNICODE *p = PyUnicode_AS_UNICODE(v); - int quote; - - /* Figure out which quote to use; single is preferred */ - quote = '\''; - if (smartquotes) { - char *test, *start; - start = PyBytes_AS_STRING(op); - for (test = start; test < start+length; ++test) { - if (*test == '"') { - quote = '\''; /* back to single */ - goto decided; - } - else if (*test == '\'') - quote = '"'; - } - decided: - ; - } - - *p++ = 'b', *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 - PyUnicode_AS_UNICODE(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) { - *p++ = '\\'; - *p++ = 'x'; - *p++ = hexdigits[(c & 0xf0) >> 4]; - *p++ = hexdigits[c & 0xf]; - } - else - *p++ = c; - } - assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1); - *p++ = quote; - *p = '\0'; - if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) { - Py_DECREF(v); - return NULL; - } - return v; - } + static const char *hexdigits = "0123456789abcdef"; + register PyBytesObject* op = (PyBytesObject*) obj; + Py_ssize_t length = Py_SIZE(op); + size_t newsize = 3 + 4 * length; + PyObject *v; + if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) { + PyErr_SetString(PyExc_OverflowError, + "bytes object is too large to make repr"); + return NULL; + } + v = PyUnicode_FromUnicode(NULL, newsize); + if (v == NULL) { + return NULL; + } + else { + register Py_ssize_t i; + register Py_UNICODE c; + register Py_UNICODE *p = PyUnicode_AS_UNICODE(v); + int quote; + + /* Figure out which quote to use; single is preferred */ + quote = '\''; + if (smartquotes) { + char *test, *start; + start = PyBytes_AS_STRING(op); + for (test = start; test < start+length; ++test) { + if (*test == '"') { + quote = '\''; /* back to single */ + goto decided; + } + else if (*test == '\'') + quote = '"'; + } + decided: + ; + } + + *p++ = 'b', *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 - PyUnicode_AS_UNICODE(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) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hexdigits[(c & 0xf0) >> 4]; + *p++ = hexdigits[c & 0xf]; + } + else + *p++ = c; + } + assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1); + *p++ = quote; + *p = '\0'; + if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) { + Py_DECREF(v); + return NULL; + } + return v; + } } static PyObject * bytes_repr(PyObject *op) { - return PyBytes_Repr(op, 1); + return PyBytes_Repr(op, 1); } static PyObject * bytes_str(PyObject *op) { - if (Py_BytesWarningFlag) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "str() on a bytes instance", 1)) - return NULL; - } - return bytes_repr(op); + if (Py_BytesWarningFlag) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "str() on a bytes instance", 1)) + return NULL; + } + return bytes_repr(op); } static Py_ssize_t bytes_length(PyBytesObject *a) { - return Py_SIZE(a); + return Py_SIZE(a); } /* This is also used by PyBytes_Concat() */ static PyObject * bytes_concat(PyObject *a, PyObject *b) { - Py_ssize_t size; - Py_buffer va, vb; - PyObject *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; - } - - /* Optimize end cases */ - if (va.len == 0 && PyBytes_CheckExact(b)) { - result = b; - Py_INCREF(result); - goto done; - } - if (vb.len == 0 && PyBytes_CheckExact(a)) { - result = a; - Py_INCREF(result); - goto done; - } - - size = va.len + vb.len; - if (size < 0) { - PyErr_NoMemory(); - goto done; - } - - result = PyBytes_FromStringAndSize(NULL, size); - if (result != NULL) { - memcpy(PyBytes_AS_STRING(result), va.buf, va.len); - memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len); - } + Py_ssize_t size; + Py_buffer va, vb; + PyObject *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; + } + + /* Optimize end cases */ + if (va.len == 0 && PyBytes_CheckExact(b)) { + result = b; + Py_INCREF(result); + goto done; + } + if (vb.len == 0 && PyBytes_CheckExact(a)) { + result = a; + Py_INCREF(result); + goto done; + } + + size = va.len + vb.len; + if (size < 0) { + PyErr_NoMemory(); + goto done; + } + + result = PyBytes_FromStringAndSize(NULL, size); + if (result != NULL) { + memcpy(PyBytes_AS_STRING(result), va.buf, va.len); + memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len); + } done: - if (va.len != -1) - PyBuffer_Release(&va); - if (vb.len != -1) - PyBuffer_Release(&vb); - return result; + if (va.len != -1) + PyBuffer_Release(&va); + if (vb.len != -1) + PyBuffer_Release(&vb); + return result; } static PyObject * bytes_repeat(register PyBytesObject *a, register Py_ssize_t n) { - register Py_ssize_t i; - register Py_ssize_t j; - register Py_ssize_t size; - register PyBytesObject *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 bytes are too long"); - return NULL; - } - if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; - } - nbytes = (size_t)size; - if (nbytes + PyBytesObject_SIZE <= nbytes) { - PyErr_SetString(PyExc_OverflowError, - "repeated bytes are too long"); - return NULL; - } - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); - if (op == NULL) - return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); - op->ob_shash = -1; - 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; + register Py_ssize_t i; + register Py_ssize_t j; + register Py_ssize_t size; + register PyBytesObject *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 bytes are too long"); + return NULL; + } + if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { + Py_INCREF(a); + return (PyObject *)a; + } + nbytes = (size_t)size; + if (nbytes + PyBytesObject_SIZE <= nbytes) { + PyErr_SetString(PyExc_OverflowError, + "repeated bytes are too long"); + return NULL; + } + op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); + if (op == NULL) + return PyErr_NoMemory(); + PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + 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; } static int @@ -776,19 +776,19 @@ bytes_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(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_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; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; @@ -797,197 +797,197 @@ bytes_contains(PyObject *self, PyObject *arg) static PyObject * bytes_item(PyBytesObject *a, register Py_ssize_t i) { - if (i < 0 || i >= Py_SIZE(a)) { - PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; - } - return PyLong_FromLong((unsigned char)a->ob_sval[i]); + if (i < 0 || i >= Py_SIZE(a)) { + PyErr_SetString(PyExc_IndexError, "index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)a->ob_sval[i]); } static PyObject* bytes_richcompare(PyBytesObject *a, PyBytesObject *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 (!(PyBytes_Check(a) && PyBytes_Check(b))) { - if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && - (PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyUnicode_Type) || - PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyUnicode_Type))) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytes and string", 1)) - return NULL; - } - 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; + int c; + Py_ssize_t len_a, len_b; + Py_ssize_t min_len; + PyObject *result; + + /* Make sure both arguments are strings. */ + if (!(PyBytes_Check(a) && PyBytes_Check(b))) { + if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && + (PyObject_IsInstance((PyObject*)a, + (PyObject*)&PyUnicode_Type) || + PyObject_IsInstance((PyObject*)b, + (PyObject*)&PyUnicode_Type))) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and string", 1)) + return NULL; + } + 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; + Py_INCREF(result); + return result; } static long bytes_hash(PyBytesObject *a) { - register Py_ssize_t len; - register unsigned char *p; - register long x; + register Py_ssize_t len; + register unsigned char *p; + register long x; - if (a->ob_shash != -1) - return a->ob_shash; - len = Py_SIZE(a); - p = (unsigned char *) a->ob_sval; - x = *p << 7; - while (--len >= 0) - x = (1000003*x) ^ *p++; - x ^= Py_SIZE(a); - if (x == -1) - x = -2; - a->ob_shash = x; - return x; + if (a->ob_shash != -1) + return a->ob_shash; + len = Py_SIZE(a); + p = (unsigned char *) a->ob_sval; + x = *p << 7; + while (--len >= 0) + x = (1000003*x) ^ *p++; + x ^= Py_SIZE(a); + if (x == -1) + x = -2; + a->ob_shash = x; + return x; } static PyObject* bytes_subscript(PyBytesObject* 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 += PyBytes_GET_SIZE(self); - if (i < 0 || i >= PyBytes_GET_SIZE(self)) { - PyErr_SetString(PyExc_IndexError, - "index out of range"); - return NULL; - } - return PyLong_FromLong((unsigned char)self->ob_sval[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, - PyBytes_GET_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { - return NULL; - } - - if (slicelength <= 0) { - return PyBytes_FromStringAndSize("", 0); - } - else if (start == 0 && step == 1 && - slicelength == PyBytes_GET_SIZE(self) && - PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; - } - else if (step == 1) { - return PyBytes_FromStringAndSize( - PyBytes_AS_STRING(self) + start, - slicelength); - } - else { - source_buf = PyBytes_AS_STRING(self); - result = PyBytes_FromStringAndSize(NULL, slicelength); - if (result == NULL) - return NULL; - - result_buf = PyBytes_AS_STRING(result); - for (cur = start, i = 0; i < slicelength; - cur += step, i++) { - result_buf[i] = source_buf[cur]; - } - - return result; - } - } - else { - PyErr_Format(PyExc_TypeError, - "byte indices must be integers, not %.200s", - Py_TYPE(item)->tp_name); - 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 += PyBytes_GET_SIZE(self); + if (i < 0 || i >= PyBytes_GET_SIZE(self)) { + PyErr_SetString(PyExc_IndexError, + "index out of range"); + return NULL; + } + return PyLong_FromLong((unsigned char)self->ob_sval[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, + PyBytes_GET_SIZE(self), + &start, &stop, &step, &slicelength) < 0) { + return NULL; + } + + if (slicelength <= 0) { + return PyBytes_FromStringAndSize("", 0); + } + else if (start == 0 && step == 1 && + slicelength == PyBytes_GET_SIZE(self) && + PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject *)self; + } + else if (step == 1) { + return PyBytes_FromStringAndSize( + PyBytes_AS_STRING(self) + start, + slicelength); + } + else { + source_buf = PyBytes_AS_STRING(self); + result = PyBytes_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + + result_buf = PyBytes_AS_STRING(result); + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + result_buf[i] = source_buf[cur]; + } + + return result; + } + } + else { + PyErr_Format(PyExc_TypeError, + "byte indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); + return NULL; + } } static int bytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) { - return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), - 1, flags); + return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), + 1, flags); } static PySequenceMethods bytes_as_sequence = { - (lenfunc)bytes_length, /*sq_length*/ - (binaryfunc)bytes_concat, /*sq_concat*/ - (ssizeargfunc)bytes_repeat, /*sq_repeat*/ - (ssizeargfunc)bytes_item, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - (objobjproc)bytes_contains /*sq_contains*/ + (lenfunc)bytes_length, /*sq_length*/ + (binaryfunc)bytes_concat, /*sq_concat*/ + (ssizeargfunc)bytes_repeat, /*sq_repeat*/ + (ssizeargfunc)bytes_item, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + (objobjproc)bytes_contains /*sq_contains*/ }; static PyMappingMethods bytes_as_mapping = { - (lenfunc)bytes_length, - (binaryfunc)bytes_subscript, - 0, + (lenfunc)bytes_length, + (binaryfunc)bytes_subscript, + 0, }; static PyBufferProcs bytes_as_buffer = { - (getbufferproc)bytes_buffer_getbuffer, - NULL, + (getbufferproc)bytes_buffer_getbuffer, + NULL, }; @@ -1011,26 +1011,26 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * bytes_split(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; - const char *s = PyBytes_AS_STRING(self), *sub; - Py_buffer vsub; - PyObject *list, *subobj = Py_None; + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; + const char *s = PyBytes_AS_STRING(self), *sub; + Py_buffer vsub; + PyObject *list, *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 (_getbuffer(subobj, &vsub) < 0) - return NULL; - sub = vsub.buf; - n = vsub.len; + 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; + list = stringlib_split((PyObject*) self, s, len, sub, n, maxsplit); + PyBuffer_Release(&vsub); + return list; } PyDoc_STRVAR(partition__doc__, @@ -1043,21 +1043,21 @@ found, returns B and two empty bytes objects."); static PyObject * bytes_partition(PyBytesObject *self, PyObject *sep_obj) { - const char *sep; - Py_ssize_t sep_len; + const char *sep; + Py_ssize_t sep_len; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; + if (PyBytes_Check(sep_obj)) { + sep = PyBytes_AS_STRING(sep_obj); + sep_len = PyBytes_GET_SIZE(sep_obj); + } + else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) + return NULL; - return stringlib_partition( - (PyObject*) self, - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len - ); + return stringlib_partition( + (PyObject*) self, + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sep_obj, sep, sep_len + ); } PyDoc_STRVAR(rpartition__doc__, @@ -1071,21 +1071,21 @@ bytes objects and B."); static PyObject * bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) { - const char *sep; - Py_ssize_t sep_len; + const char *sep; + Py_ssize_t sep_len; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; + if (PyBytes_Check(sep_obj)) { + sep = PyBytes_AS_STRING(sep_obj); + sep_len = PyBytes_GET_SIZE(sep_obj); + } + else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) + return NULL; - return stringlib_rpartition( - (PyObject*) self, - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len - ); + return stringlib_rpartition( + (PyObject*) self, + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sep_obj, sep, sep_len + ); } PyDoc_STRVAR(rsplit__doc__, @@ -1101,26 +1101,26 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *args) { - Py_ssize_t len = PyBytes_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; - const char *s = PyBytes_AS_STRING(self), *sub; - Py_buffer vsub; - PyObject *list, *subobj = Py_None; + Py_ssize_t len = PyBytes_GET_SIZE(self), n; + Py_ssize_t maxsplit = -1; + const char *s = PyBytes_AS_STRING(self), *sub; + Py_buffer vsub; + PyObject *list, *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 (_getbuffer(subobj, &vsub) < 0) - return NULL; - sub = vsub.buf; - n = vsub.len; + 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; + list = stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit); + PyBuffer_Release(&vsub); + return list; } @@ -1133,156 +1133,156 @@ Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); static PyObject * bytes_join(PyObject *self, PyObject *orig) { - char *sep = PyBytes_AS_STRING(self); - const Py_ssize_t seplen = PyBytes_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, ""); - if (seq == NULL) { - return NULL; - } - - seqlen = PySequence_Size(seq); - if (seqlen == 0) { - Py_DECREF(seq); - return PyBytes_FromString(""); - } - if (seqlen == 1) { - item = PySequence_Fast_GET_ITEM(seq, 0); - if (PyBytes_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), and see whether all argument are bytes. - */ - /* XXX Shouldn't we use _getbuffer() on these items instead? */ - for (i = 0; i < seqlen; i++) { - const size_t old_sz = sz; - item = PySequence_Fast_GET_ITEM(seq, i); - if (!PyBytes_Check(item) && !PyByteArray_Check(item)) { - PyErr_Format(PyExc_TypeError, - "sequence item %zd: expected bytes," - " %.80s found", - i, Py_TYPE(item)->tp_name); - Py_DECREF(seq); - return NULL; - } - sz += Py_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 bytes"); - Py_DECREF(seq); - return NULL; - } - } - - /* Allocate result space. */ - res = PyBytes_FromStringAndSize((char*)NULL, sz); - if (res == NULL) { - Py_DECREF(seq); - return NULL; - } - - /* Catenate everything. */ - /* I'm not worried about a PyByteArray item growing because there's - nowhere in this function where we release the GIL. */ - p = PyBytes_AS_STRING(res); - for (i = 0; i < seqlen; ++i) { - size_t n; - char *q; - if (i) { - Py_MEMCPY(p, sep, seplen); - p += seplen; - } - item = PySequence_Fast_GET_ITEM(seq, i); - n = Py_SIZE(item); - if (PyBytes_Check(item)) - q = PyBytes_AS_STRING(item); - else - q = PyByteArray_AS_STRING(item); - Py_MEMCPY(p, q, n); - p += n; - } - - Py_DECREF(seq); - return res; + char *sep = PyBytes_AS_STRING(self); + const Py_ssize_t seplen = PyBytes_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, ""); + if (seq == NULL) { + return NULL; + } + + seqlen = PySequence_Size(seq); + if (seqlen == 0) { + Py_DECREF(seq); + return PyBytes_FromString(""); + } + if (seqlen == 1) { + item = PySequence_Fast_GET_ITEM(seq, 0); + if (PyBytes_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), and see whether all argument are bytes. + */ + /* XXX Shouldn't we use _getbuffer() on these items instead? */ + for (i = 0; i < seqlen; i++) { + const size_t old_sz = sz; + item = PySequence_Fast_GET_ITEM(seq, i); + if (!PyBytes_Check(item) && !PyByteArray_Check(item)) { + PyErr_Format(PyExc_TypeError, + "sequence item %zd: expected bytes," + " %.80s found", + i, Py_TYPE(item)->tp_name); + Py_DECREF(seq); + return NULL; + } + sz += Py_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 bytes"); + Py_DECREF(seq); + return NULL; + } + } + + /* Allocate result space. */ + res = PyBytes_FromStringAndSize((char*)NULL, sz); + if (res == NULL) { + Py_DECREF(seq); + return NULL; + } + + /* Catenate everything. */ + /* I'm not worried about a PyByteArray item growing because there's + nowhere in this function where we release the GIL. */ + p = PyBytes_AS_STRING(res); + for (i = 0; i < seqlen; ++i) { + size_t n; + char *q; + if (i) { + Py_MEMCPY(p, sep, seplen); + p += seplen; + } + item = PySequence_Fast_GET_ITEM(seq, i); + n = Py_SIZE(item); + if (PyBytes_Check(item)) + q = PyBytes_AS_STRING(item); + else + q = PyByteArray_AS_STRING(item); + Py_MEMCPY(p, q, n); + p += n; + } + + Py_DECREF(seq); + return res; } PyObject * _PyBytes_Join(PyObject *sep, PyObject *x) { - assert(sep != NULL && PyBytes_Check(sep)); - assert(x != NULL); - return bytes_join(sep, x); + assert(sep != NULL && PyBytes_Check(sep)); + assert(x != NULL); + return bytes_join(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; \ - } + 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) bytes_find_internal(PyBytesObject *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; - PyObject *obj_start=Py_None, *obj_end=Py_None; - - if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj, - &obj_start, &obj_end)) - return -2; - /* 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, &start)) - return -2; - if (obj_end != Py_None) - if (!_PyEval_SliceIndex(obj_end, &end)) - return -2; - - if (PyBytes_Check(subobj)) { - sub = PyBytes_AS_STRING(subobj); - sub_len = PyBytes_GET_SIZE(subobj); - } - 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( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); - else - return stringlib_rfind_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); + PyObject *subobj; + const char *sub; + Py_ssize_t sub_len; + Py_ssize_t start=0, end=PY_SSIZE_T_MAX; + PyObject *obj_start=Py_None, *obj_end=Py_None; + + if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj, + &obj_start, &obj_end)) + return -2; + /* 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, &start)) + return -2; + if (obj_end != Py_None) + if (!_PyEval_SliceIndex(obj_end, &end)) + return -2; + + if (PyBytes_Check(subobj)) { + sub = PyBytes_AS_STRING(subobj); + sub_len = PyBytes_GET_SIZE(subobj); + } + 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( + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sub, sub_len, start, end); + else + return stringlib_rfind_slice( + PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + sub, sub_len, start, end); } @@ -1298,10 +1298,10 @@ Return -1 on failure."); static PyObject * bytes_find(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); - if (result == -2) - return NULL; - return PyLong_FromSsize_t(result); + Py_ssize_t result = bytes_find_internal(self, args, +1); + if (result == -2) + return NULL; + return PyLong_FromSsize_t(result); } @@ -1313,15 +1313,15 @@ Like B.find() but raise ValueError when the substring is not found."); static PyObject * bytes_index(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); - if (result == -2) - return NULL; - if (result == -1) { - PyErr_SetString(PyExc_ValueError, - "substring not found"); - return NULL; - } - return PyLong_FromSsize_t(result); + Py_ssize_t result = bytes_find_internal(self, args, +1); + if (result == -2) + return NULL; + if (result == -1) { + PyErr_SetString(PyExc_ValueError, + "substring not found"); + return NULL; + } + return PyLong_FromSsize_t(result); } @@ -1337,10 +1337,10 @@ Return -1 on failure."); static PyObject * bytes_rfind(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); - if (result == -2) - return NULL; - return PyLong_FromSsize_t(result); + Py_ssize_t result = bytes_find_internal(self, args, -1); + if (result == -2) + return NULL; + return PyLong_FromSsize_t(result); } @@ -1352,101 +1352,101 @@ Like B.rfind() but raise ValueError when the substring is not found."); static PyObject * bytes_rindex(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); - if (result == -2) - return NULL; - if (result == -1) { - PyErr_SetString(PyExc_ValueError, - "substring not found"); - return NULL; - } - return PyLong_FromSsize_t(result); + Py_ssize_t result = bytes_find_internal(self, args, -1); + if (result == -2) + return NULL; + if (result == -1) { + PyErr_SetString(PyExc_ValueError, + "substring not found"); + return NULL; + } + return PyLong_FromSsize_t(result); } Py_LOCAL_INLINE(PyObject *) do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) { - Py_buffer vsep; - char *s = PyBytes_AS_STRING(self); - Py_ssize_t len = PyBytes_GET_SIZE(self); - char *sep; - Py_ssize_t seplen; - Py_ssize_t i, j; - - if (_getbuffer(sepobj, &vsep) < 0) - return NULL; - sep = vsep.buf; - seplen = vsep.len; + Py_buffer vsep; + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self); + char *sep; + Py_ssize_t seplen; + Py_ssize_t i, j; - i = 0; - if (striptype != RIGHTSTRIP) { - while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) { - i++; - } - } + if (_getbuffer(sepobj, &vsep) < 0) + return NULL; + sep = vsep.buf; + seplen = vsep.len; + + 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++; - } + j = len; + if (striptype != LEFTSTRIP) { + do { + j--; + } while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen)); + j++; + } - PyBuffer_Release(&vsep); + PyBuffer_Release(&vsep); - if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; - } - else - return PyBytes_FromStringAndSize(s+i, j-i); + if (i == 0 && j == len && PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*)self; + } + else + return PyBytes_FromStringAndSize(s+i, j-i); } Py_LOCAL_INLINE(PyObject *) do_strip(PyBytesObject *self, int striptype) { - char *s = PyBytes_AS_STRING(self); - Py_ssize_t len = PyBytes_GET_SIZE(self), i, j; + char *s = PyBytes_AS_STRING(self); + Py_ssize_t len = PyBytes_GET_SIZE(self), i, j; - i = 0; - if (striptype != RIGHTSTRIP) { - while (i < len && ISSPACE(s[i])) { - i++; - } - } + i = 0; + if (striptype != RIGHTSTRIP) { + while (i < len && ISSPACE(s[i])) { + i++; + } + } - j = len; - if (striptype != LEFTSTRIP) { - do { - j--; - } while (j >= i && ISSPACE(s[j])); - j++; - } + j = len; + if (striptype != LEFTSTRIP) { + do { + j--; + } while (j >= i && ISSPACE(s[j])); + j++; + } - if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; - } - else - return PyBytes_FromStringAndSize(s+i, j-i); + if (i == 0 && j == len && PyBytes_CheckExact(self)) { + Py_INCREF(self); + return (PyObject*)self; + } + else + return PyBytes_FromStringAndSize(s+i, j-i); } Py_LOCAL_INLINE(PyObject *) do_argstrip(PyBytesObject *self, int striptype, PyObject *args) { - PyObject *sep = NULL; + PyObject *sep = NULL; - if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep)) - return NULL; + if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep)) + return NULL; - if (sep != NULL && sep != Py_None) { - return do_xstrip(self, striptype, sep); - } - return do_strip(self, striptype); + if (sep != NULL && sep != Py_None) { + return do_xstrip(self, striptype, sep); + } + return do_strip(self, striptype); } @@ -1458,10 +1458,10 @@ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * bytes_strip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, BOTHSTRIP); /* Common case */ - else - return do_argstrip(self, BOTHSTRIP, args); + if (PyTuple_GET_SIZE(args) == 0) + return do_strip(self, BOTHSTRIP); /* Common case */ + else + return do_argstrip(self, BOTHSTRIP, args); } @@ -1473,10 +1473,10 @@ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * bytes_lstrip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, LEFTSTRIP); /* Common case */ - else - return do_argstrip(self, LEFTSTRIP, args); + if (PyTuple_GET_SIZE(args) == 0) + return do_strip(self, LEFTSTRIP); /* Common case */ + else + return do_argstrip(self, LEFTSTRIP, args); } @@ -1488,10 +1488,10 @@ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * bytes_rstrip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, RIGHTSTRIP); /* Common case */ - else - return do_argstrip(self, RIGHTSTRIP, args); + if (PyTuple_GET_SIZE(args) == 0) + return do_strip(self, RIGHTSTRIP); /* Common case */ + else + return do_argstrip(self, RIGHTSTRIP, args); } @@ -1505,27 +1505,27 @@ as in slice notation."); static PyObject * bytes_count(PyBytesObject *self, PyObject *args) { - PyObject *sub_obj; - const char *str = PyBytes_AS_STRING(self), *sub; - Py_ssize_t sub_len; - Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; + PyObject *sub_obj; + const char *str = PyBytes_AS_STRING(self), *sub; + Py_ssize_t sub_len; + Py_ssize_t start = 0, end = PY_SSIZE_T_MAX; - if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; + if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj, + _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) + return NULL; - if (PyBytes_Check(sub_obj)) { - sub = PyBytes_AS_STRING(sub_obj); - sub_len = PyBytes_GET_SIZE(sub_obj); - } - else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) - return NULL; + if (PyBytes_Check(sub_obj)) { + sub = PyBytes_AS_STRING(sub_obj); + sub_len = PyBytes_GET_SIZE(sub_obj); + } + else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) + return NULL; - ADJUST_INDICES(start, end, PyBytes_GET_SIZE(self)); + ADJUST_INDICES(start, end, PyBytes_GET_SIZE(self)); - return PyLong_FromSsize_t( - stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) - ); + return PyLong_FromSsize_t( + stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX) + ); } @@ -1540,110 +1540,110 @@ table, which must be a bytes object of length 256."); static PyObject * bytes_translate(PyBytesObject *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 (PyBytes_Check(tableobj)) { - table = PyBytes_AS_STRING(tableobj); - tablen = PyBytes_GET_SIZE(tableobj); - } - else if (tableobj == Py_None) { - table = NULL; - tablen = 256; - } - 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 (PyBytes_Check(delobj)) { - del_table = PyBytes_AS_STRING(delobj); - dellen = PyBytes_GET_SIZE(delobj); - } - else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen)) - return NULL; - } - else { - del_table = NULL; - dellen = 0; - } - - inlen = PyBytes_GET_SIZE(input_obj); - result = PyBytes_FromStringAndSize((char *)NULL, inlen); - if (result == NULL) - return NULL; - output_start = output = PyBytes_AsString(result); - input = PyBytes_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 || !PyBytes_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 && PyBytes_CheckExact(input_obj)) { - Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; - } - /* Fix the size of the resulting string */ - if (inlen > 0) - _PyBytes_Resize(&result, output - output_start); - return result; + 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 (PyBytes_Check(tableobj)) { + table = PyBytes_AS_STRING(tableobj); + tablen = PyBytes_GET_SIZE(tableobj); + } + else if (tableobj == Py_None) { + table = NULL; + tablen = 256; + } + 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 (PyBytes_Check(delobj)) { + del_table = PyBytes_AS_STRING(delobj); + dellen = PyBytes_GET_SIZE(delobj); + } + else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen)) + return NULL; + } + else { + del_table = NULL; + dellen = 0; + } + + inlen = PyBytes_GET_SIZE(input_obj); + result = PyBytes_FromStringAndSize((char *)NULL, inlen); + if (result == NULL) + return NULL; + output_start = output = PyBytes_AsString(result); + input = PyBytes_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 || !PyBytes_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 && PyBytes_CheckExact(input_obj)) { + Py_DECREF(result); + Py_INCREF(input_obj); + return input_obj; + } + /* Fix the size of the resulting string */ + if (inlen > 0) + _PyBytes_Resize(&result, output - output_start); + return result; } static PyObject * bytes_maketrans(PyObject *null, PyObject *args) { - return _Py_bytes_maketrans(args); + return _Py_bytes_maketrans(args); } /* find and count characters and substrings */ -#define findchar(target, target_len, c) \ +#define findchar(target, target_len, c) \ ((char *)memchr((const void *)(target), c, target_len)) /* String ops must return a string. */ @@ -1651,29 +1651,29 @@ bytes_maketrans(PyObject *null, PyObject *args) Py_LOCAL(PyBytesObject *) return_self(PyBytesObject *self) { - if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return self; - } - return (PyBytesObject *)PyBytes_FromStringAndSize( - PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self)); + if (PyBytes_CheckExact(self)) { + Py_INCREF(self); + return self; + } + return (PyBytesObject *)PyBytes_FromStringAndSize( + PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self)); } Py_LOCAL_INLINE(Py_ssize_t) countchar(const char *target, int target_len, char c, Py_ssize_t maxcount) { - Py_ssize_t count=0; - const char *start=target; - const char *end=target+target_len; + 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; + while ( (start=findchar(start, end-start, c)) != NULL ) { + count++; + if (count >= maxcount) + break; + start += 1; + } + return count; } @@ -1682,467 +1682,467 @@ countchar(const char *target, int target_len, char c, Py_ssize_t maxcount) /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ Py_LOCAL(PyBytesObject *) replace_interleave(PyBytesObject *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; - PyBytesObject *result; - - self_len = PyBytes_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, - "replacement bytes are too long"); - return NULL; - } - result_len = product + self_len; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replacement bytes are too long"); - return NULL; - } - - if (! (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) ) - return NULL; - - self_s = PyBytes_AS_STRING(self); - result_s = PyBytes_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=1, len(from)==1, to="", maxcount>=1 */ Py_LOCAL(PyBytesObject *) replace_delete_single_character(PyBytesObject *self, - char from_c, Py_ssize_t maxcount) + 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; - PyBytesObject *result; - - self_len = PyBytes_GET_SIZE(self); - self_s = PyBytes_AS_STRING(self); + char *self_s, *result_s; + char *start, *next, *end; + Py_ssize_t self_len, result_len; + Py_ssize_t count; + PyBytesObject *result; - count = countchar(self_s, self_len, from_c, maxcount); - if (count == 0) { - return return_self(self); - } + self_len = PyBytes_GET_SIZE(self); + self_s = PyBytes_AS_STRING(self); - result_len = self_len - count; /* from_len == 1 */ - assert(result_len>=0); + count = countchar(self_s, self_len, from_c, maxcount); + if (count == 0) { + return return_self(self); + } - if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyBytes_AS_STRING(result); + result_len = self_len - count; /* from_len == 1 */ + assert(result_len>=0); - 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); + if ( (result = (PyBytesObject *) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + return NULL; + result_s = PyBytes_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; + return result; } /* len(self)>=1, len(from)>=2, to="", maxcount>=1 */ Py_LOCAL(PyBytesObject *) replace_delete_substring(PyBytesObject *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; - PyBytesObject *result; - - self_len = PyBytes_GET_SIZE(self); - self_s = PyBytes_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 = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL ) - return NULL; - - result_s = PyBytes_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; + 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; + PyBytesObject *result; + + self_len = PyBytes_GET_SIZE(self); + self_s = PyBytes_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 = (PyBytesObject *) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL ) + return NULL; + + result_s = PyBytes_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(PyBytesObject *) replace_single_character_in_place(PyBytesObject *self, - char from_c, char to_c, - Py_ssize_t maxcount) + char from_c, char to_c, + Py_ssize_t maxcount) { - char *self_s, *result_s, *start, *end, *next; - Py_ssize_t self_len; - PyBytesObject *result; + char *self_s, *result_s, *start, *end, *next; + Py_ssize_t self_len; + PyBytesObject *result; - /* The result string will be the same size */ - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_GET_SIZE(self); + /* The result string will be the same size */ + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_GET_SIZE(self); - next = findchar(self_s, self_len, from_c); + 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 = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyBytes_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; + if (next == NULL) { + /* No matches; return the original string */ + return return_self(self); + } - while (--maxcount > 0) { - next = findchar(start, end-start, from_c); - if (next == NULL) - break; - *next = to_c; - start = next+1; - } + /* Need to make a new string */ + result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyBytes_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; + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Py_LOCAL(PyBytesObject *) replace_substring_in_place(PyBytesObject *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; - PyBytesObject *result; - - /* The result string will be the same size */ - - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_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 = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); - if (result == NULL) - return NULL; - result_s = PyBytes_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; + 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; + PyBytesObject *result; + + /* The result string will be the same size */ + + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_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 = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, self_len); + if (result == NULL) + return NULL; + result_s = PyBytes_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(PyBytesObject *) replace_single_character(PyBytesObject *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; - PyBytesObject *result; - - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_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, - "replacement bytes are too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replacment bytes are too long"); - return NULL; - } - - if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyBytes_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; + 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; + PyBytesObject *result; + + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_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, + "replacement bytes are too long"); + return NULL; + } + result_len = self_len + product; + if (result_len < 0) { + PyErr_SetString(PyExc_OverflowError, + "replacment bytes are too long"); + return NULL; + } + + if ( (result = (PyBytesObject *) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + return NULL; + result_s = PyBytes_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(PyBytesObject *) replace_substring(PyBytesObject *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; - PyBytesObject *result; - - self_s = PyBytes_AS_STRING(self); - self_len = PyBytes_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, - "replacement bytes are too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replacement bytes are too long"); - return NULL; - } - - if ( (result = (PyBytesObject *) - PyBytes_FromStringAndSize(NULL, result_len)) == NULL) - return NULL; - result_s = PyBytes_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; + 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; + PyBytesObject *result; + + self_s = PyBytes_AS_STRING(self); + self_len = PyBytes_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, + "replacement bytes are too long"); + return NULL; + } + result_len = self_len + product; + if (result_len < 0) { + PyErr_SetString(PyExc_OverflowError, + "replacement bytes are too long"); + return NULL; + } + + if ( (result = (PyBytesObject *) + PyBytes_FromStringAndSize(NULL, result_len)) == NULL) + return NULL; + result_s = PyBytes_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(PyBytesObject *) replace(PyBytesObject *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 || PyBytes_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 (PyBytes_GET_SIZE(self) == 0) { - return return_self(self); - } - - if (to_len == 0) { - /* delete all occurrences 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); - } + 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 || PyBytes_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 (PyBytes_GET_SIZE(self) == 0) { + return return_self(self); + } + + if (to_len == 0) { + /* delete all occurrences 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__, @@ -2155,31 +2155,31 @@ given, only the first count occurrences are replaced."); static PyObject * bytes_replace(PyBytesObject *self, PyObject *args) { - Py_ssize_t count = -1; - PyObject *from, *to; - const char *from_s, *to_s; - Py_ssize_t from_len, to_len; + 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 (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) + return NULL; - if (PyBytes_Check(from)) { - from_s = PyBytes_AS_STRING(from); - from_len = PyBytes_GET_SIZE(from); - } - else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) - return NULL; + if (PyBytes_Check(from)) { + from_s = PyBytes_AS_STRING(from); + from_len = PyBytes_GET_SIZE(from); + } + else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) + return NULL; - if (PyBytes_Check(to)) { - to_s = PyBytes_AS_STRING(to); - to_len = PyBytes_GET_SIZE(to); - } - else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) - return NULL; + if (PyBytes_Check(to)) { + to_s = PyBytes_AS_STRING(to); + to_len = PyBytes_GET_SIZE(to); + } + else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) + return NULL; - return (PyObject *)replace((PyBytesObject *) self, - from_s, from_len, - to_s, to_len, count); + return (PyObject *)replace((PyBytesObject *) self, + from_s, from_len, + to_s, to_len, count); } /** End DALKE **/ @@ -2190,38 +2190,38 @@ bytes_replace(PyBytesObject *self, PyObject *args) */ Py_LOCAL(int) _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, - Py_ssize_t end, int direction) + Py_ssize_t end, int direction) { - Py_ssize_t len = PyBytes_GET_SIZE(self); - Py_ssize_t slen; - const char* sub; - const char* str; + Py_ssize_t len = PyBytes_GET_SIZE(self); + Py_ssize_t slen; + const char* sub; + const char* str; - if (PyBytes_Check(substr)) { - sub = PyBytes_AS_STRING(substr); - slen = PyBytes_GET_SIZE(substr); - } - else if (PyObject_AsCharBuffer(substr, &sub, &slen)) - return -1; - str = PyBytes_AS_STRING(self); + if (PyBytes_Check(substr)) { + sub = PyBytes_AS_STRING(substr); + slen = PyBytes_GET_SIZE(substr); + } + else if (PyObject_AsCharBuffer(substr, &sub, &slen)) + return -1; + str = PyBytes_AS_STRING(self); - ADJUST_INDICES(start, end, len); + 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 (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; + if (end-slen > start) + start = end - slen; + } + if (end-start >= slen) + return ! memcmp(str+start, sub, slen); + return 0; } @@ -2236,33 +2236,33 @@ prefix can also be a tuple of bytes to try."); static PyObject * bytes_startswith(PyBytesObject *self, PyObject *args) { - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; - int result; - - if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; - if (PyTuple_Check(subobj)) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_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 = _bytes_tailmatch(self, subobj, start, end, -1); - if (result == -1) - return NULL; - else - return PyBool_FromLong(result); + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + PyObject *subobj; + int result; + + if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj, + _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) + return NULL; + if (PyTuple_Check(subobj)) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { + result = _bytes_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 = _bytes_tailmatch(self, subobj, start, end, -1); + if (result == -1) + return NULL; + else + return PyBool_FromLong(result); } @@ -2277,33 +2277,33 @@ suffix can also be a tuple of bytes to try."); static PyObject * bytes_endswith(PyBytesObject *self, PyObject *args) { - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; - int result; - - if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj, - _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) - return NULL; - if (PyTuple_Check(subobj)) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_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 = _bytes_tailmatch(self, subobj, start, end, +1); - if (result == -1) - return NULL; - else - return PyBool_FromLong(result); + Py_ssize_t start = 0; + Py_ssize_t end = PY_SSIZE_T_MAX; + PyObject *subobj; + int result; + + if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj, + _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end)) + return NULL; + if (PyTuple_Check(subobj)) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { + result = _bytes_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 = _bytes_tailmatch(self, subobj, start, end, +1); + if (result == -1) + return NULL; + else + return PyBool_FromLong(result); } @@ -2320,15 +2320,15 @@ able to handle UnicodeDecodeErrors."); static PyObject * bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) { - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; + 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) - encoding = PyUnicode_GetDefaultEncoding(); - return PyUnicode_FromEncodedObject(self, encoding, errors); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) + return NULL; + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); + return PyUnicode_FromEncodedObject(self, encoding, errors); } @@ -2345,12 +2345,12 @@ bytes_splitlines(PyObject *self, PyObject *args) int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self), keepends - ); + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); } @@ -2364,61 +2364,61 @@ Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'."); static int hex_digit_to_int(Py_UNICODE c) { - if (c >= 128) - return -1; - if (ISDIGIT(c)) - return c - '0'; - else { - if (ISUPPER(c)) - c = TOLOWER(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - } - return -1; + if (c >= 128) + return -1; + if (ISDIGIT(c)) + return c - '0'; + else { + if (ISUPPER(c)) + c = TOLOWER(c); + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + } + return -1; } static PyObject * bytes_fromhex(PyObject *cls, PyObject *args) { - PyObject *newstring, *hexobj; - char *buf; - Py_UNICODE *hex; - Py_ssize_t hexlen, byteslen, i, j; - int top, bot; - - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) - return NULL; - assert(PyUnicode_Check(hexobj)); - hexlen = PyUnicode_GET_SIZE(hexobj); - hex = PyUnicode_AS_UNICODE(hexobj); - byteslen = hexlen/2; /* This overestimates if there are spaces */ - newstring = PyBytes_FromStringAndSize(NULL, byteslen); - if (!newstring) - return NULL; - buf = PyBytes_AS_STRING(newstring); - 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 (j != byteslen && _PyBytes_Resize(&newstring, j) < 0) - goto error; - return newstring; + PyObject *newstring, *hexobj; + char *buf; + Py_UNICODE *hex; + Py_ssize_t hexlen, byteslen, i, j; + int top, bot; + + if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) + return NULL; + assert(PyUnicode_Check(hexobj)); + hexlen = PyUnicode_GET_SIZE(hexobj); + hex = PyUnicode_AS_UNICODE(hexobj); + byteslen = hexlen/2; /* This overestimates if there are spaces */ + newstring = PyBytes_FromStringAndSize(NULL, byteslen); + if (!newstring) + return NULL; + buf = PyBytes_AS_STRING(newstring); + 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 (j != byteslen && _PyBytes_Resize(&newstring, j) < 0) + goto error; + return newstring; error: - Py_XDECREF(newstring); - return NULL; + Py_XDECREF(newstring); + return NULL; } PyDoc_STRVAR(sizeof__doc__, @@ -2427,80 +2427,80 @@ PyDoc_STRVAR(sizeof__doc__, static PyObject * bytes_sizeof(PyBytesObject *v) { - Py_ssize_t res; - res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; - return PyLong_FromSsize_t(res); + Py_ssize_t res; + res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; + return PyLong_FromSsize_t(res); } static PyObject * bytes_getnewargs(PyBytesObject *v) { - return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); + return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); } static PyMethodDef bytes_methods[] = { - {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, - {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, - _Py_capitalize__doc__}, - {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, - {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, - endswith__doc__}, - {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, - expandtabs__doc__}, - {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, - {"index", (PyCFunction)bytes_index, METH_VARARGS, index__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)bytes_join, METH_O, join__doc__}, - {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, - {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, - {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, - {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, - rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, - {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS, - splitlines__doc__}, - {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, - startswith__doc__}, - {"strip", (PyCFunction)bytes_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)bytes_translate, METH_VARARGS, - translate__doc__}, - {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, - {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, - sizeof__doc__}, - {NULL, NULL} /* sentinel */ + {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, + {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, + _Py_capitalize__doc__}, + {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, + {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, + {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, + endswith__doc__}, + {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, + expandtabs__doc__}, + {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, + fromhex_doc}, + {"index", (PyCFunction)bytes_index, METH_VARARGS, index__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)bytes_join, METH_O, join__doc__}, + {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, + {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, + {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, + _Py_maketrans__doc__}, + {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, + {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, + {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, + {"rpartition", (PyCFunction)bytes_rpartition, METH_O, + rpartition__doc__}, + {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, + {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS, + splitlines__doc__}, + {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, + startswith__doc__}, + {"strip", (PyCFunction)bytes_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)bytes_translate, METH_VARARGS, + translate__doc__}, + {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, + {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, + sizeof__doc__}, + {NULL, NULL} /* sentinel */ }; static PyObject * @@ -2509,236 +2509,236 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *x = NULL; - const char *encoding = NULL; - const char *errors = NULL; - PyObject *new = NULL; - Py_ssize_t size; - static char *kwlist[] = {"source", "encoding", "errors", 0}; - - if (type != &PyBytes_Type) - return str_subtype_new(type, args, kwds); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, - &encoding, &errors)) - return NULL; - if (x == NULL) { - if (encoding != NULL || errors != NULL) { - PyErr_SetString(PyExc_TypeError, - "encoding or errors without sequence " - "argument"); - return NULL; - } - return PyBytes_FromString(""); - } - - if (PyUnicode_Check(x)) { - /* Encode via the codec registry */ - if (encoding == NULL) { - PyErr_SetString(PyExc_TypeError, - "string argument without an encoding"); - return NULL; - } - new = PyUnicode_AsEncodedString(x, encoding, errors); - if (new == NULL) - return NULL; - assert(PyBytes_Check(new)); - return new; - } - /* Is it an integer? */ - size = PyNumber_AsSsize_t(x, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - else if (size < 0) { - PyErr_SetString(PyExc_ValueError, "negative count"); - return NULL; - } - else { - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) { - return NULL; - } - if (size > 0) { - memset(((PyBytesObject*)new)->ob_sval, 0, size); - } - return new; - } - - /* 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 NULL; - } - return PyObject_Bytes(x); + PyObject *x = NULL; + const char *encoding = NULL; + const char *errors = NULL; + PyObject *new = NULL; + Py_ssize_t size; + static char *kwlist[] = {"source", "encoding", "errors", 0}; + + if (type != &PyBytes_Type) + return str_subtype_new(type, args, kwds); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, + &encoding, &errors)) + return NULL; + if (x == NULL) { + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + "encoding or errors without sequence " + "argument"); + return NULL; + } + return PyBytes_FromString(""); + } + + if (PyUnicode_Check(x)) { + /* Encode via the codec registry */ + if (encoding == NULL) { + PyErr_SetString(PyExc_TypeError, + "string argument without an encoding"); + return NULL; + } + new = PyUnicode_AsEncodedString(x, encoding, errors); + if (new == NULL) + return NULL; + assert(PyBytes_Check(new)); + return new; + } + /* Is it an integer? */ + size = PyNumber_AsSsize_t(x, PyExc_OverflowError); + if (size == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + else if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + else { + new = PyBytes_FromStringAndSize(NULL, size); + if (new == NULL) { + return NULL; + } + if (size > 0) { + memset(((PyBytesObject*)new)->ob_sval, 0, size); + } + return new; + } + + /* 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 NULL; + } + return PyObject_Bytes(x); } PyObject * PyBytes_FromObject(PyObject *x) { - PyObject *new, *it; - Py_ssize_t i, size; - - if (x == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - /* Use the modern buffer interface */ - if (PyObject_CheckBuffer(x)) { - Py_buffer view; - if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) - return NULL; - new = PyBytes_FromStringAndSize(NULL, view.len); - if (!new) - goto fail; - /* XXX(brett.cannon): Better way to get to internal buffer? */ - if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval, - &view, view.len, 'C') < 0) - goto fail; - PyBuffer_Release(&view); - return new; - fail: - Py_XDECREF(new); - PyBuffer_Release(&view); - return NULL; - } - if (PyUnicode_Check(x)) { - PyErr_SetString(PyExc_TypeError, - "cannot convert unicode object to bytes"); - return NULL; - } - - if (PyList_CheckExact(x)) { - new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); - if (new == NULL) - return NULL; - for (i = 0; i < Py_SIZE(x); i++) { - Py_ssize_t value = PyNumber_AsSsize_t( - PyList_GET_ITEM(x, i), PyExc_ValueError); - if (value == -1 && PyErr_Occurred()) { - Py_DECREF(new); - return NULL; - } - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - Py_DECREF(new); - return NULL; - } - ((PyBytesObject *)new)->ob_sval[i] = value; - } - return new; - } - if (PyTuple_CheckExact(x)) { - new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); - if (new == NULL) - return NULL; - for (i = 0; i < Py_SIZE(x); i++) { - Py_ssize_t value = PyNumber_AsSsize_t( - PyTuple_GET_ITEM(x, i), PyExc_ValueError); - if (value == -1 && PyErr_Occurred()) { - Py_DECREF(new); - return NULL; - } - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - Py_DECREF(new); - return NULL; - } - ((PyBytesObject *)new)->ob_sval[i] = value; - } - return new; - } - - /* For iterator version, create a string object and resize as needed */ - size = _PyObject_LengthHint(x, 64); - if (size == -1 && PyErr_Occurred()) - return NULL; - /* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from - returning a shared empty bytes string. This required because we - want to call _PyBytes_Resize() the returned object, which we can - only do on bytes objects with refcount == 1. */ - size += 1; - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) - return NULL; - - /* Get the iterator */ - it = PyObject_GetIter(x); - if (it == NULL) - goto error; - - /* Run the iterator to exhaustion */ - for (i = 0; ; i++) { - PyObject *item; - Py_ssize_t value; - - /* Get the next item */ - item = PyIter_Next(it); - if (item == NULL) { - if (PyErr_Occurred()) - goto error; - break; - } - - /* Interpret it as an int (__index__) */ - value = PyNumber_AsSsize_t(item, PyExc_ValueError); - Py_DECREF(item); - if (value == -1 && PyErr_Occurred()) - goto error; - - /* Range check */ - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - goto error; - } - - /* Append the byte */ - if (i >= size) { - size = 2 * size + 1; - if (_PyBytes_Resize(&new, size) < 0) - goto error; - } - ((PyBytesObject *)new)->ob_sval[i] = value; - } - _PyBytes_Resize(&new, i); - - /* Clean up and return success */ - Py_DECREF(it); - return new; + PyObject *new, *it; + Py_ssize_t i, size; + + if (x == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + /* Use the modern buffer interface */ + if (PyObject_CheckBuffer(x)) { + Py_buffer view; + if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) + return NULL; + new = PyBytes_FromStringAndSize(NULL, view.len); + if (!new) + goto fail; + /* XXX(brett.cannon): Better way to get to internal buffer? */ + if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval, + &view, view.len, 'C') < 0) + goto fail; + PyBuffer_Release(&view); + return new; + fail: + Py_XDECREF(new); + PyBuffer_Release(&view); + return NULL; + } + if (PyUnicode_Check(x)) { + PyErr_SetString(PyExc_TypeError, + "cannot convert unicode object to bytes"); + return NULL; + } + + if (PyList_CheckExact(x)) { + new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); + if (new == NULL) + return NULL; + for (i = 0; i < Py_SIZE(x); i++) { + Py_ssize_t value = PyNumber_AsSsize_t( + PyList_GET_ITEM(x, i), PyExc_ValueError); + if (value == -1 && PyErr_Occurred()) { + Py_DECREF(new); + return NULL; + } + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + Py_DECREF(new); + return NULL; + } + ((PyBytesObject *)new)->ob_sval[i] = value; + } + return new; + } + if (PyTuple_CheckExact(x)) { + new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); + if (new == NULL) + return NULL; + for (i = 0; i < Py_SIZE(x); i++) { + Py_ssize_t value = PyNumber_AsSsize_t( + PyTuple_GET_ITEM(x, i), PyExc_ValueError); + if (value == -1 && PyErr_Occurred()) { + Py_DECREF(new); + return NULL; + } + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + Py_DECREF(new); + return NULL; + } + ((PyBytesObject *)new)->ob_sval[i] = value; + } + return new; + } + + /* For iterator version, create a string object and resize as needed */ + size = _PyObject_LengthHint(x, 64); + if (size == -1 && PyErr_Occurred()) + return NULL; + /* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from + returning a shared empty bytes string. This required because we + want to call _PyBytes_Resize() the returned object, which we can + only do on bytes objects with refcount == 1. */ + size += 1; + new = PyBytes_FromStringAndSize(NULL, size); + if (new == NULL) + return NULL; + + /* Get the iterator */ + it = PyObject_GetIter(x); + if (it == NULL) + goto error; + + /* Run the iterator to exhaustion */ + for (i = 0; ; i++) { + PyObject *item; + Py_ssize_t value; + + /* Get the next item */ + item = PyIter_Next(it); + if (item == NULL) { + if (PyErr_Occurred()) + goto error; + break; + } + + /* Interpret it as an int (__index__) */ + value = PyNumber_AsSsize_t(item, PyExc_ValueError); + Py_DECREF(item); + if (value == -1 && PyErr_Occurred()) + goto error; + + /* Range check */ + if (value < 0 || value >= 256) { + PyErr_SetString(PyExc_ValueError, + "bytes must be in range(0, 256)"); + goto error; + } + + /* Append the byte */ + if (i >= size) { + size = 2 * size + 1; + if (_PyBytes_Resize(&new, size) < 0) + goto error; + } + ((PyBytesObject *)new)->ob_sval[i] = value; + } + _PyBytes_Resize(&new, i); + + /* Clean up and return success */ + Py_DECREF(it); + return new; error: - /* Error handling when new != NULL */ - Py_XDECREF(it); - Py_DECREF(new); - return NULL; + /* Error handling when new != NULL */ + Py_XDECREF(it); + Py_DECREF(new); + return NULL; } static PyObject * str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *tmp, *pnew; - Py_ssize_t n; - - assert(PyType_IsSubtype(type, &PyBytes_Type)); - tmp = bytes_new(&PyBytes_Type, args, kwds); - if (tmp == NULL) - return NULL; - assert(PyBytes_CheckExact(tmp)); - n = PyBytes_GET_SIZE(tmp); - pnew = type->tp_alloc(type, n); - if (pnew != NULL) { - Py_MEMCPY(PyBytes_AS_STRING(pnew), - PyBytes_AS_STRING(tmp), n+1); - ((PyBytesObject *)pnew)->ob_shash = - ((PyBytesObject *)tmp)->ob_shash; - } - Py_DECREF(tmp); - return pnew; + PyObject *tmp, *pnew; + Py_ssize_t n; + + assert(PyType_IsSubtype(type, &PyBytes_Type)); + tmp = bytes_new(&PyBytes_Type, args, kwds); + if (tmp == NULL) + return NULL; + assert(PyBytes_CheckExact(tmp)); + n = PyBytes_GET_SIZE(tmp); + pnew = type->tp_alloc(type, n); + if (pnew != NULL) { + Py_MEMCPY(PyBytes_AS_STRING(pnew), + PyBytes_AS_STRING(tmp), n+1); + ((PyBytesObject *)pnew)->ob_shash = + ((PyBytesObject *)tmp)->ob_shash; + } + Py_DECREF(tmp); + return pnew; } PyDoc_STRVAR(bytes_doc, @@ -2756,70 +2756,70 @@ Construct an immutable array of bytes from:\n\ static PyObject *bytes_iter(PyObject *seq); PyTypeObject PyBytes_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytes", - PyBytesObject_SIZE, - sizeof(char), - bytes_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)bytes_repr, /* tp_repr */ - 0, /* tp_as_number */ - &bytes_as_sequence, /* tp_as_sequence */ - &bytes_as_mapping, /* tp_as_mapping */ - (hashfunc)bytes_hash, /* tp_hash */ - 0, /* tp_call */ - bytes_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &bytes_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_BYTES_SUBCLASS, /* tp_flags */ - bytes_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)bytes_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - bytes_iter, /* tp_iter */ - 0, /* tp_iternext */ - bytes_methods, /* 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 */ - bytes_new, /* tp_new */ - PyObject_Del, /* tp_free */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytes", + PyBytesObject_SIZE, + sizeof(char), + bytes_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)bytes_repr, /* tp_repr */ + 0, /* tp_as_number */ + &bytes_as_sequence, /* tp_as_sequence */ + &bytes_as_mapping, /* tp_as_mapping */ + (hashfunc)bytes_hash, /* tp_hash */ + 0, /* tp_call */ + bytes_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &bytes_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_BYTES_SUBCLASS, /* tp_flags */ + bytes_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)bytes_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + bytes_iter, /* tp_iter */ + 0, /* tp_iternext */ + bytes_methods, /* 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 */ + bytes_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; void PyBytes_Concat(register PyObject **pv, register PyObject *w) { - register PyObject *v; - assert(pv != NULL); - if (*pv == NULL) - return; - if (w == NULL) { - Py_DECREF(*pv); - *pv = NULL; - return; - } - v = bytes_concat(*pv, w); - Py_DECREF(*pv); - *pv = v; + register PyObject *v; + assert(pv != NULL); + if (*pv == NULL) + return; + if (w == NULL) { + Py_DECREF(*pv); + *pv = NULL; + return; + } + v = bytes_concat(*pv, w); + Py_DECREF(*pv); + *pv = v; } void PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w) { - PyBytes_Concat(pv, w); - Py_XDECREF(w); + PyBytes_Concat(pv, w); + Py_XDECREF(w); } @@ -2840,31 +2840,31 @@ PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w) int _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) { - register PyObject *v; - register PyBytesObject *sv; - v = *pv; - if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) { - *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, PyBytesObject_SIZE + newsize); - if (*pv == NULL) { - PyObject_Del(v); - PyErr_NoMemory(); - return -1; - } - _Py_NewReference(*pv); - sv = (PyBytesObject *) *pv; - Py_SIZE(sv) = newsize; - sv->ob_sval[newsize] = '\0'; - sv->ob_shash = -1; /* invalidate cached hash value */ - return 0; + register PyObject *v; + register PyBytesObject *sv; + v = *pv; + if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) { + *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, PyBytesObject_SIZE + newsize); + if (*pv == NULL) { + PyObject_Del(v); + PyErr_NoMemory(); + return -1; + } + _Py_NewReference(*pv); + sv = (PyBytesObject *) *pv; + Py_SIZE(sv) = newsize; + sv->ob_sval[newsize] = '\0'; + sv->ob_shash = -1; /* invalidate cached hash value */ + return 0; } /* _PyBytes_FormatLong emulates the format codes d, u, o, x and X, and @@ -2880,262 +2880,262 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) * 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 + * 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* _PyBytes_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; - - /* Avoid exceeding SSIZE_T_MAX */ - if (prec > INT_MAX-3) { - PyErr_SetString(PyExc_OverflowError, - "precision too large"); - return NULL; - } - - switch (type) { - case 'd': - case 'u': - /* Special-case boolean: we want 0/1 */ - if (PyBool_Check(val)) - result = PyNumber_ToBase(val, 10); - else - result = Py_TYPE(val)->tp_str(val); - break; - case 'o': - numnondigits = 2; - result = PyNumber_ToBase(val, 8); - break; - case 'x': - case 'X': - numnondigits = 2; - result = PyNumber_ToBase(val, 16); - break; - default: - assert(!"'type' not in [duoxX]"); - } - if (!result) - return NULL; - - buf = _PyUnicode_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 = PyUnicode_GetSize(result); - if (llen > INT_MAX) { - PyErr_SetString(PyExc_ValueError, - "string too large in _PyBytes_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 && - (type == 'o' || type == 'x' || type == 'X'))) { - assert(buf[sign] == '0'); - assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || - buf[sign+1] == 'o'); - numnondigits -= 2; - buf += 2; - len -= 2; - if (sign) - buf[0] = '-'; - assert(len == numnondigits + numdigits); - assert(numdigits > 0); - } - - /* Fill with leading zeroes to meet minimum width. */ - if (prec > numdigits) { - PyObject *r1 = PyBytes_FromStringAndSize(NULL, - numnondigits + prec); - char *b1; - if (!r1) { - Py_DECREF(result); - return NULL; - } - b1 = PyBytes_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 = PyBytes_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; + 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; + + /* Avoid exceeding SSIZE_T_MAX */ + if (prec > INT_MAX-3) { + PyErr_SetString(PyExc_OverflowError, + "precision too large"); + return NULL; + } + + switch (type) { + case 'd': + case 'u': + /* Special-case boolean: we want 0/1 */ + if (PyBool_Check(val)) + result = PyNumber_ToBase(val, 10); + else + result = Py_TYPE(val)->tp_str(val); + break; + case 'o': + numnondigits = 2; + result = PyNumber_ToBase(val, 8); + break; + case 'x': + case 'X': + numnondigits = 2; + result = PyNumber_ToBase(val, 16); + break; + default: + assert(!"'type' not in [duoxX]"); + } + if (!result) + return NULL; + + buf = _PyUnicode_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 = PyUnicode_GetSize(result); + if (llen > INT_MAX) { + PyErr_SetString(PyExc_ValueError, + "string too large in _PyBytes_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 && + (type == 'o' || type == 'x' || type == 'X'))) { + assert(buf[sign] == '0'); + assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || + buf[sign+1] == 'o'); + numnondigits -= 2; + buf += 2; + len -= 2; + if (sign) + buf[0] = '-'; + assert(len == numnondigits + numdigits); + assert(numdigits > 0); + } + + /* Fill with leading zeroes to meet minimum width. */ + if (prec > numdigits) { + PyObject *r1 = PyBytes_FromStringAndSize(NULL, + numnondigits + prec); + char *b1; + if (!r1) { + Py_DECREF(result); + return NULL; + } + b1 = PyBytes_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 = PyBytes_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; } void PyBytes_Fini(void) { - int i; - for (i = 0; i < UCHAR_MAX + 1; i++) { - Py_XDECREF(characters[i]); - characters[i] = NULL; - } - Py_XDECREF(nullstring); - nullstring = NULL; + int i; + for (i = 0; i < UCHAR_MAX + 1; i++) { + Py_XDECREF(characters[i]); + characters[i] = NULL; + } + Py_XDECREF(nullstring); + nullstring = NULL; } /*********************** Bytes Iterator ****************************/ typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ + PyObject_HEAD + Py_ssize_t it_index; + PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ } striterobject; static void striter_dealloc(striterobject *it) { - _PyObject_GC_UNTRACK(it); - Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); + _PyObject_GC_UNTRACK(it); + Py_XDECREF(it->it_seq); + PyObject_GC_Del(it); } static int striter_traverse(striterobject *it, visitproc visit, void *arg) { - Py_VISIT(it->it_seq); - return 0; + Py_VISIT(it->it_seq); + return 0; } static PyObject * striter_next(striterobject *it) { - PyBytesObject *seq; - PyObject *item; - - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyBytes_Check(seq)); + PyBytesObject *seq; + PyObject *item; - if (it->it_index < PyBytes_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)seq->ob_sval[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; - } + assert(it != NULL); + seq = it->it_seq; + if (seq == NULL) + return NULL; + assert(PyBytes_Check(seq)); + + if (it->it_index < PyBytes_GET_SIZE(seq)) { + item = PyLong_FromLong( + (unsigned char)seq->ob_sval[it->it_index]); + if (item != NULL) + ++it->it_index; + return item; + } - Py_DECREF(seq); - it->it_seq = NULL; - return NULL; + Py_DECREF(seq); + it->it_seq = NULL; + return NULL; } static PyObject * striter_len(striterobject *it) { - Py_ssize_t len = 0; - if (it->it_seq) - len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; - return PyLong_FromSsize_t(len); + Py_ssize_t len = 0; + if (it->it_seq) + len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; + return PyLong_FromSsize_t(len); } PyDoc_STRVAR(length_hint_doc, - "Private method returning an estimate of len(list(it))."); + "Private method returning an estimate of len(list(it))."); static PyMethodDef striter_methods[] = { - {"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, - length_hint_doc}, - {NULL, NULL} /* sentinel */ + {"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, + length_hint_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyBytesIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "bytes_iterator", /* tp_name */ - sizeof(striterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)striter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 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)striter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)striter_next, /* tp_iternext */ - striter_methods, /* tp_methods */ - 0, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "bytes_iterator", /* tp_name */ + sizeof(striterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)striter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 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)striter_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)striter_next, /* tp_iternext */ + striter_methods, /* tp_methods */ + 0, }; static PyObject * bytes_iter(PyObject *seq) { - striterobject *it; - - if (!PyBytes_Check(seq)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_GC_New(striterobject, &PyBytesIter_Type); - if (it == NULL) - return NULL; - it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; - _PyObject_GC_TRACK(it); - return (PyObject *)it; + striterobject *it; + + if (!PyBytes_Check(seq)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_GC_New(striterobject, &PyBytesIter_Type); + if (it == NULL) + return NULL; + it->it_index = 0; + Py_INCREF(seq); + it->it_seq = (PyBytesObject *)seq; + _PyObject_GC_TRACK(it); + return (PyObject *)it; } diff --git a/Objects/cellobject.c b/Objects/cellobject.c index d7908de907..eb5ad98e68 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -5,50 +5,50 @@ PyObject * PyCell_New(PyObject *obj) { - PyCellObject *op; + PyCellObject *op; - op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); - if (op == NULL) - return NULL; - op->ob_ref = obj; - Py_XINCREF(obj); + 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_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); + 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; + 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); + _PyObject_GC_UNTRACK(op); + Py_XDECREF(op->ob_ref); + PyObject_GC_Del(op); } #define TEST_COND(cond) ((cond) ? Py_True : Py_False) @@ -56,124 +56,124 @@ cell_dealloc(PyCellObject *op) static PyObject * cell_richcompare(PyObject *a, PyObject *b, int op) { - int result; - PyObject *v; - - /* neither argument should be NULL, unless something's gone wrong */ - assert(a != NULL && b != NULL); - - /* both arguments should be instances of PyCellObject */ - if (!PyCell_Check(a) || !PyCell_Check(b)) { - v = Py_NotImplemented; - Py_INCREF(v); - return v; - } - - /* compare cells by contents; empty cells come before anything else */ - a = ((PyCellObject *)a)->ob_ref; - b = ((PyCellObject *)b)->ob_ref; - if (a != NULL && b != NULL) - return PyObject_RichCompare(a, b, op); - - result = (b == NULL) - (a == NULL); - switch (op) { - case Py_EQ: - v = TEST_COND(result == 0); - break; - case Py_NE: - v = TEST_COND(result != 0); - break; - case Py_LE: - v = TEST_COND(result <= 0); - break; - case Py_GE: - v = TEST_COND(result >= 0); - break; - case Py_LT: - v = TEST_COND(result < 0); - break; - case Py_GT: - v = TEST_COND(result > 0); - break; - default: - PyErr_BadArgument(); - return NULL; - } - Py_INCREF(v); - return v; + int result; + PyObject *v; + + /* neither argument should be NULL, unless something's gone wrong */ + assert(a != NULL && b != NULL); + + /* both arguments should be instances of PyCellObject */ + if (!PyCell_Check(a) || !PyCell_Check(b)) { + v = Py_NotImplemented; + Py_INCREF(v); + return v; + } + + /* compare cells by contents; empty cells come before anything else */ + a = ((PyCellObject *)a)->ob_ref; + b = ((PyCellObject *)b)->ob_ref; + if (a != NULL && b != NULL) + return PyObject_RichCompare(a, b, op); + + result = (b == NULL) - (a == NULL); + switch (op) { + case Py_EQ: + v = TEST_COND(result == 0); + break; + case Py_NE: + v = TEST_COND(result != 0); + break; + case Py_LE: + v = TEST_COND(result <= 0); + break; + case Py_GE: + v = TEST_COND(result >= 0); + break; + case Py_LT: + v = TEST_COND(result < 0); + break; + case Py_GT: + v = TEST_COND(result > 0); + break; + default: + PyErr_BadArgument(); + return NULL; + } + Py_INCREF(v); + return v; } static PyObject * cell_repr(PyCellObject *op) { - if (op->ob_ref == NULL) - return PyUnicode_FromFormat("", op); + if (op->ob_ref == NULL) + return PyUnicode_FromFormat("", op); - return PyUnicode_FromFormat("", - op, op->ob_ref->ob_type->tp_name, - op->ob_ref); + return PyUnicode_FromFormat("", + 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; + Py_VISIT(op->ob_ref); + return 0; } static int cell_clear(PyCellObject *op) { - Py_CLEAR(op->ob_ref); - return 0; + 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; + 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 */ + {"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 */ - 0, /* tp_reserved */ - (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 */ - cell_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - cell_getsetlist, /* tp_getset */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "cell", + sizeof(PyCellObject), + 0, + (destructor)cell_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + cell_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + cell_getsetlist, /* tp_getset */ }; diff --git a/Objects/classobject.c b/Objects/classobject.c index cb78d159e6..afd4ec3dc6 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -17,21 +17,21 @@ static int numfree = 0; PyObject * PyMethod_Function(PyObject *im) { - if (!PyMethod_Check(im)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyMethodObject *)im)->im_func; + 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; + if (!PyMethod_Check(im)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyMethodObject *)im)->im_self; } /* Method objects are used for bound instance methods returned by @@ -42,29 +42,29 @@ PyMethod_Self(PyObject *im) PyObject * PyMethod_New(PyObject *func, PyObject *self) { - register PyMethodObject *im; - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - 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; - _PyObject_GC_TRACK(im); - return (PyObject *)im; + register PyMethodObject *im; + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + 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; + _PyObject_GC_TRACK(im); + return (PyObject *)im; } /* Descriptors for PyMethod attributes */ @@ -74,11 +74,11 @@ PyMethod_New(PyObject *func, PyObject *self) #define MO_OFF(x) offsetof(PyMethodObject, x) static PyMemberDef method_memberlist[] = { - {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED, - "the function (or other callable) implementing a method"}, - {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED, - "the instance to which a method is bound"}, - {NULL} /* Sentinel */ + {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED, + "the function (or other callable) implementing a method"}, + {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED, + "the instance to which a method is bound"}, + {NULL} /* Sentinel */ }; /* Christian Tismer argued convincingly that method attributes should @@ -89,46 +89,46 @@ static PyMemberDef method_memberlist[] = { static PyObject * method_get_doc(PyMethodObject *im, void *context) { - static PyObject *docstr; - if (docstr == NULL) { - docstr= PyUnicode_InternFromString("__doc__"); - if (docstr == NULL) - return NULL; - } - return PyObject_GetAttr(im->im_func, docstr); + static PyObject *docstr; + if (docstr == NULL) { + docstr= PyUnicode_InternFromString("__doc__"); + if (docstr == NULL) + return NULL; + } + return PyObject_GetAttr(im->im_func, docstr); } static PyGetSetDef method_getset[] = { - {"__doc__", (getter)method_get_doc, NULL, NULL}, - {0} + {"__doc__", (getter)method_get_doc, NULL, NULL}, + {0} }; static PyObject * method_getattro(PyObject *obj, PyObject *name) { - PyMethodObject *im = (PyMethodObject *)obj; - PyTypeObject *tp = obj->ob_type; - PyObject *descr = NULL; - - { - 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); + PyMethodObject *im = (PyMethodObject *)obj; + PyTypeObject *tp = obj->ob_type; + PyObject *descr = NULL; + + { + 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(method_doc, @@ -139,241 +139,241 @@ Create a bound instance method object."); static PyObject * method_new(PyTypeObject* type, PyObject* args, PyObject *kw) { - PyObject *func; - PyObject *self; - - if (!_PyArg_NoKeywords("method", kw)) - return NULL; - if (!PyArg_UnpackTuple(args, "method", 2, 2, - &func, &self)) - return NULL; - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "first argument must be callable"); - return NULL; - } - if (self == NULL || self == Py_None) { - PyErr_SetString(PyExc_TypeError, - "self must not be None"); - return NULL; - } - - return PyMethod_New(func, self); + PyObject *func; + PyObject *self; + + if (!_PyArg_NoKeywords("method", kw)) + return NULL; + if (!PyArg_UnpackTuple(args, "method", 2, 2, + &func, &self)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return NULL; + } + if (self == NULL || self == Py_None) { + PyErr_SetString(PyExc_TypeError, + "self must not be None"); + return NULL; + } + + return PyMethod_New(func, self); } static void method_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); - if (numfree < PyMethod_MAXFREELIST) { - im->im_self = (PyObject *)free_list; - free_list = im; - numfree++; - } - else { - PyObject_GC_Del(im); - } + _PyObject_GC_UNTRACK(im); + if (im->im_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)im); + Py_DECREF(im->im_func); + Py_XDECREF(im->im_self); + if (numfree < PyMethod_MAXFREELIST) { + im->im_self = (PyObject *)free_list; + free_list = im; + numfree++; + } + else { + PyObject_GC_Del(im); + } } static PyObject * method_richcompare(PyObject *self, PyObject *other, int op) { - PyMethodObject *a, *b; - PyObject *res; - int eq; - - if ((op != Py_EQ && op != Py_NE) || - !PyMethod_Check(self) || - !PyMethod_Check(other)) - { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - a = (PyMethodObject *)self; - b = (PyMethodObject *)other; - eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); - if (eq == 1) { - if (a->im_self == NULL || b->im_self == NULL) - eq = a->im_self == b->im_self; - else - eq = PyObject_RichCompareBool(a->im_self, b->im_self, - Py_EQ); - } - if (eq < 0) - return NULL; - if (op == Py_EQ) - res = eq ? Py_True : Py_False; - else - res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + PyMethodObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !PyMethod_Check(self) || + !PyMethod_Check(other)) + { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + a = (PyMethodObject *)self; + b = (PyMethodObject *)other; + eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); + if (eq == 1) { + if (a->im_self == NULL || b->im_self == NULL) + eq = a->im_self == b->im_self; + else + eq = PyObject_RichCompareBool(a->im_self, b->im_self, + Py_EQ); + } + if (eq < 0) + return NULL; + if (op == Py_EQ) + res = eq ? Py_True : Py_False; + else + res = eq ? Py_False : Py_True; + Py_INCREF(res); + return res; } static PyObject * method_repr(PyMethodObject *a) { - PyObject *self = a->im_self; - PyObject *func = a->im_func; - PyObject *klass = (PyObject*)Py_TYPE(self); - PyObject *funcname = NULL ,*klassname = NULL, *result = NULL; - char *defname = "?"; - - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - funcname = PyObject_GetAttrString(func, "__name__"); - if (funcname == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - return NULL; - PyErr_Clear(); - } - else if (!PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; - } - - 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 (!PyUnicode_Check(klassname)) { - Py_DECREF(klassname); - klassname = NULL; - } - } - - /* XXX Shouldn't use repr()/%R here! */ - result = PyUnicode_FromFormat("", - klassname, defname, - funcname, defname, self); - - Py_XDECREF(funcname); - Py_XDECREF(klassname); - return result; + PyObject *self = a->im_self; + PyObject *func = a->im_func; + PyObject *klass = (PyObject*)Py_TYPE(self); + PyObject *funcname = NULL ,*klassname = NULL, *result = NULL; + char *defname = "?"; + + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + funcname = PyObject_GetAttrString(func, "__name__"); + if (funcname == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return NULL; + PyErr_Clear(); + } + else if (!PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; + } + + 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 (!PyUnicode_Check(klassname)) { + Py_DECREF(klassname); + klassname = NULL; + } + } + + /* XXX Shouldn't use repr()/%R here! */ + result = PyUnicode_FromFormat("", + klassname, defname, + funcname, defname, self); + + Py_XDECREF(funcname); + Py_XDECREF(klassname); + return result; } static long method_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; + 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 method_traverse(PyMethodObject *im, visitproc visit, void *arg) { - Py_VISIT(im->im_func); - Py_VISIT(im->im_self); - return 0; + Py_VISIT(im->im_func); + Py_VISIT(im->im_self); + return 0; } static PyObject * method_call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *self = PyMethod_GET_SELF(func); - PyObject *result; - - func = PyMethod_GET_FUNCTION(func); - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - 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; + PyObject *self = PyMethod_GET_SELF(func); + PyObject *result; + + func = PyMethod_GET_FUNCTION(func); + if (self == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + 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 * method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) { - /* Don't rebind an already bound 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; - } - /* Bind it to obj */ - return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj); + /* Don't rebind an already bound 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; + } + /* Bind it to obj */ + return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj); } PyTypeObject PyMethod_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "method", - sizeof(PyMethodObject), - 0, - (destructor)method_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)method_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)method_hash, /* tp_hash */ - method_call, /* tp_call */ - 0, /* tp_str */ - method_getattro, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - method_doc, /* tp_doc */ - (traverseproc)method_traverse, /* tp_traverse */ - 0, /* tp_clear */ - method_richcompare, /* tp_richcompare */ - offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - method_memberlist, /* tp_members */ - method_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - method_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - method_new, /* tp_new */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "method", + sizeof(PyMethodObject), + 0, + (destructor)method_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)method_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)method_hash, /* tp_hash */ + method_call, /* tp_call */ + 0, /* tp_str */ + method_getattro, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + method_doc, /* tp_doc */ + (traverseproc)method_traverse, /* tp_traverse */ + 0, /* tp_clear */ + method_richcompare, /* tp_richcompare */ + offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + method_memberlist, /* tp_members */ + method_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + method_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + method_new, /* tp_new */ }; /* Clear out the free list */ @@ -381,22 +381,22 @@ PyTypeObject PyMethod_Type = { 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; + 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(); + (void)PyMethod_ClearFreeList(); } /* ------------------------------------------------------------------------ @@ -405,176 +405,176 @@ PyMethod_Fini(void) PyObject * PyInstanceMethod_New(PyObject *func) { - PyInstanceMethodObject *method; - method = PyObject_GC_New(PyInstanceMethodObject, - &PyInstanceMethod_Type); - if (method == NULL) return NULL; - Py_INCREF(func); - method->func = func; - _PyObject_GC_TRACK(method); - return (PyObject *)method; + PyInstanceMethodObject *method; + method = PyObject_GC_New(PyInstanceMethodObject, + &PyInstanceMethod_Type); + if (method == NULL) return NULL; + Py_INCREF(func); + method->func = func; + _PyObject_GC_TRACK(method); + return (PyObject *)method; } PyObject * PyInstanceMethod_Function(PyObject *im) { - if (!PyInstanceMethod_Check(im)) { - PyErr_BadInternalCall(); - return NULL; - } - return PyInstanceMethod_GET_FUNCTION(im); + if (!PyInstanceMethod_Check(im)) { + PyErr_BadInternalCall(); + return NULL; + } + return PyInstanceMethod_GET_FUNCTION(im); } #define IMO_OFF(x) offsetof(PyInstanceMethodObject, x) static PyMemberDef instancemethod_memberlist[] = { - {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED, - "the function (or other callable) implementing a method"}, - {NULL} /* Sentinel */ + {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED, + "the function (or other callable) implementing a method"}, + {NULL} /* Sentinel */ }; static PyObject * instancemethod_get_doc(PyObject *self, void *context) { - static PyObject *docstr; - if (docstr == NULL) { - docstr = PyUnicode_InternFromString("__doc__"); - if (docstr == NULL) - return NULL; - } - return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr); + static PyObject *docstr; + if (docstr == NULL) { + docstr = PyUnicode_InternFromString("__doc__"); + if (docstr == NULL) + return NULL; + } + return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr); } static PyGetSetDef instancemethod_getset[] = { - {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, - {0} + {"__doc__", (getter)instancemethod_get_doc, NULL, NULL}, + {0} }; static PyObject * instancemethod_getattro(PyObject *self, PyObject *name) { - PyTypeObject *tp = self->ob_type; - PyObject *descr = NULL; - - 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, self, (PyObject *)self->ob_type); - else { - Py_INCREF(descr); - return descr; - } - } - - return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); + PyTypeObject *tp = self->ob_type; + PyObject *descr = NULL; + + 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, self, (PyObject *)self->ob_type); + else { + Py_INCREF(descr); + return descr; + } + } + + return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name); } static void instancemethod_dealloc(PyObject *self) { - _PyObject_GC_UNTRACK(self); - Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); - PyObject_GC_Del(self); + _PyObject_GC_UNTRACK(self); + Py_DECREF(PyInstanceMethod_GET_FUNCTION(self)); + PyObject_GC_Del(self); } static int instancemethod_traverse(PyObject *self, visitproc visit, void *arg) { - Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); - return 0; + Py_VISIT(PyInstanceMethod_GET_FUNCTION(self)); + return 0; } static PyObject * instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) { - return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw); + return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw); } static PyObject * instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { - register PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); - if (obj == NULL) { - Py_INCREF(func); - return func; - } - else - return PyMethod_New(func, obj); + register PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); + if (obj == NULL) { + Py_INCREF(func); + return func; + } + else + return PyMethod_New(func, obj); } static PyObject * instancemethod_richcompare(PyObject *self, PyObject *other, int op) { - PyInstanceMethodObject *a, *b; - PyObject *res; - int eq; - - if ((op != Py_EQ && op != Py_NE) || - !PyInstanceMethod_Check(self) || - !PyInstanceMethod_Check(other)) - { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - a = (PyInstanceMethodObject *)self; - b = (PyInstanceMethodObject *)other; - eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); - if (eq < 0) - return NULL; - if (op == Py_EQ) - res = eq ? Py_True : Py_False; - else - res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + PyInstanceMethodObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !PyInstanceMethod_Check(self) || + !PyInstanceMethod_Check(other)) + { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + a = (PyInstanceMethodObject *)self; + b = (PyInstanceMethodObject *)other; + eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ); + if (eq < 0) + return NULL; + if (op == Py_EQ) + res = eq ? Py_True : Py_False; + else + res = eq ? Py_False : Py_True; + Py_INCREF(res); + return res; } static PyObject * instancemethod_repr(PyObject *self) { - PyObject *func = PyInstanceMethod_Function(self); - PyObject *funcname = NULL , *result = NULL; - char *defname = "?"; - - if (func == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - funcname = PyObject_GetAttrString(func, "__name__"); - if (funcname == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - return NULL; - PyErr_Clear(); - } - else if (!PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; - } - - result = PyUnicode_FromFormat("", - funcname, defname, self); - - Py_XDECREF(funcname); - return result; + PyObject *func = PyInstanceMethod_Function(self); + PyObject *funcname = NULL , *result = NULL; + char *defname = "?"; + + if (func == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + funcname = PyObject_GetAttrString(func, "__name__"); + if (funcname == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return NULL; + PyErr_Clear(); + } + else if (!PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; + } + + result = PyUnicode_FromFormat("", + funcname, defname, self); + + Py_XDECREF(funcname); + return result; } /* static long instancemethod_hash(PyObject *self) { - long x, y; - x = (long)self; - y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); - if (y == -1) - return -1; - x = x ^ y; - if (x == -1) - x = -2; - return x; + long x, y; + x = (long)self; + y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); + if (y == -1) + return -1; + x = x ^ y; + if (x == -1) + x = -2; + return x; } */ @@ -586,59 +586,59 @@ Bind a function to a class."); static PyObject * instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw) { - PyObject *func; - - if (!_PyArg_NoKeywords("instancemethod", kw)) - return NULL; - if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func)) - return NULL; - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_TypeError, - "first argument must be callable"); - return NULL; - } - - return PyInstanceMethod_New(func); + PyObject *func; + + if (!_PyArg_NoKeywords("instancemethod", kw)) + return NULL; + if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func)) + return NULL; + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return NULL; + } + + return PyInstanceMethod_New(func); } PyTypeObject PyInstanceMethod_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "instancemethod", /* tp_name */ - sizeof(PyInstanceMethodObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - instancemethod_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)instancemethod_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /*(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, /* tp_flags */ - instancemethod_doc, /* tp_doc */ - instancemethod_traverse, /* tp_traverse */ - 0, /* tp_clear */ - instancemethod_richcompare, /* tp_richcompare */ - 0, /* 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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "instancemethod", /* tp_name */ + sizeof(PyInstanceMethodObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + instancemethod_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)instancemethod_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /*(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, /* tp_flags */ + instancemethod_doc, /* tp_doc */ + instancemethod_traverse, /* tp_traverse */ + 0, /* tp_clear */ + instancemethod_richcompare, /* tp_richcompare */ + 0, /* 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 */ }; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index ad2068bb2a..da5c09ac8d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -3,183 +3,183 @@ #include "structmember.h" #define NAME_CHARS \ - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ static int all_name_chars(Py_UNICODE *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 (*s >= 128) - return 0; - if (ok_name_char[*s++] == 0) - return 0; - } - return 1; + 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 (*s >= 128) + return 0; + 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 || !PyUnicode_CheckExact(v)) { - Py_FatalError("non-string found in code slot"); - } - PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i)); - } + Py_ssize_t i; + + for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { + PyObject *v = PyTuple_GET_ITEM(tuple, i); + if (v == NULL || !PyUnicode_CheckExact(v)) { + Py_FatalError("non-string found in code slot"); + } + PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i)); + } } PyCodeObject * PyCode_New(int argcount, int kwonlyargcount, - 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) + 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 || kwonlyargcount < 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 || !PyUnicode_Check(name) || - filename == NULL || !PyUnicode_Check(filename) || - lnotab == NULL || !PyBytes_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 (!PyUnicode_Check(v)) - continue; - if (!all_name_chars(PyUnicode_AS_UNICODE(v))) - continue; - PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); - } - co = PyObject_NEW(PyCodeObject, &PyCode_Type); - if (co != NULL) { - co->co_argcount = argcount; - co->co_kwonlyargcount = kwonlyargcount; - 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 *co; + Py_ssize_t i; + + /* Check argument types */ + if (argcount < 0 || kwonlyargcount < 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 || !PyUnicode_Check(name) || + filename == NULL || !PyUnicode_Check(filename) || + lnotab == NULL || !PyBytes_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 (!PyUnicode_Check(v)) + continue; + if (!all_name_chars(PyUnicode_AS_UNICODE(v))) + continue; + PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); + } + co = PyObject_NEW(PyCodeObject, &PyCode_Type); + if (co != NULL) { + co->co_argcount = argcount; + co->co_kwonlyargcount = kwonlyargcount; + 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 = PyBytes_FromString(""); - if (emptystring == NULL) - goto failed; - } - if (nulltuple == NULL) { - nulltuple = PyTuple_New(0); - if (nulltuple == NULL) - goto failed; - } - funcname_ob = PyUnicode_FromString(funcname); - if (funcname_ob == NULL) - goto failed; - filename_ob = PyUnicode_DecodeFSDefault(filename); - if (filename_ob == NULL) - goto failed; - - result = PyCode_New(0, /* argcount */ - 0, /* kwonlyargcount */ - 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 */ - ); + static PyObject *emptystring = NULL; + static PyObject *nulltuple = NULL; + PyObject *filename_ob = NULL; + PyObject *funcname_ob = NULL; + PyCodeObject *result = NULL; + if (emptystring == NULL) { + emptystring = PyBytes_FromString(""); + if (emptystring == NULL) + goto failed; + } + if (nulltuple == NULL) { + nulltuple = PyTuple_New(0); + if (nulltuple == NULL) + goto failed; + } + funcname_ob = PyUnicode_FromString(funcname); + if (funcname_ob == NULL) + goto failed; + filename_ob = PyUnicode_DecodeFSDefault(filename); + if (filename_ob == NULL) + goto failed; + + result = PyCode_New(0, /* argcount */ + 0, /* kwonlyargcount */ + 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; + 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_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), 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 */ + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), 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 @@ -188,42 +188,42 @@ static PyMemberDef code_memberlist[] = { 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 (PyUnicode_CheckExact(item)) { - Py_INCREF(item); - } - else if (!PyUnicode_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 = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(item), - PyUnicode_GET_SIZE(item)); - if (item == NULL) { - Py_DECREF(newtuple); - return NULL; - } - } - PyTuple_SET_ITEM(newtuple, i, item); - } - - return newtuple; + 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 (PyUnicode_CheckExact(item)) { + Py_INCREF(item); + } + else if (!PyUnicode_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 = PyUnicode_FromUnicode( + PyUnicode_AS_UNICODE(item), + PyUnicode_GET_SIZE(item)); + if (item == NULL) { + Py_DECREF(newtuple); + return NULL; + } + } + PyTuple_SET_ITEM(newtuple, i, item); + } + + return newtuple; } PyDoc_STRVAR(code_doc, @@ -236,253 +236,253 @@ Create a code object. Not for the faint of heart."); static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - int argcount; - int kwonlyargcount; - 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, "iiiiiSO!O!O!UUiS|O!O!:code", - &argcount, &kwonlyargcount, - &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 (kwonlyargcount < 0) { - PyErr_SetString( - PyExc_ValueError, - "code: kwonlyargcount 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, kwonlyargcount, - nlocals, stacksize, flags, - code, consts, ournames, ourvarnames, - ourfreevars, ourcellvars, filename, - name, firstlineno, lnotab); + int argcount; + int kwonlyargcount; + 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, "iiiiiSO!O!O!UUiS|O!O!:code", + &argcount, &kwonlyargcount, + &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 (kwonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: kwonlyargcount 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, kwonlyargcount, + 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; + 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); + 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) { - int lineno; - if (co->co_firstlineno != 0) - lineno = co->co_firstlineno; - else - lineno = -1; - if (co->co_filename && PyUnicode_Check(co->co_filename)) { - return PyUnicode_FromFormat( - "", - co->co_name, co, co->co_filename, lineno); - } else { - return PyUnicode_FromFormat( - "", - co->co_name, co, lineno); - } + int lineno; + if (co->co_firstlineno != 0) + lineno = co->co_firstlineno; + else + lineno = -1; + if (co->co_filename && PyUnicode_Check(co->co_filename)) { + return PyUnicode_FromFormat( + "", + co->co_name, co, co->co_filename, lineno); + } else { + return PyUnicode_FromFormat( + "", + co->co_name, co, lineno); + } } 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)) { - 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_kwonlyargcount == cp->co_kwonlyargcount; - 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; + PyCodeObject *co, *cp; + int eq; + PyObject *res; + + if ((op != Py_EQ && op != Py_NE) || + !PyCode_Check(self) || + !PyCode_Check(other)) { + 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_kwonlyargcount == cp->co_kwonlyargcount; + 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; + if (eq < 0) + return NULL; + if (op == Py_NE) + res = Py_True; + else + res = Py_False; done: - Py_INCREF(res); - return res; + 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_kwonlyargcount ^ - co->co_nlocals ^ co->co_flags; - if (h == -1) h = -2; - return h; + 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_kwonlyargcount ^ + 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 */ - 0, /* tp_reserved */ - (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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "code", + sizeof(PyCodeObject), + 0, + (destructor)code_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 @@ -492,17 +492,17 @@ PyTypeObject PyCode_Type = { int PyCode_Addr2Line(PyCodeObject *co, int addrq) { - int size = PyBytes_Size(co->co_lnotab) / 2; - unsigned char *p = (unsigned char*)PyBytes_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; + int size = PyBytes_Size(co->co_lnotab) / 2; + unsigned char *p = (unsigned char*)PyBytes_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 @@ -510,47 +510,47 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) int _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) { - int size, addr, line; - unsigned char* p; - - p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); - size = PyBytes_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; + int size, addr, line; + unsigned char* p; + + p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); + size = PyBytes_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; + return line; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 0e55bc323c..ec26e0a700 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -15,377 +15,377 @@ 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 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 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 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 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 { - /* 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; - } - return r; + /****************************************************************** + 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 { + /* 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; + } + 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; + 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; + 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)); + 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; + /* 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; + PyObject *op; - op = type->tp_alloc(type, 0); - if (op != NULL) - ((PyComplexObject *)op)->cval = cval; - return 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; + 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); + 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); + 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); - } + 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; - } + 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; - - f = _PyObject_LookupSpecial(op, "__complex__", &complexstr); - if (f) { - PyObject *res = PyObject_CallFunctionObjArgs(f, NULL); - Py_DECREF(f); - return res; - } - return NULL; + PyObject *f; + static PyObject *complexstr; + + f = _PyObject_LookupSpecial(op, "__complex__", &complexstr); + if (f) { + 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; - } + 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); + 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 = PyUnicode_FromString(buf); + 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 = PyUnicode_FromString(buf); done: - PyMem_Free(im); - PyMem_Free(pre); - PyMem_Free(buf); + PyMem_Free(im); + PyMem_Free(pre); + PyMem_Free(buf); - return result; + return result; } static PyObject * @@ -403,264 +403,264 @@ complex_str(PyComplexObject *v) 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; + 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) + 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 (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; + PyObject *obj = *pobj; + + pc->real = pc->imag = 0.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); + 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); + 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); + 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); + 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_remainder(PyObject *v, PyObject *w) { - PyErr_SetString(PyExc_TypeError, - "can't mod complex numbers."); - return NULL; + PyErr_SetString(PyExc_TypeError, + "can't mod complex numbers."); + return NULL; } static PyObject * complex_divmod(PyObject *v, PyObject *w) { - PyErr_SetString(PyExc_TypeError, - "can't take floor or mod of complex number."); - return NULL; + PyErr_SetString(PyExc_TypeError, + "can't take floor or mod of complex number."); + return NULL; } 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); + 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) { - PyErr_SetString(PyExc_TypeError, - "can't take floor of complex number."); - return NULL; + PyErr_SetString(PyExc_TypeError, + "can't take floor of complex number."); + 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); + 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); + 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); + 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_bool(PyComplexObject *v) { - return v->cval.real != 0.0 || v->cval.imag != 0.0; + return v->cval.real != 0.0 || v->cval.imag != 0.0; } static PyObject * complex_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *res; - Py_complex i, j; - TO_COMPLEX(v, i); - TO_COMPLEX(w, j); - - if (op != Py_EQ && op != Py_NE) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) - res = Py_True; - else - res = Py_False; - - Py_INCREF(res); - return res; + PyObject *res; + Py_complex i, j; + TO_COMPLEX(v, i); + TO_COMPLEX(w, j); + + if (op != Py_EQ && op != Py_NE) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) + res = Py_True; + else + res = Py_False; + + Py_INCREF(res); + return res; } static PyObject * complex_int(PyObject *v) { - PyErr_SetString(PyExc_TypeError, - "can't convert complex to int"); - return NULL; + PyErr_SetString(PyExc_TypeError, + "can't convert complex to int"); + return NULL; } static PyObject * complex_float(PyObject *v) { - PyErr_SetString(PyExc_TypeError, - "can't convert complex to float"); - return NULL; + 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); + Py_complex c; + c = ((PyComplexObject *)self)->cval; + c.imag = -c.imag; + return PyComplex_FromCComplex(c); } PyDoc_STRVAR(complex_conjugate_doc, @@ -671,8 +671,8 @@ PyDoc_STRVAR(complex_conjugate_doc, static PyObject * complex_getnewargs(PyComplexObject *v) { - Py_complex c = v->cval; - return Py_BuildValue("(dd)", c.real, c.imag); + Py_complex c = v->cval; + return Py_BuildValue("(dd)", c.real, c.imag); } PyDoc_STRVAR(complex__format__doc, @@ -686,7 +686,7 @@ complex__format__(PyObject* self, PyObject* args) PyObject *format_spec; if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; + return NULL; return _PyComplex_FormatAdvanced(self, PyUnicode_AS_UNICODE(format_spec), PyUnicode_GET_SIZE(format_spec)); @@ -696,10 +696,10 @@ complex__format__(PyObject* self, PyObject* args) 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))); + 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, @@ -709,305 +709,305 @@ PyDoc_STRVAR(complex_is_finite_doc, #endif static PyMethodDef complex_methods[] = { - {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, - complex_conjugate_doc}, + {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, + complex_conjugate_doc}, #if 0 - {"is_finite", (PyCFunction)complex_is_finite, METH_NOARGS, - complex_is_finite_doc}, + {"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 */ + {"__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}, + {"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; - char *s_buffer = NULL; - Py_ssize_t len; - - 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); - } - 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: - - - real part only - j - imaginary part only - j - real and imaginary parts - - where represents any numeric string that's accepted by the - float constructor (including 'nan', 'inf', 'infinity', etc.), and - is any string of the form whose first - character is '+' or '-'. - - For backwards compatibility, the extra forms - - j - 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 */ - 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 land here */ - s = end; - if (*s == '+' || *s == '-') { - /* j | 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) - /* j */ - s = end; - else { - /* j */ - y = *s == '+' ? 1.0 : -1.0; - s++; - } - if (!(*s == 'j' || *s == 'J')) - goto parse_error; - s++; - } - else if (*s == 'j' || *s == 'J') { - /* j */ - s++; - y = z; - } - else - /* */ - x = z; - } - else { - /* not starting with ; must be j or j */ - if (*s == '+' || *s == '-') { - /* 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; - - if (s_buffer) - PyMem_FREE(s_buffer); - return complex_subtype_from_doubles(type, x, y); + const char *s, *start; + char *end; + double x=0.0, y=0.0, z; + int got_bracket=0; + char *s_buffer = NULL; + Py_ssize_t len; + + 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); + } + 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: + + - real part only + j - imaginary part only + j - real and imaginary parts + + where represents any numeric string that's accepted by the + float constructor (including 'nan', 'inf', 'infinity', etc.), and + is any string of the form whose first + character is '+' or '-'. + + For backwards compatibility, the extra forms + + j + 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 */ + 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 land here */ + s = end; + if (*s == '+' || *s == '-') { + /* j | 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) + /* j */ + s = end; + else { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; + } + if (!(*s == 'j' || *s == 'J')) + goto parse_error; + s++; + } + else if (*s == 'j' || *s == 'J') { + /* j */ + s++; + y = z; + } + else + /* */ + x = z; + } + else { + /* not starting with ; must be j or j */ + if (*s == '+' || *s == '-') { + /* 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; + + if (s_buffer) + PyMem_FREE(s_buffer); + return complex_subtype_from_doubles(type, x, y); parse_error: - PyErr_SetString(PyExc_ValueError, - "complex() arg is a malformed string"); + PyErr_SetString(PyExc_ValueError, + "complex() arg is a malformed string"); error: - if (s_buffer) - PyMem_FREE(s_buffer); - return NULL; + if (s_buffer) + PyMem_FREE(s_buffer); + 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 (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 && 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); + 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 (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 && 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, @@ -1017,79 +1017,79 @@ PyDoc_STRVAR(complex_doc, "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_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_bool, /* nb_bool */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - 0, /* nb_and */ - 0, /* nb_xor */ - 0, /* nb_or */ - complex_int, /* nb_int */ - 0, /* nb_reserved */ - complex_float, /* nb_float */ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply*/ - 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 */ + (binaryfunc)complex_add, /* nb_add */ + (binaryfunc)complex_sub, /* nb_subtract */ + (binaryfunc)complex_mul, /* nb_multiply */ + (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_bool, /* nb_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + complex_int, /* nb_int */ + 0, /* nb_reserved */ + complex_float, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply*/ + 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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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_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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "complex", + sizeof(PyComplexObject), + 0, + complex_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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_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 */ }; diff --git a/Objects/descrobject.c b/Objects/descrobject.c index a09e0e2068..aa4411c027 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -6,647 +6,647 @@ static void descr_dealloc(PyDescrObject *descr) { - _PyObject_GC_UNTRACK(descr); - Py_XDECREF(descr->d_type); - Py_XDECREF(descr->d_name); - PyObject_GC_Del(descr); + _PyObject_GC_UNTRACK(descr); + Py_XDECREF(descr->d_type); + Py_XDECREF(descr->d_name); + PyObject_GC_Del(descr); } static PyObject * descr_name(PyDescrObject *descr) { - if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) - return descr->d_name; - return NULL; + if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) + return descr->d_name; + return NULL; } static PyObject * descr_repr(PyDescrObject *descr, char *format) { - PyObject *name = NULL; - if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) - name = descr->d_name; + PyObject *name = NULL; + if (descr->d_name != NULL && PyUnicode_Check(descr->d_name)) + name = descr->d_name; - return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name); + return PyUnicode_FromFormat(format, name, "?", descr->d_type->tp_name); } static PyObject * method_repr(PyMethodDescrObject *descr) { - return descr_repr((PyDescrObject *)descr, - ""); + return descr_repr((PyDescrObject *)descr, + ""); } static PyObject * member_repr(PyMemberDescrObject *descr) { - return descr_repr((PyDescrObject *)descr, - ""); + return descr_repr((PyDescrObject *)descr, + ""); } static PyObject * getset_repr(PyGetSetDescrObject *descr) { - return descr_repr((PyDescrObject *)descr, - ""); + return descr_repr((PyDescrObject *)descr, + ""); } static PyObject * wrapperdescr_repr(PyWrapperDescrObject *descr) { - return descr_repr((PyDescrObject *)descr, - ""); + return descr_repr((PyDescrObject *)descr, + ""); } 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 '%V' 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; + if (obj == NULL) { + Py_INCREF(descr); + *pres = (PyObject *)descr; + return 1; + } + if (!PyObject_TypeCheck(obj, descr->d_type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' 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 '%V' for type '%s' " - "needs either an object or a type", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return NULL; - } - } - if (!PyType_Check(type)) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%s' " - "needs a type, not a '%s' as arg 2", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, - type->ob_type->tp_name); - return NULL; - } - if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' for type '%s' " - "doesn't apply to type '%s'", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, - ((PyTypeObject *)type)->tp_name); - return NULL; - } - return PyCFunction_New(descr->d_method, 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 '%V' for type '%s' " + "needs either an object or a type", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + } + if (!PyType_Check(type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for type '%s' " + "needs a type, not a '%s' as arg 2", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name, + type->ob_type->tp_name); + return NULL; + } + if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' for type '%s' " + "doesn't apply to type '%s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->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; + PyObject *res; - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; - return PyCFunction_New(descr->d_method, obj); + 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; + PyObject *res; - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; - return PyMember_GetOne((char *)obj, descr->d_member); + 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 '%V' of '%.100s' objects is not readable", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return NULL; + 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 '%V' of '%.100s' objects is not readable", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; } static PyObject * wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) { - PyObject *res; + PyObject *res; - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; - return PyWrapper_New((PyObject *)descr, obj); + 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) + int *pres) { - assert(obj != NULL); - if (!PyObject_TypeCheck(obj, descr->d_type)) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' 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; + assert(obj != NULL); + if (!PyObject_TypeCheck(obj, descr->d_type)) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' 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; + int res; - if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) - return res; - return PyMember_SetOne((char *)obj, descr->d_member, value); + 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 '%V' of '%.100s' objects is not writable", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return -1; + 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 '%V' of '%.100s' objects is not writable", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->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 '%V' of '%.100s' " - "object needs an argument", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return NULL; - } - self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' " - "requires a '%.100s' object " - "but received a '%.100s'", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->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; + 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 '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + self = PyTuple_GET_ITEM(args, 0); + if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' " + "requires a '%.100s' object " + "but received a '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->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) + PyObject *kwds) { - PyObject *func, *result; + PyObject *func, *result; - func = PyCFunction_New(descr->d_method, (PyObject *)PyDescr_TYPE(descr)); - if (func == NULL) - return NULL; + func = PyCFunction_New(descr->d_method, (PyObject *)PyDescr_TYPE(descr)); + if (func == NULL) + return NULL; - result = PyEval_CallObjectWithKeywords(func, args, kwds); - Py_DECREF(func); - return result; + result = PyEval_CallObjectWithKeywords(func, args, kwds); + Py_DECREF(func); + 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 '%V' of '%.100s' " - "object needs an argument", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name); - return NULL; - } - self = PyTuple_GET_ITEM(args, 0); - if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' " - "requires a '%.100s' object " - "but received a '%.100s'", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->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; + 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 '%V' of '%.100s' " + "object needs an argument", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->tp_name); + return NULL; + } + self = PyTuple_GET_ITEM(args, 0); + if (!PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))) { + PyErr_Format(PyExc_TypeError, + "descriptor '%V' " + "requires a '%.100s' object " + "but received a '%.100s'", + descr_name((PyDescrObject *)descr), "?", + PyDescr_TYPE(descr)->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 PyUnicode_FromString(descr->d_method->ml_doc); + if (descr->d_method->ml_doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyUnicode_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} + {"__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} + {"__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 PyUnicode_FromString(descr->d_member->doc); + if (descr->d_member->doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyUnicode_FromString(descr->d_member->doc); } static PyGetSetDef member_getset[] = { - {"__doc__", (getter)member_get_doc}, - {0} + {"__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 PyUnicode_FromString(descr->d_getset->doc); + if (descr->d_getset->doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyUnicode_FromString(descr->d_getset->doc); } static PyGetSetDef getset_getset[] = { - {"__doc__", (getter)getset_get_doc}, - {0} + {"__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 PyUnicode_FromString(descr->d_base->doc); + if (descr->d_base->doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyUnicode_FromString(descr->d_base->doc); } static PyGetSetDef wrapperdescr_getset[] = { - {"__doc__", (getter)wrapperdescr_get_doc}, - {0} + {"__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; + PyDescrObject *descr = (PyDescrObject *)self; + Py_VISIT(descr->d_type); + return 0; } 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_reserved */ - (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 */ + 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_reserved */ + (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! */ 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_reserved */ - (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 */ + 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_reserved */ + (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_reserved */ - (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 */ + 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_reserved */ + (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_reserved */ - (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 */ + 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_reserved */ + (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_reserved */ - (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 */ + 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_reserved */ + (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 = PyUnicode_InternFromString(name); - if (descr->d_name == NULL) { - Py_DECREF(descr); - descr = NULL; - } - } - return descr; + PyDescrObject *descr; + + descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); + if (descr != NULL) { + Py_XINCREF(type); + descr->d_type = type; + descr->d_name = PyUnicode_InternFromString(name); + if (descr->d_name == NULL) { + Py_DECREF(descr); + descr = NULL; + } + } + return descr; } PyObject * PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) { - PyMethodDescrObject *descr; + PyMethodDescrObject *descr; - descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, - type, method->ml_name); - if (descr != NULL) - descr->d_method = method; - return (PyObject *)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; + PyMethodDescrObject *descr; - descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type, - type, method->ml_name); - if (descr != NULL) - descr->d_method = method; - return (PyObject *)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; + PyMemberDescrObject *descr; - descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, - type, member->name); - if (descr != NULL) - descr->d_member = member; - return (PyObject *)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; + PyGetSetDescrObject *descr; - descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, - type, getset->name); - if (descr != NULL) - descr->d_getset = getset; - return (PyObject *)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; + 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; } @@ -656,180 +656,180 @@ PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) bit of a pain */ typedef struct { - PyObject_HEAD - PyObject *dict; + PyObject_HEAD + PyObject *dict; } proxyobject; static Py_ssize_t proxy_len(proxyobject *pp) { - return PyObject_Size(pp->dict); + return PyObject_Size(pp->dict); } static PyObject * proxy_getitem(proxyobject *pp, PyObject *key) { - return PyObject_GetItem(pp->dict, 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 */ + (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); + 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 */ + 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_get(proxyobject *pp, PyObject *args) { - PyObject *key, *def = Py_None; + 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); + 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); + return PyMapping_Keys(pp->dict); } static PyObject * proxy_values(proxyobject *pp) { - return PyMapping_Values(pp->dict); + return PyMapping_Values(pp->dict); } static PyObject * proxy_items(proxyobject *pp) { - return PyMapping_Items(pp->dict); + return PyMapping_Items(pp->dict); } static PyObject * proxy_copy(proxyobject *pp) { - return PyObject_CallMethod(pp->dict, "copy", NULL); + return PyObject_CallMethod(pp->dict, "copy", NULL); } static PyMethodDef proxy_methods[] = { - {"get", (PyCFunction)proxy_get, METH_VARARGS, - PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, 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")}, - {"copy", (PyCFunction)proxy_copy, METH_NOARGS, - PyDoc_STR("D.copy() -> a shallow copy of D")}, - {0} + {"get", (PyCFunction)proxy_get, METH_VARARGS, + PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, 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")}, + {"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); + _PyObject_GC_UNTRACK(pp); + Py_DECREF(pp->dict); + PyObject_GC_Del(pp); } static PyObject * proxy_getiter(proxyobject *pp) { - return PyObject_GetIter(pp->dict); + return PyObject_GetIter(pp->dict); } static PyObject * proxy_str(proxyobject *pp) { - return PyObject_Str(pp->dict); + return PyObject_Str(pp->dict); } static int proxy_traverse(PyObject *self, visitproc visit, void *arg) { - proxyobject *pp = (proxyobject *)self; - Py_VISIT(pp->dict); - return 0; + proxyobject *pp = (proxyobject *)self; + Py_VISIT(pp->dict); + return 0; } static PyObject * proxy_richcompare(proxyobject *v, PyObject *w, int op) { - return PyObject_RichCompare(v->dict, w, op); + return PyObject_RichCompare(v->dict, w, op); } PyTypeObject PyDictProxy_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "dict_proxy", /* tp_name */ - sizeof(proxyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)proxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* 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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_proxy", /* tp_name */ + sizeof(proxyobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)proxy_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* 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; + 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; } @@ -842,9 +842,9 @@ PyDictProxy_New(PyObject *dict) static PyTypeObject wrappertype; typedef struct { - PyObject_HEAD - PyWrapperDescrObject *descr; - PyObject *self; + PyObject_HEAD + PyWrapperDescrObject *descr; + PyObject *self; } wrapperobject; #define Wrapper_Check(v) (Py_TYPE(v) == &wrappertype) @@ -852,12 +852,12 @@ typedef struct { 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) + 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) } #define TEST_COND(cond) ((cond) ? Py_True : Py_False) @@ -865,211 +865,211 @@ wrapper_dealloc(wrapperobject *wp) static PyObject * wrapper_richcompare(PyObject *a, PyObject *b, int op) { - int result; - PyObject *v; - PyWrapperDescrObject *a_descr, *b_descr; - - assert(a != NULL && b != NULL); - - /* both arguments should be wrapperobjects */ - if (!Wrapper_Check(a) || !Wrapper_Check(b)) { - v = Py_NotImplemented; - Py_INCREF(v); - return v; - } - - /* compare by descriptor address; if the descriptors are the same, - compare by the objects they're bound to */ - a_descr = ((wrapperobject *)a)->descr; - b_descr = ((wrapperobject *)b)->descr; - if (a_descr == b_descr) { - a = ((wrapperobject *)a)->self; - b = ((wrapperobject *)b)->self; - return PyObject_RichCompare(a, b, op); - } - - result = a_descr - b_descr; - switch (op) { - case Py_EQ: - v = TEST_COND(result == 0); - break; - case Py_NE: - v = TEST_COND(result != 0); - break; - case Py_LE: - v = TEST_COND(result <= 0); - break; - case Py_GE: - v = TEST_COND(result >= 0); - break; - case Py_LT: - v = TEST_COND(result < 0); - break; - case Py_GT: - v = TEST_COND(result > 0); - break; - default: - PyErr_BadArgument(); - return NULL; - } - Py_INCREF(v); - return v; + int result; + PyObject *v; + PyWrapperDescrObject *a_descr, *b_descr; + + assert(a != NULL && b != NULL); + + /* both arguments should be wrapperobjects */ + if (!Wrapper_Check(a) || !Wrapper_Check(b)) { + v = Py_NotImplemented; + Py_INCREF(v); + return v; + } + + /* compare by descriptor address; if the descriptors are the same, + compare by the objects they're bound to */ + a_descr = ((wrapperobject *)a)->descr; + b_descr = ((wrapperobject *)b)->descr; + if (a_descr == b_descr) { + a = ((wrapperobject *)a)->self; + b = ((wrapperobject *)b)->self; + return PyObject_RichCompare(a, b, op); + } + + result = a_descr - b_descr; + switch (op) { + case Py_EQ: + v = TEST_COND(result == 0); + break; + case Py_NE: + v = TEST_COND(result != 0); + break; + case Py_LE: + v = TEST_COND(result <= 0); + break; + case Py_GE: + v = TEST_COND(result >= 0); + break; + case Py_LT: + v = TEST_COND(result < 0); + break; + case Py_GT: + v = TEST_COND(result > 0); + break; + default: + PyErr_BadArgument(); + return NULL; + } + Py_INCREF(v); + return v; } 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; + 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 PyUnicode_FromFormat("", - wp->descr->d_base->name, - wp->self->ob_type->tp_name, - wp->self); + return PyUnicode_FromFormat("", + 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} + {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, + {0} }; static PyObject * wrapper_objclass(wrapperobject *wp) { - PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); + PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); - Py_INCREF(c); - return c; + Py_INCREF(c); + return c; } static PyObject * wrapper_name(wrapperobject *wp) { - const char *s = wp->descr->d_base->name; + const char *s = wp->descr->d_base->name; - return PyUnicode_FromString(s); + return PyUnicode_FromString(s); } static PyObject * wrapper_doc(wrapperobject *wp) { - const char *s = wp->descr->d_base->doc; - - if (s == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - else { - return PyUnicode_FromString(s); - } + const char *s = wp->descr->d_base->doc; + + if (s == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + else { + return PyUnicode_FromString(s); + } } static PyGetSetDef wrapper_getsets[] = { - {"__objclass__", (getter)wrapper_objclass}, - {"__name__", (getter)wrapper_name}, - {"__doc__", (getter)wrapper_doc}, - {0} + {"__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); + 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; + 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 */ - 0, /* tp_reserved */ - (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 */ - wrapper_richcompare, /* 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 */ + 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 */ + 0, /* tp_reserved */ + (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 */ + wrapper_richcompare, /* 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_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))); - - 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; + wrapperobject *wp; + PyWrapperDescrObject *descr; + + assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); + descr = (PyWrapperDescrObject *)d; + assert(PyObject_IsInstance(self, (PyObject *)PyDescr_TYPE(descr))); + + 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; } @@ -1078,247 +1078,247 @@ PyWrapper_New(PyObject *d, PyObject *self) /* 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) + 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; + 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 *, 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} + {"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."); + "Descriptor to change the getter on a property."); static PyObject * property_getter(PyObject *self, PyObject *getter) { - return property_copy(self, getter, NULL, NULL, NULL); + return property_copy(self, getter, NULL, NULL, NULL); } PyDoc_STRVAR(setter_doc, - "Descriptor to change the setter on a property."); + "Descriptor to change the setter on a property."); static PyObject * property_setter(PyObject *self, PyObject *setter) { - return property_copy(self, NULL, setter, NULL, NULL); + return property_copy(self, NULL, setter, NULL, NULL); } PyDoc_STRVAR(deleter_doc, - "Descriptor to change the deleter on a property."); + "Descriptor to change the deleter on a property."); static PyObject * property_deleter(PyObject *self, PyObject *deleter) { - return property_copy(self, NULL, NULL, deleter, NULL); + return property_copy(self, NULL, NULL, deleter, NULL); } 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} + {"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); + 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); + 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; + 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, - PyObject *doc) + PyObject *doc) { - propertyobject *pold = (propertyobject *)old; - PyObject *new, *type; - - 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 (doc == NULL || doc == Py_None) { - Py_XDECREF(doc); - 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; + propertyobject *pold = (propertyobject *)old; + PyObject *new, *type; + + 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 (doc == NULL || doc == Py_None) { + Py_XDECREF(doc); + 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; + 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, @@ -1346,54 +1346,54 @@ PyDoc_STRVAR(property_doc, 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; + 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_reserved */ - 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 */ + 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_reserved */ + 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/Objects/dictobject.c b/Objects/dictobject.c index 2eddc8648e..745e2dc9fe 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -17,12 +17,12 @@ 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); + 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. */ @@ -52,7 +52,7 @@ 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 -the list [i << 16 for i in range(20000)] as a set of keys. Since ints are +the list [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. @@ -142,7 +142,7 @@ static PyObject *dummy = NULL; /* Initialized by first call to newPyDictObject() PyObject * _PyDict_Dummy(void) { - return dummy; + return dummy; } #endif @@ -157,9 +157,9 @@ 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); + 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 @@ -172,12 +172,12 @@ 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))); + 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 @@ -189,12 +189,12 @@ 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))); + 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 @@ -208,15 +208,15 @@ show_track(void) an excellent reason not to). */ -#define INIT_NONZERO_DICT_SLOTS(mp) do { \ - (mp)->ma_table = (mp)->ma_smalltable; \ - (mp)->ma_mask = PyDict_MINSIZE - 1; \ +#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); \ +#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 */ @@ -229,68 +229,68 @@ static int numfree = 0; void PyDict_Fini(void) { - PyDictObject *op; + PyDictObject *op; - while (numfree) { - op = free_list[--numfree]; - assert(PyDict_CheckExact(op)); - PyObject_GC_Del(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 = PyUnicode_FromString(""); - if (dummy == NULL) - return NULL; + register PyDictObject *mp; + if (dummy == NULL) { /* Auto-initialize dummy */ + dummy = PyUnicode_FromString(""); + if (dummy == NULL) + return NULL; #ifdef SHOW_CONVERSION_COUNTS - Py_AtExit(show_counts); + Py_AtExit(show_counts); #endif #ifdef SHOW_ALLOC_COUNT - Py_AtExit(show_alloc); + Py_AtExit(show_alloc); #endif #ifdef SHOW_TRACK_COUNT - Py_AtExit(show_track); + 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); + } + 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++; + count_reuse++; #endif - } else { - mp = PyObject_GC_New(PyDictObject, &PyDict_Type); - if (mp == NULL) - return NULL; - EMPTY_TO_MINSIZE(mp); + } else { + mp = PyObject_GC_New(PyDictObject, &PyDict_Type); + if (mp == NULL) + return NULL; + EMPTY_TO_MINSIZE(mp); #ifdef SHOW_ALLOC_COUNT - count_alloc++; + count_alloc++; #endif - } - mp->ma_lookup = lookdict_unicode; + } + mp->ma_lookup = lookdict_unicode; #ifdef SHOW_TRACK_COUNT - count_untracked++; + count_untracked++; #endif #ifdef SHOW_CONVERSION_COUNTS - ++created; + ++created; #endif - return (PyObject *)mp; + return (PyObject *)mp; } /* @@ -320,80 +320,80 @@ 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; + 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; } /* @@ -409,114 +409,114 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash) static PyDictEntry * lookdict_unicode(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-unicode keys, - including subclasses of str; e.g., one reason to subclass - unicodes is to override __eq__, and for speed we don't cater to - that here. */ - if (!PyUnicode_CheckExact(key)) { + 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-unicode keys, + including subclasses of str; e.g., one reason to subclass + unicodes is to override __eq__, and for speed we don't cater to + that here. */ + if (!PyUnicode_CheckExact(key)) { #ifdef SHOW_CONVERSION_COUNTS - ++converted; + ++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 && unicode_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 - && unicode_eq(ep->me_key, key))) - return ep; - if (ep->me_key == dummy && freeslot == NULL) - freeslot = ep; - } - assert(0); /* NOT REACHED */ - return 0; + 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 && unicode_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 + && unicode_eq(ep->me_key, key))) + return ep; + if (ep->me_key == dummy && freeslot == NULL) + freeslot = ep; + } + assert(0); /* NOT REACHED */ + return 0; } int _PyDict_HasOnlyStringKeys(PyObject *dict) { - Py_ssize_t pos = 0; - PyObject *key, *value; - assert(PyDict_CheckExact(dict)); - /* Shortcut */ - if (((PyDictObject *)dict)->ma_lookup == lookdict_unicode) - return 1; - while (PyDict_Next(dict, &pos, &key, &value)) - if (!PyUnicode_Check(key)) - return 0; - return 1; + Py_ssize_t pos = 0; + PyObject *key, *value; + assert(PyDict_CheckExact(dict)); + /* Shortcut */ + if (((PyDictObject *)dict)->ma_lookup == lookdict_unicode) + return 1; + while (PyDict_Next(dict, &pos, &key, &value)) + if (!PyUnicode_Check(key)) + return 0; + return 1; } #ifdef SHOW_TRACK_COUNT #define INCREASE_TRACK_COUNT \ - (count_tracked++, count_untracked--); + (count_tracked++, count_untracked--); #define DECREASE_TRACK_COUNT \ - (count_tracked--, count_untracked++); + (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) + 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); + 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); } @@ -529,37 +529,37 @@ Returns -1 if an error occurred, or 0 on success. static int insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value) { - PyObject *old_value; - register PyDictEntry *ep; - typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); - - assert(mp->ma_lookup != NULL); - ep = mp->ma_lookup(mp, key, hash); - if (ep == NULL) { - Py_DECREF(key); - Py_DECREF(value); - return -1; - } - 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; + PyObject *old_value; + register PyDictEntry *ep; + typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); + + assert(mp->ma_lookup != NULL); + ep = mp->ma_lookup(mp, key, hash); + if (ep == NULL) { + Py_DECREF(key); + Py_DECREF(value); + return -1; + } + 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; } /* @@ -572,27 +572,27 @@ 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++; + 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++; } /* @@ -603,84 +603,84 @@ 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; + 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. @@ -691,13 +691,13 @@ dictresize(PyDictObject *mp, Py_ssize_t minused) PyObject * _PyDict_NewPresized(Py_ssize_t minused) { - PyObject *op = PyDict_New(); + PyObject *op = PyDict_New(); - if (minused>5 && op != NULL && dictresize((PyDictObject *)op, minused) == -1) { - Py_DECREF(op); - return NULL; - } - return op; + 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 @@ -713,47 +713,47 @@ _PyDict_NewPresized(Py_ssize_t minused) PyObject * PyDict_GetItem(PyObject *op, PyObject *key) { - long hash; - PyDictObject *mp = (PyDictObject *)op; - PyDictEntry *ep; - PyThreadState *tstate; - if (!PyDict_Check(op)) - return NULL; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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*)_Py_atomic_load_relaxed( - &_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; + long hash; + PyDictObject *mp = (PyDictObject *)op; + PyDictEntry *ep; + PyThreadState *tstate; + if (!PyDict_Check(op)) + return NULL; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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*)_Py_atomic_load_relaxed( + &_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; } /* Variant of PyDict_GetItem() that doesn't suppress exceptions. @@ -763,27 +763,27 @@ PyDict_GetItem(PyObject *op, PyObject *key) PyObject * PyDict_GetItemWithError(PyObject *op, PyObject *key) { - long hash; - PyDictObject*mp = (PyDictObject *)op; - PyDictEntry *ep; - - if (!PyDict_Check(op)) { - PyErr_BadInternalCall(); - return NULL; - } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -1) - { - hash = PyObject_Hash(key); - if (hash == -1) { - return NULL; - } - } - - ep = (mp->ma_lookup)(mp, key, hash); - if (ep == NULL) - return NULL; - return ep->me_value; + long hash; + PyDictObject*mp = (PyDictObject *)op; + PyDictEntry *ep; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) { + return NULL; + } + } + + ep = (mp->ma_lookup)(mp, key, hash); + if (ep == NULL) + return NULL; + return ep->me_value; } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the @@ -795,154 +795,154 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) int PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) { - register PyDictObject *mp; - register long hash; - register Py_ssize_t n_used; - - if (!PyDict_Check(op)) { - PyErr_BadInternalCall(); - return -1; - } - assert(key); - assert(value); - mp = (PyDictObject *)op; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -1) - { - hash = PyObject_Hash(key); - if (hash == -1) - return -1; - } - assert(mp->ma_fill <= mp->ma_mask); /* at least one empty slot */ - n_used = mp->ma_used; - Py_INCREF(value); - Py_INCREF(key); - if (insertdict(mp, key, hash, 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); + register PyDictObject *mp; + register long hash; + register Py_ssize_t n_used; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(value); + mp = (PyDictObject *)op; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + } + assert(mp->ma_fill <= mp->ma_mask); /* at least one empty slot */ + n_used = mp->ma_used; + Py_INCREF(value); + Py_INCREF(key); + if (insertdict(mp, key, hash, 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); } 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 (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + 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 (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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]; + 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; + Py_ssize_t i, n; #endif - if (!PyDict_Check(op)) - return; - mp = (PyDictObject *)op; + if (!PyDict_Check(op)) + return; + mp = (PyDictObject *)op; #ifdef Py_DEBUG - n = mp->ma_mask + 1; - i = 0; + 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) { + 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; + assert(i < n); + ++i; #endif - if (ep->me_key) { - --fill; - Py_DECREF(ep->me_key); - Py_XDECREF(ep->me_value); - } + if (ep->me_key) { + --fill; + Py_DECREF(ep->me_key); + Py_XDECREF(ep->me_value); + } #ifdef Py_DEBUG - else - assert(ep->me_value == NULL); + else + assert(ep->me_value == NULL); #endif - } + } - if (table_is_malloced) - PyMem_DEL(table); + if (table_is_malloced) + PyMem_DEL(table); } /* @@ -963,55 +963,55 @@ PyDict_Clear(PyObject *op) 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; + 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; + 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 */ @@ -1019,404 +1019,404 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, 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) + 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 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 ? PyUnicode_FromString("{...}") : NULL; - } - - if (mp->ma_used == 0) { - result = PyUnicode_FromString("{}"); - goto Done; - } - - pieces = PyList_New(0); - if (pieces == NULL) - goto Done; - - colon = PyUnicode_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); - PyUnicode_Append(&s, colon); - PyUnicode_AppendAndDel(&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 = PyUnicode_FromString("{"); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyList_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyUnicode_FromString("}"); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); - PyUnicode_AppendAndDel(&temp, s); - PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); + 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 ? PyUnicode_FromString("{...}") : NULL; + } + + if (mp->ma_used == 0) { + result = PyUnicode_FromString("{}"); + goto Done; + } + + pieces = PyList_New(0); + if (pieces == NULL) + goto Done; + + colon = PyUnicode_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); + PyUnicode_Append(&s, colon); + PyUnicode_AppendAndDel(&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 = PyUnicode_FromString("{"); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, 0); + PyUnicode_AppendAndDel(&s, temp); + PyList_SET_ITEM(pieces, 0, s); + if (s == NULL) + goto Done; + + s = PyUnicode_FromString("}"); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); + PyUnicode_AppendAndDel(&temp, s); + PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); + if (temp == NULL) + goto Done; + + /* Paste them all together with ", " between. */ + s = PyUnicode_FromString(", "); + if (s == NULL) + goto Done; + result = PyUnicode_Join(s, pieces); + Py_DECREF(s); Done: - Py_XDECREF(pieces); - Py_XDECREF(colon); - Py_ReprLeave((PyObject *)mp); - return result; + Py_XDECREF(pieces); + Py_XDECREF(colon); + Py_ReprLeave((PyObject *)mp); + return result; } static Py_ssize_t dict_length(PyDictObject *mp) { - return mp->ma_used; + 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 (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + PyObject *v; + long hash; + PyDictEntry *ep; + assert(mp->ma_table != NULL); + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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); + 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*/ + (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; + 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; + 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; + 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; + 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; + 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. :-( - */ + /* 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; + 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) && PyDict_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - PyObject *oldvalue; - Py_ssize_t pos = 0; - PyObject *key; - long hash; - - if (dictresize(mp, Py_SIZE(seq))) - return NULL; - - while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) - return NULL; - } - return d; - } - - if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - Py_ssize_t pos = 0; - PyObject *key; - long hash; - - if (dictresize(mp, PySet_GET_SIZE(seq))) - return NULL; - - while (_PySet_NextEntry(seq, &pos, &key, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) - 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; + 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) && PyDict_CheckExact(seq)) { + PyDictObject *mp = (PyDictObject *)d; + PyObject *oldvalue; + Py_ssize_t pos = 0; + PyObject *key; + long hash; + + if (dictresize(mp, Py_SIZE(seq))) + return NULL; + + while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { + Py_INCREF(key); + Py_INCREF(value); + if (insertdict(mp, key, hash, value)) + return NULL; + } + return d; + } + + if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) { + PyDictObject *mp = (PyDictObject *)d; + Py_ssize_t pos = 0; + PyObject *key; + long hash; + + if (dictresize(mp, PySet_GET_SIZE(seq))) + return NULL; + + while (_PySet_NextEntry(seq, &pos, &key, &hash)) { + Py_INCREF(key); + Py_INCREF(value); + if (insertdict(mp, key, hash, value)) + 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; + 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; + PyObject *arg = NULL; + int result = 0; - if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) - result = -1; + 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) { - if (PyArg_ValidateKeywordArguments(kwds)) - result = PyDict_Merge(self, kwds, 1); - else - result = -1; - } - return result; + 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) { + if (PyArg_ValidateKeywordArguments(kwds)) + result = PyDict_Merge(self, kwds, 1); + else + result = -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; + if (dict_update_common(self, args, kwds, "update") != -1) + Py_RETURN_NONE; + return NULL; } /* Update unconditionally replaces existing items. @@ -1432,238 +1432,238 @@ dict_update(PyObject *self, PyObject *args, PyObject *kwds) 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; + 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; + Py_XDECREF(item); + Py_XDECREF(fast); + i = -1; Return: - Py_DECREF(it); - return Py_SAFE_DOWNCAST(i, Py_ssize_t, int); + 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); + 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; + 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); + return PyDict_Copy((PyObject*)mp); } PyObject * PyDict_Copy(PyObject *o) { - PyObject *copy; + 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; + 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; + 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); + 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); + 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); + if (mp == NULL || !PyDict_Check(mp)) { + PyErr_BadInternalCall(); + return NULL; + } + return dict_items((PyDictObject *)mp); } /* Return 1 if dicts equal, 0 if not, -1 if error. @@ -1673,271 +1673,271 @@ PyDict_Items(PyObject *mp) 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_GetItemWithError((PyObject *)b, key); - Py_DECREF(key); - if (bval == NULL) { - Py_DECREF(aval); - if (PyErr_Occurred()) - return -1; - return 0; - } - cmp = PyObject_RichCompareBool(aval, bval, Py_EQ); - Py_DECREF(aval); - if (cmp <= 0) /* error or not equal */ - return cmp; - } - } - return 1; + 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_GetItemWithError((PyObject *)b, key); + Py_DECREF(key); + if (bval == NULL) { + Py_DECREF(aval); + if (PyErr_Occurred()) + return -1; + 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 - res = Py_NotImplemented; - Py_INCREF(res); - return res; + 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 + res = Py_NotImplemented; + Py_INCREF(res); + return res; } static PyObject * dict_contains(register PyDictObject *mp, PyObject *key) { - long hash; - PyDictEntry *ep; + long hash; + PyDictEntry *ep; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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); + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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_get(register PyDictObject *mp, PyObject *args) { - PyObject *key; - PyObject *failobj = Py_None; - PyObject *val = NULL; - long hash; - PyDictEntry *ep; + 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 (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) + return NULL; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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 (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; - if (PyDict_SetItem((PyObject*)mp, key, failobj)) - val = NULL; - } - Py_XINCREF(val); - return val; + 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 (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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; + if (PyDict_SetItem((PyObject*)mp, key, failobj)) + val = NULL; + } + Py_XINCREF(val); + return val; } static PyObject * dict_clear(register PyDictObject *mp) { - PyDict_Clear((PyObject *)mp); - Py_RETURN_NONE; + 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; - } - PyErr_SetString(PyExc_KeyError, - "pop(): dictionary is empty"); - return NULL; - } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + 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; + } + PyErr_SetString(PyExc_KeyError, + "pop(): dictionary is empty"); + return NULL; + } + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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; + 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; + Py_ssize_t i = 0; + PyObject *pk; + PyObject *pv; - while (PyDict_Next(op, &i, &pk, &pv)) { - Py_VISIT(pk); - Py_VISIT(pv); - } - return 0; + 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; + PyDict_Clear(op); + return 0; } static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); @@ -1945,12 +1945,12 @@ static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); static PyObject * dict_sizeof(PyDictObject *mp) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyDictObject); - if (mp->ma_table != mp->ma_smalltable) - res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry); - return PyLong_FromSsize_t(res); + res = sizeof(PyDictObject); + if (mp->ma_table != mp->ma_smalltable) + res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry); + return PyLong_FromSsize_t(res); } PyDoc_STRVAR(contains__doc__, @@ -1997,126 +1997,126 @@ static PyObject *dictitems_new(PyObject *); static PyObject *dictvalues_new(PyObject *); PyDoc_STRVAR(keys__doc__, - "D.keys() -> a set-like object providing a view on D's keys"); + "D.keys() -> a set-like object providing a view on D's keys"); PyDoc_STRVAR(items__doc__, - "D.items() -> a set-like object providing a view on D's items"); + "D.items() -> a set-like object providing a view on D's items"); PyDoc_STRVAR(values__doc__, - "D.values() -> an object providing a view on D's values"); + "D.values() -> 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__}, - {"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)dictkeys_new, METH_NOARGS, - keys__doc__}, - {"items", (PyCFunction)dictitems_new, METH_NOARGS, - items__doc__}, - {"values", (PyCFunction)dictvalues_new, METH_NOARGS, - values__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__}, - {NULL, NULL} /* sentinel */ + {"__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__}, + {"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)dictkeys_new, METH_NOARGS, + keys__doc__}, + {"items", (PyCFunction)dictitems_new, METH_NOARGS, + items__doc__}, + {"values", (PyCFunction)dictvalues_new, METH_NOARGS, + values__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__}, + {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; + long hash; + PyDictObject *mp = (PyDictObject *)op; + PyDictEntry *ep; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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); + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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; + PyDictObject *mp = (PyDictObject *)op; + PyDictEntry *ep; - ep = (mp->ma_lookup)(mp, key, hash); - return ep == NULL ? -1 : (ep->me_value != NULL); + 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 */ + 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_unicode; - /* The object has been implicitely tracked by tp_alloc */ - if (type == &PyDict_Type) - _PyObject_GC_UNTRACK(d); + 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_unicode; + /* The object has been implicitely tracked by tp_alloc */ + if (type == &PyDict_Type) + _PyObject_GC_UNTRACK(d); #ifdef SHOW_CONVERSION_COUNTS - ++created; + ++created; #endif #ifdef SHOW_TRACK_COUNT - if (_PyObject_GC_IS_TRACKED(d)) - count_tracked++; - else - count_untracked++; + if (_PyObject_GC_IS_TRACKED(d)) + count_tracked++; + else + count_untracked++; #endif - } - return self; + } + return self; } static int dict_init(PyObject *self, PyObject *args, PyObject *kwds) { - return dict_update_common(self, args, kwds, "dict"); + return dict_update_common(self, args, kwds, "dict"); } static PyObject * dict_iter(PyDictObject *dict) { - return dictiter_new(dict, &PyDictIterKey_Type); + return dictiter_new(dict, &PyDictIterKey_Type); } PyDoc_STRVAR(dictionary_doc, @@ -2131,46 +2131,46 @@ PyDoc_STRVAR(dictionary_doc, " 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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict", + sizeof(PyDictObject), + 0, + (destructor)dict_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ @@ -2178,340 +2178,340 @@ PyTypeObject PyDict_Type = { PyObject * PyDict_GetItemString(PyObject *v, const char *key) { - PyObject *kv, *rv; - kv = PyUnicode_FromString(key); - if (kv == NULL) - return NULL; - rv = PyDict_GetItem(v, kv); - Py_DECREF(kv); - return rv; + PyObject *kv, *rv; + kv = PyUnicode_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 = PyUnicode_FromString(key); - if (kv == NULL) - return -1; - PyUnicode_InternInPlace(&kv); /* XXX Should we really? */ - err = PyDict_SetItem(v, kv, item); - Py_DECREF(kv); - return err; + PyObject *kv; + int err; + kv = PyUnicode_FromString(key); + if (kv == NULL) + return -1; + PyUnicode_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 = PyUnicode_FromString(key); - if (kv == NULL) - return -1; - err = PyDict_DelItem(v, kv); - Py_DECREF(kv); - return err; + PyObject *kv; + int err; + kv = PyUnicode_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; + 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; + 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); + 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; + 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 PyLong_FromSize_t(len); + Py_ssize_t len = 0; + if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used) + len = di->len; + return PyLong_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 */ + {"__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; + 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; + Py_DECREF(d); + di->di_dict = NULL; + return NULL; } PyTypeObject PyDictIterKey_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "dict_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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_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_reserved */ + 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; + 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; + Py_DECREF(d); + di->di_dict = NULL; + return NULL; } PyTypeObject PyDictIterValue_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "dict_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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_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_reserved */ + 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; + 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; + Py_DECREF(d); + di->di_dict = NULL; + return NULL; } PyTypeObject PyDictIterItem_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "dict_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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "dict_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_reserved */ + 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, }; @@ -2522,56 +2522,56 @@ PyTypeObject PyDictIterItem_Type = { /* The instance lay-out is the same for all three; but the type differs. */ typedef struct { - PyObject_HEAD - PyDictObject *dv_dict; + PyObject_HEAD + PyDictObject *dv_dict; } dictviewobject; static void dictview_dealloc(dictviewobject *dv) { - Py_XDECREF(dv->dv_dict); - PyObject_GC_Del(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; + 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; + 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; + 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: @@ -2587,102 +2587,102 @@ dictview_new(PyObject *dict, PyTypeObject *type) 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; + 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; + 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 *result; - - seq = PySequence_List((PyObject *)dv); - if (seq == NULL) - return NULL; + PyObject *seq; + PyObject *result; + + seq = PySequence_List((PyObject *)dv); + if (seq == NULL) + return NULL; - result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); - Py_DECREF(seq); - return result; + result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); + Py_DECREF(seq); + return result; } /*** dict_keys ***/ @@ -2690,164 +2690,164 @@ dictview_repr(dictviewobject *dv) static PyObject * dictkeys_iter(dictviewobject *dv) { - if (dv->dv_dict == NULL) { - Py_RETURN_NONE; - } - return dictiter_new(dv->dv_dict, &PyDictIterKey_Type); + 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); + 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 */ + (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; + 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; - } + tmp = PyObject_CallMethod(result, "difference_update", "O", other); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } - Py_DECREF(tmp); - return result; + 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; + 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; - } + tmp = PyObject_CallMethod(result, "intersection_update", "O", other); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } - Py_DECREF(tmp); - return result; + 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; + 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; - } + tmp = PyObject_CallMethod(result, "update", "O", other); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } - Py_DECREF(tmp); - return result; + 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; + 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; - } + tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O", + other); + if (tmp == NULL) { + Py_DECREF(result); + return NULL; + } - Py_DECREF(tmp); - return result; + Py_DECREF(tmp); + return result; } static PyNumberMethods dictviews_as_number = { - 0, /*nb_add*/ - (binaryfunc)dictviews_sub, /*nb_subtract*/ - 0, /*nb_multiply*/ - 0, /*nb_remainder*/ - 0, /*nb_divmod*/ - 0, /*nb_power*/ - 0, /*nb_negative*/ - 0, /*nb_positive*/ - 0, /*nb_absolute*/ - 0, /*nb_bool*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - (binaryfunc)dictviews_and, /*nb_and*/ - (binaryfunc)dictviews_xor, /*nb_xor*/ - (binaryfunc)dictviews_or, /*nb_or*/ + 0, /*nb_add*/ + (binaryfunc)dictviews_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 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 */ + {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,/* 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, + 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,/* 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); + return dictview_new(dict, &PyDictKeys_Type); } /*** dict_items ***/ @@ -2855,83 +2855,83 @@ dictkeys_new(PyObject *dict) static PyObject * dictitems_iter(dictviewobject *dv) { - if (dv->dv_dict == NULL) { - Py_RETURN_NONE; - } - return dictiter_new(dv->dv_dict, &PyDictIterItem_Type); + 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); + 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 */ + (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 */ + {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,/* 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, + 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,/* 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); + return dictview_new(dict, &PyDictItems_Type); } /*** dict_values ***/ @@ -2939,62 +2939,62 @@ dictitems_new(PyObject *dict) static PyObject * dictvalues_iter(dictviewobject *dv) { - if (dv->dv_dict == NULL) { - Py_RETURN_NONE; - } - return dictiter_new(dv->dv_dict, &PyDictIterValue_Type); + 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 */ + (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 */ + {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, + 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); + return dictview_new(dict, &PyDictValues_Type); } diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 3d9bfada9e..b579f9672f 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -3,159 +3,159 @@ #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 */ + 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[] = {"iterable", "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(PyLong_Check(start)); - en->en_index = PyLong_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; + enumobject *en; + PyObject *seq = NULL; + PyObject *start = NULL; + static char *kwlist[] = {"iterable", "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(PyLong_Check(start)); + en->en_index = PyLong_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); + 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; + 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 = PyLong_FromSsize_t(PY_SSIZE_T_MAX); - if (en->en_longindex == NULL) - return NULL; - } - if (one == NULL) { - one = PyLong_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 *one = NULL; + PyObject *result = en->en_result; + PyObject *next_index; + PyObject *stepped_up; + + if (en->en_longindex == NULL) { + en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX); + if (en->en_longindex == NULL) + return NULL; + } + if (one == NULL) { + one = PyLong_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 = PyLong_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; + 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 = PyLong_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, @@ -167,134 +167,134 @@ PyDoc_STRVAR(enum_doc, "for obtaining an indexed list: (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_reserved */ - 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 */ + 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_reserved */ + 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; + 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; - - reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache); - if (reversed_meth != NULL) { - PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); - Py_DECREF(reversed_meth); - return res; - } - else if (PyErr_Occurred()) - return NULL; - - 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; + 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; + + reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache); + if (reversed_meth != NULL) { + PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); + Py_DECREF(reversed_meth); + return res; + } + else if (PyErr_Occurred()) + return NULL; + + 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); + 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; + 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; + 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, @@ -305,64 +305,64 @@ PyDoc_STRVAR(reversed_doc, static PyObject * reversed_len(reversedobject *ro) { - Py_ssize_t position, seqsize; - - if (ro->seq == NULL) - return PyLong_FromLong(0); - seqsize = PySequence_Size(ro->seq); - if (seqsize == -1) - return NULL; - position = ro->index + 1; - return PyLong_FromSsize_t((seqsize < position) ? 0 : position); + Py_ssize_t position, seqsize; + + if (ro->seq == NULL) + return PyLong_FromLong(0); + seqsize = PySequence_Size(ro->seq); + if (seqsize == -1) + return NULL; + position = ro->index + 1; + return PyLong_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 */ + {"__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_reserved */ - 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 */ + 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_reserved */ + 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/Objects/exceptions.c b/Objects/exceptions.c index 64e21418bb..8200d4d321 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -270,7 +270,7 @@ BaseException_set_context(PyObject *self, PyObject *arg) { } else { /* PyException_SetContext steals this reference */ Py_INCREF(arg); - } + } PyException_SetContext(self, arg); return 0; } @@ -296,7 +296,7 @@ BaseException_set_cause(PyObject *self, PyObject *arg) { } else { /* PyException_SetCause steals this reference */ Py_INCREF(arg); - } + } PyException_SetCause(self, arg); return 0; } @@ -379,7 +379,7 @@ static PyTypeObject _PyExc_BaseException = { 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*/ + 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 */ @@ -1013,7 +1013,7 @@ SyntaxError_str(PySyntaxErrorObject *self) result = PyUnicode_FromFormat("%S (%U, line %ld)", self->msg ? self->msg : Py_None, filename, - PyLong_AsLongAndOverflow(self->lineno, &overflow)); + PyLong_AsLongAndOverflow(self->lineno, &overflow)); else if (filename) result = PyUnicode_FromFormat("%S (%U)", self->msg ? self->msg : Py_None, @@ -2011,25 +2011,25 @@ _PyExc_Init(void) PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); if (!PyExc_RecursionErrorInst) - Py_FatalError("Cannot pre-allocate RuntimeError instance for " - "recursion errors"); + 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 = PyUnicode_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); + PyBaseExceptionObject *err_inst = + (PyBaseExceptionObject *)PyExc_RecursionErrorInst; + PyObject *args_tuple; + PyObject *exc_message; + exc_message = PyUnicode_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); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index bbed57bc1b..3709e00bc1 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -14,10 +14,10 @@ #endif /* Newline flags */ -#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 */ +#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 */ #ifdef __cplusplus extern "C" { @@ -27,110 +27,110 @@ extern "C" { PyObject * PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, - char *errors, char *newline, int closefd) + char *errors, char *newline, int closefd) { - PyObject *io, *stream, *nameobj = NULL; - - io = PyImport_ImportModule("io"); - if (io == NULL) - return NULL; - stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode, - buffering, encoding, errors, - newline, closefd); - Py_DECREF(io); - if (stream == NULL) - return NULL; - if (name != NULL) { - nameobj = PyUnicode_DecodeFSDefault(name); - if (nameobj == NULL) - PyErr_Clear(); - else { - if (PyObject_SetAttrString(stream, "name", nameobj) < 0) - PyErr_Clear(); - Py_DECREF(nameobj); - } - } - return stream; + PyObject *io, *stream, *nameobj = NULL; + + io = PyImport_ImportModule("io"); + if (io == NULL) + return NULL; + stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode, + buffering, encoding, errors, + newline, closefd); + Py_DECREF(io); + if (stream == NULL) + return NULL; + if (name != NULL) { + nameobj = PyUnicode_DecodeFSDefault(name); + if (nameobj == NULL) + PyErr_Clear(); + else { + if (PyObject_SetAttrString(stream, "name", nameobj) < 0) + PyErr_Clear(); + Py_DECREF(nameobj); + } + } + return stream; } PyObject * PyFile_GetLine(PyObject *f, int n) { - PyObject *result; - - if (f == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - - { - 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 && !PyBytes_Check(result) && - !PyUnicode_Check(result)) { - Py_DECREF(result); - result = NULL; - PyErr_SetString(PyExc_TypeError, - "object.readline() returned non-string"); - } - } - - if (n < 0 && result != NULL && PyBytes_Check(result)) { - char *s = PyBytes_AS_STRING(result); - Py_ssize_t len = PyBytes_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) - _PyBytes_Resize(&result, len-1); - else { - PyObject *v; - v = PyBytes_FromStringAndSize(s, len-1); - Py_DECREF(result); - result = v; - } - } - } - 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; - } - } - } - return result; + PyObject *result; + + if (f == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + { + 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 && !PyBytes_Check(result) && + !PyUnicode_Check(result)) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_TypeError, + "object.readline() returned non-string"); + } + } + + if (n < 0 && result != NULL && PyBytes_Check(result)) { + char *s = PyBytes_AS_STRING(result); + Py_ssize_t len = PyBytes_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) + _PyBytes_Resize(&result, len-1); + else { + PyObject *v; + v = PyBytes_FromStringAndSize(s, len-1); + Py_DECREF(result); + result = v; + } + } + } + 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; + } + } + } + return result; } /* Interfaces to write objects/strings to file-like objects */ @@ -138,60 +138,60 @@ PyFile_GetLine(PyObject *f, int n) 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; - } - writer = PyObject_GetAttrString(f, "write"); - if (writer == NULL) - return -1; - if (flags & Py_PRINT_RAW) { - 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; + PyObject *writer, *value, *args, *result; + if (f == NULL) { + PyErr_SetString(PyExc_TypeError, "writeobject with NULL file"); + return -1; + } + writer = PyObject_GetAttrString(f, "write"); + if (writer == NULL) + return -1; + if (flags & Py_PRINT_RAW) { + 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 (!PyErr_Occurred()) { - PyObject *v = PyUnicode_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; + 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 (!PyErr_Occurred()) { + PyObject *v = PyUnicode_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 @@ -204,45 +204,45 @@ PyFile_WriteString(const char *s, PyObject *f) int PyObject_AsFileDescriptor(PyObject *o) { - int fd; - PyObject *meth; - - if (PyLong_Check(o)) { - fd = PyLong_AsLong(o); - } - else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL) - { - PyObject *fno = PyEval_CallObject(meth, NULL); - Py_DECREF(meth); - if (fno == NULL) - return -1; - - if (PyLong_Check(fno)) { - fd = PyLong_AsLong(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 == -1 && PyErr_Occurred()) - return -1; - if (fd < 0) { - PyErr_Format(PyExc_ValueError, - "file descriptor cannot be a negative integer (%i)", - fd); - return -1; - } - return fd; + int fd; + PyObject *meth; + + if (PyLong_Check(o)) { + fd = PyLong_AsLong(o); + } + else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL) + { + PyObject *fno = PyEval_CallObject(meth, NULL); + Py_DECREF(meth); + if (fno == NULL) + return -1; + + if (PyLong_Check(fno)) { + fd = PyLong_AsLong(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 == -1 && PyErr_Occurred()) + return -1; + if (fd < 0) { + PyErr_Format(PyExc_ValueError, + "file descriptor cannot be a negative integer (%i)", + fd); + return -1; + } + return fd; } /* @@ -262,68 +262,68 @@ PyObject_AsFileDescriptor(PyObject *o) char * Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) { - char *p = buf; - int c; - int newlinetypes = 0; - int skipnextlf = 0; - - if (fobj) { - errno = ENXIO; /* What can you do... */ - return NULL; - } - 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 ( 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 - ** exec(open("/dev/tty").read()). - */ - c = GETC(stream); - if ( c != '\n' ) - ungetc(c, stream); - } - if (p == buf) - return NULL; - return buf; + char *p = buf; + int c; + int newlinetypes = 0; + int skipnextlf = 0; + + if (fobj) { + errno = ENXIO; /* What can you do... */ + return NULL; + } + 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 ( 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 + ** exec(open("/dev/tty").read()). + */ + c = GETC(stream); + if ( c != '\n' ) + ungetc(c, stream); + } + if (p == buf) + return NULL; + return buf; } /* **************************** std printer **************************** @@ -332,195 +332,195 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) */ typedef struct { - PyObject_HEAD - int fd; + PyObject_HEAD + int fd; } PyStdPrinter_Object; static PyObject * stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews) { - PyStdPrinter_Object *self; + PyStdPrinter_Object *self; - assert(type != NULL && type->tp_alloc != NULL); + assert(type != NULL && type->tp_alloc != NULL); - self = (PyStdPrinter_Object *) type->tp_alloc(type, 0); - if (self != NULL) { - self->fd = -1; - } + self = (PyStdPrinter_Object *) type->tp_alloc(type, 0); + if (self != NULL) { + self->fd = -1; + } - return (PyObject *) self; + return (PyObject *) self; } static int fileio_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyErr_SetString(PyExc_TypeError, - "cannot create 'stderrprinter' instances"); - return -1; + PyErr_SetString(PyExc_TypeError, + "cannot create 'stderrprinter' instances"); + return -1; } PyObject * PyFile_NewStdPrinter(int fd) { - PyStdPrinter_Object *self; - - if (fd != fileno(stdout) && fd != fileno(stderr)) { - /* not enough infrastructure for PyErr_BadInternalCall() */ - return NULL; - } - - self = PyObject_New(PyStdPrinter_Object, - &PyStdPrinter_Type); - if (self != NULL) { - self->fd = fd; - } - return (PyObject*)self; + PyStdPrinter_Object *self; + + if (fd != fileno(stdout) && fd != fileno(stderr)) { + /* not enough infrastructure for PyErr_BadInternalCall() */ + return NULL; + } + + self = PyObject_New(PyStdPrinter_Object, + &PyStdPrinter_Type); + if (self != NULL) { + self->fd = fd; + } + return (PyObject*)self; } static PyObject * stdprinter_write(PyStdPrinter_Object *self, PyObject *args) { - char *c; - Py_ssize_t n; - - if (self->fd < 0) { - /* fd might be invalid on Windows - * I can't raise an exception here. It may lead to an - * unlimited recursion in the case stderr is invalid. - */ - Py_RETURN_NONE; - } - - if (!PyArg_ParseTuple(args, "s", &c)) { - return NULL; - } - n = strlen(c); - - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = write(self->fd, c, n); - Py_END_ALLOW_THREADS - - if (n < 0) { - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return PyLong_FromSsize_t(n); + char *c; + Py_ssize_t n; + + if (self->fd < 0) { + /* fd might be invalid on Windows + * I can't raise an exception here. It may lead to an + * unlimited recursion in the case stderr is invalid. + */ + Py_RETURN_NONE; + } + + if (!PyArg_ParseTuple(args, "s", &c)) { + return NULL; + } + n = strlen(c); + + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = write(self->fd, c, n); + Py_END_ALLOW_THREADS + + if (n < 0) { + if (errno == EAGAIN) + Py_RETURN_NONE; + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + return PyLong_FromSsize_t(n); } static PyObject * stdprinter_fileno(PyStdPrinter_Object *self) { - return PyLong_FromLong((long) self->fd); + return PyLong_FromLong((long) self->fd); } static PyObject * stdprinter_repr(PyStdPrinter_Object *self) { - return PyUnicode_FromFormat("", - self->fd, self); + return PyUnicode_FromFormat("", + self->fd, self); } static PyObject * stdprinter_noop(PyStdPrinter_Object *self) { - Py_RETURN_NONE; + Py_RETURN_NONE; } static PyObject * stdprinter_isatty(PyStdPrinter_Object *self) { - long res; - if (self->fd < 0) { - Py_RETURN_FALSE; - } + long res; + if (self->fd < 0) { + Py_RETURN_FALSE; + } - Py_BEGIN_ALLOW_THREADS - res = isatty(self->fd); - Py_END_ALLOW_THREADS + Py_BEGIN_ALLOW_THREADS + res = isatty(self->fd); + Py_END_ALLOW_THREADS - return PyBool_FromLong(res); + return PyBool_FromLong(res); } static PyMethodDef stdprinter_methods[] = { - {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, - {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, - {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""}, - {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""}, - {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""}, - {NULL, NULL} /*sentinel */ + {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, + {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""}, + {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""}, + {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""}, + {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""}, + {NULL, NULL} /*sentinel */ }; static PyObject * get_closed(PyStdPrinter_Object *self, void *closure) { - Py_INCREF(Py_False); - return Py_False; + Py_INCREF(Py_False); + return Py_False; } static PyObject * get_mode(PyStdPrinter_Object *self, void *closure) { - return PyUnicode_FromString("w"); + return PyUnicode_FromString("w"); } static PyObject * get_encoding(PyStdPrinter_Object *self, void *closure) { - Py_RETURN_NONE; + Py_RETURN_NONE; } static PyGetSetDef stdprinter_getsetlist[] = { - {"closed", (getter)get_closed, NULL, "True if the file is closed"}, - {"encoding", (getter)get_encoding, NULL, "Encoding of the file"}, - {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {0}, + {"closed", (getter)get_closed, NULL, "True if the file is closed"}, + {"encoding", (getter)get_encoding, NULL, "Encoding of the file"}, + {"mode", (getter)get_mode, NULL, "String giving the file mode"}, + {0}, }; PyTypeObject PyStdPrinter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "stderrprinter", /* tp_name */ - sizeof(PyStdPrinter_Object), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)stdprinter_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 */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - stdprinter_methods, /* tp_methods */ - 0, /* tp_members */ - stdprinter_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - fileio_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - stdprinter_new, /* tp_new */ - PyObject_Del, /* tp_free */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "stderrprinter", /* tp_name */ + sizeof(PyStdPrinter_Object), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)stdprinter_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 */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + stdprinter_methods, /* tp_methods */ + 0, /* tp_members */ + stdprinter_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + fileio_init, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + stdprinter_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 238022b3bc..9f94003184 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -22,13 +22,13 @@ 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)) +#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]; + struct _floatblock *next; + PyFloatObject objects[N_FLOATOBJECTS]; }; typedef struct _floatblock PyFloatBlock; @@ -39,31 +39,31 @@ 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; + 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; + return DBL_MAX; } double PyFloat_GetMin(void) { - return DBL_MIN; + return DBL_MIN; } static PyTypeObject FloatInfoType; @@ -76,183 +76,183 @@ 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} + {"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 + "sys.float_info", /* name */ + floatinfo__doc__, /* doc */ + floatinfo_fields, /* fields */ + 11 }; PyObject * PyFloat_GetInfo(void) { - PyObject* floatinfo; - int pos = 0; + PyObject* floatinfo; + int pos = 0; - floatinfo = PyStructSequence_New(&FloatInfoType); - if (floatinfo == NULL) { - return NULL; - } + floatinfo = PyStructSequence_New(&FloatInfoType); + if (floatinfo == NULL) { + return NULL; + } #define SetIntFlag(flag) \ - PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag)) + PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_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); + 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; + + 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; + 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; } PyObject * PyFloat_FromString(PyObject *v) { - const char *s, *last, *end; - double x; - char buffer[256]; /* for errors */ - char *s_buffer = NULL; - Py_ssize_t len; - PyObject *result = NULL; - - 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); - } - 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; - } + const char *s, *last, *end; + double x; + char buffer[256]; /* for errors */ + char *s_buffer = NULL; + Py_ssize_t len; + PyObject *result = NULL; + + 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); + } + 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: - if (s_buffer) - PyMem_FREE(s_buffer); - return result; + if (s_buffer) + PyMem_FREE(s_buffer); + 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); + 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)) { - PyErr_SetString(PyExc_TypeError, - "nb_float should return float object"); - return -1; - } - - val = PyFloat_AS_DOUBLE(fo); - Py_DECREF(fo); - - return val; + 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)) { + PyErr_SetString(PyExc_TypeError, + "nb_float should return float object"); + return -1; + } + + val = PyFloat_AS_DOUBLE(fo); + Py_DECREF(fo); + + return val; } /* Macro and helper that convert PyObject obj to a C double and store @@ -261,32 +261,32 @@ PyFloat_AsDouble(PyObject *op) 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; +#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; /* Methods */ static int convert_to_double(PyObject **v, double *dbl) { - register PyObject *obj = *v; - - 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; + register PyObject *obj = *v; + + 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; } static PyObject * @@ -298,7 +298,7 @@ float_str_or_repr(PyFloatObject *v, int precision, char format_code) Py_DTSF_ADD_DOT_0, NULL); if (!buf) - return PyErr_NoMemory(); + return PyErr_NoMemory(); result = PyUnicode_FromString(buf); PyMem_Free(buf); return result; @@ -334,341 +334,341 @@ float_str(PyFloatObject *v) 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 (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 (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 = PyLong_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; + 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 (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 (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 = PyLong_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); + 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; + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } static long float_hash(PyFloatObject *v) { - return _Py_HashDouble(v->ob_fval); + 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); + 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); + 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); + 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); + 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; - } + 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); + 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); + 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; - } + if (wx == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "float modulo"); + return NULL; + } #endif - PyFPE_START_PROTECT("modulo", return 0) - mod = fmod(vx, wx); - /* note: checking mod*wx < 0 is incorrect -- underflows to - 0 if wx < sqrt(smallest nonzero double) */ - if (mod && ((wx < 0) != (mod < 0))) { - mod += wx; - } - PyFPE_END_PROTECT(mod) - return PyFloat_FromDouble(mod); + PyFPE_START_PROTECT("modulo", return 0) + mod = fmod(vx, wx); + /* note: checking mod*wx < 0 is incorrect -- underflows to + 0 if wx < sqrt(smallest nonzero double) */ + if (mod && ((wx < 0) != (mod < 0))) { + mod += wx; + } + 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); + 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; + 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 @@ -678,123 +678,123 @@ float_floor_div(PyObject *v, PyObject *w) 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)) { - /* Negative numbers raised to fractional powers - * become complex. - */ - return PyComplex_Type.tp_as_number->nb_power(v, w, z); - } - /* 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); + 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)) { + /* Negative numbers raised to fractional powers + * become complex. + */ + return PyComplex_Type.tp_as_number->nb_power(v, w, z); + } + /* 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 @@ -802,97 +802,97 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) static PyObject * float_neg(PyFloatObject *v) { - return PyFloat_FromDouble(-v->ob_fval); + return PyFloat_FromDouble(-v->ob_fval); } static PyObject * float_abs(PyFloatObject *v) { - return PyFloat_FromDouble(fabs(v->ob_fval)); + return PyFloat_FromDouble(fabs(v->ob_fval)); } static int float_bool(PyFloatObject *v) { - return v->ob_fval != 0.0; + return v->ob_fval != 0.0; } 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; + 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)); + 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)); + 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)); + 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 >= and <= LONG_{MIN,MAX} would - * still be vulnerable: if a long has more bits of precision than - * a double, casting MIN/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. - */ - if (LONG_MIN < wholepart && wholepart < LONG_MAX) { - const long aslong = (long)wholepart; - return PyLong_FromLong(aslong); - } - return PyLong_FromDouble(wholepart); + 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 >= and <= LONG_{MIN,MAX} would + * still be vulnerable: if a long has more bits of precision than + * a double, casting MIN/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. + */ + if (LONG_MIN < wholepart && wholepart < LONG_MAX) { + const long aslong = (long)wholepart; + return PyLong_FromLong(aslong); + } + return PyLong_FromDouble(wholepart); } /* double_round: rounds a finite double to the closest multiple of @@ -907,49 +907,49 @@ float_trunc(PyObject *v) static PyObject * double_round(double x, int ndigits) { - double rounded; - Py_ssize_t buflen, mybuflen=100; - char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; - int decpt, sign; - PyObject *result = NULL; - - /* round to a decimal string */ - buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - - /* 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'). */ - buflen = buf_end - buf; - 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; - rounded = _Py_dg_strtod(mybuf, NULL); - 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); + double rounded; + Py_ssize_t buflen, mybuflen=100; + char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; + int decpt, sign; + PyObject *result = NULL; + + /* round to a decimal string */ + buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + + /* 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'). */ + buflen = buf_end - buf; + 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; + rounded = _Py_dg_strtod(mybuf, NULL); + 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; + _Py_dg_freedtoa(buf); + return result; } #else /* PY_NO_SHORT_FLOAT_REPR */ @@ -959,47 +959,47 @@ double_round(double x, int ndigits) { static PyObject * 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-half-even */ - z = 2.0*round(y/2.0); - - 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); + 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-half-even */ + z = 2.0*round(y/2.0); + + 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 */ @@ -1009,45 +1009,45 @@ double_round(double x, int ndigits) { static PyObject * float_round(PyObject *v, PyObject *args) { - double x, rounded; - PyObject *o_ndigits = NULL; - Py_ssize_t ndigits; - - x = PyFloat_AsDouble(v); - if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) - return NULL; - if (o_ndigits == NULL) { - /* single-argument round: round to nearest integer */ - rounded = round(x); - if (fabs(x-rounded) == 0.5) - /* halfway case: round to even */ - rounded = 2.0*round(x/2.0); - return PyLong_FromDouble(rounded); - } - - /* interpret second argument as a Py_ssize_t; clips on overflow */ - ndigits = PyNumber_AsSsize_t(o_ndigits, NULL); - if (ndigits == -1 && PyErr_Occurred()) - return NULL; - - /* nans and infinities round to themselves */ - if (!Py_IS_FINITE(x)) - return PyFloat_FromDouble(x); - - /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x - always rounds to itself. For ndigits < NDIGITS_MIN, x always - rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ + double x, rounded; + PyObject *o_ndigits = NULL; + Py_ssize_t ndigits; + + x = PyFloat_AsDouble(v); + if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) + return NULL; + if (o_ndigits == NULL) { + /* single-argument round: round to nearest integer */ + rounded = round(x); + if (fabs(x-rounded) == 0.5) + /* halfway case: round to even */ + rounded = 2.0*round(x/2.0); + return PyLong_FromDouble(rounded); + } + + /* interpret second argument as a Py_ssize_t; clips on overflow */ + ndigits = PyNumber_AsSsize_t(o_ndigits, NULL); + if (ndigits == -1 && PyErr_Occurred()) + return NULL; + + /* nans and infinities round to themselves */ + if (!Py_IS_FINITE(x)) + return PyFloat_FromDouble(x); + + /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x + always rounds to itself. For ndigits < NDIGITS_MIN, x always + rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ #define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103)) #define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103)) - if (ndigits > NDIGITS_MAX) - /* return x */ - return PyFloat_FromDouble(x); - else if (ndigits < NDIGITS_MIN) - /* return 0.0, but with sign of x */ - return PyFloat_FromDouble(0.0*x); - else - /* finite x, and ndigits is not unreasonably large */ - return double_round(x, (int)ndigits); + if (ndigits > NDIGITS_MAX) + /* return x */ + return PyFloat_FromDouble(x); + else if (ndigits < NDIGITS_MIN) + /* return 0.0, but with sign of x */ + return PyFloat_FromDouble(0.0*x); + else + /* finite x, and ndigits is not unreasonably large */ + return double_round(x, (int)ndigits); #undef NDIGITS_MAX #undef NDIGITS_MIN } @@ -1055,11 +1055,11 @@ float_round(PyObject *v, PyObject *args) static PyObject * float_float(PyObject *v) { - if (PyFloat_CheckExact(v)) - Py_INCREF(v); - else - v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); - return 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 */ @@ -1067,73 +1067,73 @@ float_float(PyObject *v) static char char_from_hex(int x) { - assert(0 <= x && x < 16); - return "0123456789abcdef"[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; + 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 */ @@ -1145,54 +1145,54 @@ hex_from_char(char c) { 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 PyUnicode_FromString("-0x0.0p+0"); - else - return PyUnicode_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 PyUnicode_FromFormat("-0x%sp%c%d", s, esign, e); - else - return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e); + 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 PyUnicode_FromString("-0x0.0p+0"); + else + return PyUnicode_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 PyUnicode_FromFormat("-0x%sp%c%d", s, esign, e); + else + return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e); } PyDoc_STRVAR(float_hex_doc, @@ -1209,242 +1209,242 @@ Return a hexadecimal representation of a floating-point number.\n\ 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, negate=0; - 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. - */ - - s = _PyUnicode_AsStringAndSize(arg, &length); - if (s == NULL) - return NULL; - s_end = s + length; - - /******************** - * Parse the string * - ********************/ - - /* leading whitespace */ - while (Py_ISSPACE(*s)) - s++; - - /* infinities and nans */ - x = _Py_parse_inf_or_nan(s, &coeff_end); - if (coeff_end != s) { - s = coeff_end; - goto finished; - } - - /* optional sign */ - if (*s == '-') { - s++; - negate = 1; - } - else if (*s == '+') - s++; - - /* [0x] */ - s_store = s; - if (*s == '0') { - s++; - if (*s == 'x' || *s == 'X') - s++; - else - s = s_store; - } - - /* coefficient: [. ] */ - 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 ] */ - 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; + 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, negate=0; + 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. + */ + + s = _PyUnicode_AsStringAndSize(arg, &length); + if (s == NULL) + return NULL; + s_end = s + length; + + /******************** + * Parse the string * + ********************/ + + /* leading whitespace */ + while (Py_ISSPACE(*s)) + s++; + + /* infinities and nans */ + x = _Py_parse_inf_or_nan(s, &coeff_end); + if (coeff_end != s) { + s = coeff_end; + goto finished; + } + + /* optional sign */ + if (*s == '-') { + s++; + negate = 1; + } + else if (*s == '+') + s++; + + /* [0x] */ + s_store = s; + if (*s == '0') { + s++; + if (*s == 'x' || *s == 'X') + s++; + else + s = s_store; + } + + /* coefficient: [. ] */ + 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 ] */ + 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)); +#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)", negate ? -x : x); - if (result_as_float == NULL) - return NULL; - result = PyObject_CallObject(cls, result_as_float); - Py_DECREF(result_as_float); - return result; + /* 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)", negate ? -x : 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; + 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; + 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; + PyErr_SetString(PyExc_ValueError, + "hexadecimal string too long to convert"); + return NULL; } PyDoc_STRVAR(float_fromhex_doc, @@ -1460,79 +1460,79 @@ Create a floating-point number from a hexadecimal string.\n\ 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; + 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); \ + prev = obj; \ + obj = call; \ + Py_DECREF(prev); \ - CONVERT_TO_DOUBLE(v, self); + CONVERT_TO_DOUBLE(v, self); - if (Py_IS_INFINITY(self)) { - PyErr_SetString(PyExc_OverflowError, - "Cannot pass infinity to float.as_integer_ratio."); - return NULL; - } + 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; - } + 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; - } - - result_pair = PyTuple_Pack(2, numerator, denominator); + 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; + } + + result_pair = PyTuple_Pack(2, numerator, denominator); #undef INPLACE_UPDATE error: - Py_XDECREF(py_exponent); - Py_XDECREF(denominator); - Py_XDECREF(numerator); - return result_pair; + Py_XDECREF(py_exponent); + Py_XDECREF(denominator); + Py_XDECREF(numerator); + return result_pair; } PyDoc_STRVAR(float_as_integer_ratio_doc, @@ -1556,18 +1556,18 @@ 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 (PyUnicode_CheckExact(x)) - return PyFloat_FromString(x); - return PyNumber_Float(x); + 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 (PyUnicode_CheckExact(x)) + return PyFloat_FromString(x); + return PyNumber_Float(x); } /* Wimpy, slow approach to tp_new calls for subtypes of float: @@ -1578,33 +1578,33 @@ float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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; + 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); + 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 + unknown_format, ieee_big_endian_format, ieee_little_endian_format } float_format_type; static float_format_type double_format, float_format; @@ -1613,42 +1613,42 @@ 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 (!PyUnicode_Check(arg)) { - PyErr_Format(PyExc_TypeError, - "__getformat__() argument must be string, not %.500s", - Py_TYPE(arg)->tp_name); - return NULL; - } - s = _PyUnicode_AsString(arg); - if (s == NULL) - return NULL; - 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 PyUnicode_FromString("unknown"); - case ieee_little_endian_format: - return PyUnicode_FromString("IEEE, little-endian"); - case ieee_big_endian_format: - return PyUnicode_FromString("IEEE, big-endian"); - default: - Py_FatalError("insane float_format or double_format"); - return NULL; - } + char* s; + float_format_type r; + + if (!PyUnicode_Check(arg)) { + PyErr_Format(PyExc_TypeError, + "__getformat__() argument must be string, not %.500s", + Py_TYPE(arg)->tp_name); + return NULL; + } + s = _PyUnicode_AsString(arg); + if (s == NULL) + return NULL; + 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 PyUnicode_FromString("unknown"); + case ieee_little_endian_format: + return PyUnicode_FromString("IEEE, little-endian"); + case ieee_big_endian_format: + return PyUnicode_FromString("IEEE, big-endian"); + default: + Py_FatalError("insane float_format or double_format"); + return NULL; + } } PyDoc_STRVAR(float_getformat_doc, @@ -1664,57 +1664,57 @@ PyDoc_STRVAR(float_getformat_doc, 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; + 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, @@ -1733,19 +1733,19 @@ PyDoc_STRVAR(float_setformat_doc, static PyObject * float_getzero(PyObject *v, void *closure) { - return PyFloat_FromDouble(0.0); + return PyFloat_FromDouble(0.0); } static PyObject * float__format__(PyObject *self, PyObject *args) { - PyObject *format_spec; + PyObject *format_spec; - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - return _PyFloat_FormatAdvanced(self, - PyUnicode_AS_UNICODE(format_spec), - PyUnicode_GET_SIZE(format_spec)); + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + return _PyFloat_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); } PyDoc_STRVAR(float__format__doc, @@ -1755,45 +1755,45 @@ PyDoc_STRVAR(float__format__doc, static PyMethodDef float_methods[] = { - {"conjugate", (PyCFunction)float_float, METH_NOARGS, - "Returns self, the complex conjugate of any float."}, - {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS, - "Returns the Integral closest to x between 0 and x."}, - {"__round__", (PyCFunction)float_round, METH_VARARGS, - "Returns the Integral closest to x, rounding half toward even.\n" - "When an argument is passed, works like built-in round(x, ndigits)."}, - {"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, - "Returns True if the float is an integer."}, + {"conjugate", (PyCFunction)float_float, METH_NOARGS, + "Returns self, the complex conjugate of any float."}, + {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS, + "Returns the Integral closest to x between 0 and x."}, + {"__round__", (PyCFunction)float_round, METH_VARARGS, + "Returns the Integral closest to x, rounding half toward even.\n" + "When an argument is passed, works like built-in round(x, ndigits)."}, + {"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, + "Returns True if the float is an integer."}, #if 0 - {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS, - "Returns True if the float is positive or negative infinite."}, - {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS, - "Returns True if the float is finite, neither infinite nor NaN."}, - {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS, - "Returns True if the float is not a number (NaN)."}, + {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS, + "Returns True if the float is positive or negative infinite."}, + {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS, + "Returns True if the float is finite, neither infinite nor NaN."}, + {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS, + "Returns 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 */ + {"__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", + {"real", (getter)float_float, (setter)NULL, "the real part of a complex number", NULL}, - {"imag", + {"imag", (getter)float_getzero, (setter)NULL, "the imaginary part of a complex number", NULL}, @@ -1807,229 +1807,229 @@ 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_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_bool, /*nb_bool*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - float_trunc, /*nb_int*/ - 0, /*nb_reserved*/ - float_float, /*nb_float*/ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 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 */ + float_add, /*nb_add*/ + float_sub, /*nb_subtract*/ + float_mul, /*nb_multiply*/ + 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_bool, /*nb_bool*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + float_trunc, /*nb_int*/ + 0, /*nb_reserved*/ + float_float, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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_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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "float", + sizeof(PyFloatObject), + 0, + (destructor)float_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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_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. */ + /* 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; - } + { + 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; + 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; - } + { + 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; + detected_float_format = unknown_format; #endif - double_format = detected_double_format; - float_format = detected_float_format; + double_format = detected_double_format; + float_format = detected_float_format; - /* Init float info */ - if (FloatInfoType.tp_name == 0) - PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); + /* 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 floats 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; + PyFloatObject *p; + PyFloatBlock *list, *next; + int i; + int u; /* remaining unfreed floats 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, - "# \n", - p, (long)Py_REFCNT(p), buf); - PyMem_Free(buf); - } - } - } - list = list->next; - } - } + 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, + "# \n", + p, (long)Py_REFCNT(p), buf); + PyMem_Free(buf); + } + } + } + list = list->next; + } + } } /*---------------------------------------------------------------------------- @@ -2038,406 +2038,406 @@ PyFloat_Fini(void) 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; - } + 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; + 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; - - /* 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; - } + 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; + + /* 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; - } + 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; - } + 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/Objects/frameobject.c b/Objects/frameobject.c index 26abd5f6ca..191c6b622f 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -15,39 +15,39 @@ #define OFF(x) offsetof(PyFrameObject, x) static PyMemberDef frame_memberlist[] = { - {"f_back", T_OBJECT, OFF(f_back), READONLY}, - {"f_code", T_OBJECT, OFF(f_code), READONLY}, - {"f_builtins", T_OBJECT, OFF(f_builtins),READONLY}, - {"f_globals", T_OBJECT, OFF(f_globals), READONLY}, - {"f_lasti", T_INT, OFF(f_lasti), READONLY}, - {NULL} /* Sentinel */ + {"f_back", T_OBJECT, OFF(f_back), READONLY}, + {"f_code", T_OBJECT, OFF(f_code), READONLY}, + {"f_builtins", T_OBJECT, OFF(f_builtins),READONLY}, + {"f_globals", T_OBJECT, OFF(f_globals), READONLY}, + {"f_lasti", T_INT, OFF(f_lasti), READONLY}, + {NULL} /* Sentinel */ }; static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - PyFrame_FastToLocals(f); - Py_INCREF(f->f_locals); - return f->f_locals; + 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); + 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 PyLong_FromLong(PyFrame_GetLineNumber(f)); + return PyLong_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 + * 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 @@ -64,309 +64,309 @@ frame_getlineno(PyFrameObject *f, void *closure) static int frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) { - int new_lineno = 0; /* The new value of f_lineno */ - long l_new_lineno; - int overflow; - 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 (!PyLong_CheckExact(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. */ - l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); - if (overflow + int new_lineno = 0; /* The new value of f_lineno */ + long l_new_lineno; + int overflow; + 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 (!PyLong_CheckExact(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. */ + l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); + if (overflow #if SIZEOF_LONG > SIZEOF_INT - || l_new_lineno > INT_MAX - || l_new_lineno < INT_MIN + || l_new_lineno > INT_MAX + || l_new_lineno < INT_MIN #endif - ) { - PyErr_SetString(PyExc_ValueError, - "lineno out of range"); - return -1; - } - new_lineno = (int)l_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; - PyBytes_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. */ - PyBytes_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: - 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) { - 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) { - 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: - 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; + ) { + PyErr_SetString(PyExc_ValueError, + "lineno out of range"); + return -1; + } + new_lineno = (int)l_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; + PyBytes_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. */ + PyBytes_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: + 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) { + 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) { + 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: + 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; + PyObject* trace = f->f_trace; - if (trace == NULL) - trace = Py_None; + if (trace == NULL) + trace = Py_None; - Py_INCREF(trace); + Py_INCREF(trace); - return trace; + return trace; } static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { - PyObject* old_value; + PyObject* old_value; - /* We rely on f_lineno being accurate when f_trace is set. */ - f->f_lineno = PyFrame_GetLineNumber(f); + /* 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); + old_value = f->f_trace; + Py_XINCREF(v); + f->f_trace = v; + Py_XDECREF(old_value); - return 0; + return 0; } 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}, - {0} + {"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}, + {0} }; /* Stack frames are allocated and deallocated at a considerable rate. @@ -383,7 +383,7 @@ static PyGetSetDef frame_getsetlist[] = { 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; @@ -394,10 +394,10 @@ static PyGetSetDef frame_getsetlist[] = { 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 + 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 @@ -413,307 +413,307 @@ static PyGetSetDef frame_getsetlist[] = { */ static PyFrameObject *free_list = NULL; -static int numfree = 0; /* number of frames currently in free_list */ +static int numfree = 0; /* number of frames currently in free_list */ /* max value for numfree */ -#define PyFrame_MAXFREELIST 200 +#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) + 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; + 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); - } + 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; + 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 *); + 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 PyLong_FromSsize_t(res); + return PyLong_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 */ + {"__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_reserved */ - 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 */ + 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_reserved */ + 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 = PyUnicode_InternFromString("__builtins__"); - if (builtin_object == NULL) - return 0; - return 1; + builtin_object = PyUnicode_InternFromString("__builtins__"); + if (builtin_object == NULL) + return 0; + return 1; } PyFrameObject * PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, - PyObject *locals) + PyObject *locals) { - PyFrameObject *back = tstate->frame; - PyFrameObject *f; - PyObject *builtins; - Py_ssize_t i; + 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; - } + 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; if_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; + 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; if_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 */ @@ -721,28 +721,28 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, 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 *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; + 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. + + 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, @@ -758,29 +758,29 @@ PyFrame_BlockPop(PyFrameObject *f) static void map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, - int deref) + 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(PyUnicode_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(); - } - } + 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(PyUnicode_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. @@ -788,7 +788,7 @@ map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, 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. + 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, @@ -806,150 +806,150 @@ map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, static void dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, - int deref, int clear) + 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(PyUnicode_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); - } + 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(PyUnicode_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); + /* 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); + /* 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; + 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; + (void)PyFrame_ClearFreeList(); + Py_XDECREF(builtin_object); + builtin_object = NULL; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 35fc32d659..c2ad964e58 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -9,215 +9,215 @@ 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_kwdefaults = NULL; /* No keyword only defaults */ - op->func_closure = NULL; - consts = ((PyCodeObject *)code)->co_consts; - if (PyTuple_Size(consts) >= 1) { - doc = PyTuple_GetItem(consts, 0); - if (!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; - op->func_annotations = NULL; - - /* __module__: If module name is in globals, use it. - Otherwise, use None. - */ - if (!__name__) { - __name__ = PyUnicode_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; + 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_kwdefaults = NULL; /* No keyword only defaults */ + op->func_closure = NULL; + consts = ((PyCodeObject *)code)->co_consts; + if (PyTuple_Size(consts) >= 1) { + doc = PyTuple_GetItem(consts, 0); + if (!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; + op->func_annotations = NULL; + + /* __module__: If module name is in globals, use it. + Otherwise, use None. + */ + if (!__name__) { + __name__ = PyUnicode_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; + 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; + 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; + 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; + 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; + 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_GetKwDefaults(PyObject *op) { - if (!PyFunction_Check(op)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyFunctionObject *) op) -> func_kwdefaults; + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_kwdefaults; } int PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) { - if (!PyFunction_Check(op)) { - PyErr_BadInternalCall(); - return -1; - } - if (defaults == Py_None) - defaults = NULL; - else if (defaults && PyDict_Check(defaults)) { - Py_INCREF(defaults); - } - else { - PyErr_SetString(PyExc_SystemError, - "non-dict keyword only default args"); - return -1; - } - Py_XDECREF(((PyFunctionObject *)op) -> func_kwdefaults); - ((PyFunctionObject *) op) -> func_kwdefaults = defaults; - return 0; + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (defaults == Py_None) + defaults = NULL; + else if (defaults && PyDict_Check(defaults)) { + Py_INCREF(defaults); + } + else { + PyErr_SetString(PyExc_SystemError, + "non-dict keyword only default args"); + return -1; + } + Py_XDECREF(((PyFunctionObject *)op) -> func_kwdefaults); + ((PyFunctionObject *) op) -> func_kwdefaults = defaults; + return 0; } PyObject * PyFunction_GetClosure(PyObject *op) { - if (!PyFunction_Check(op)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyFunctionObject *) op) -> func_closure; + 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; + 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; } PyObject * PyFunction_GetAnnotations(PyObject *op) { - if (!PyFunction_Check(op)) { - PyErr_BadInternalCall(); - return NULL; - } - return ((PyFunctionObject *) op) -> func_annotations; + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_annotations; } int PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) { - if (!PyFunction_Check(op)) { - PyErr_BadInternalCall(); - return -1; - } - if (annotations == Py_None) - annotations = NULL; - else if (annotations && PyDict_Check(annotations)) { - Py_INCREF(annotations); - } - else { - PyErr_SetString(PyExc_SystemError, - "non-dict annotations"); - return -1; - } - Py_XDECREF(((PyFunctionObject *)op) -> func_annotations); - ((PyFunctionObject *) op) -> func_annotations = annotations; - return 0; + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (annotations == Py_None) + annotations = NULL; + else if (annotations && PyDict_Check(annotations)) { + Py_INCREF(annotations); + } + else { + PyErr_SetString(PyExc_SystemError, + "non-dict annotations"); + return -1; + } + Py_XDECREF(((PyFunctionObject *)op) -> func_annotations); + ((PyFunctionObject *) op) -> func_annotations = annotations; + return 0; } /* Methods */ @@ -225,224 +225,224 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) #define OFF(x) offsetof(PyFunctionObject, x) static PyMemberDef func_memberlist[] = { - {"__closure__", T_OBJECT, OFF(func_closure), - RESTRICTED|READONLY}, - {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED}, - {"__globals__", T_OBJECT, OFF(func_globals), - RESTRICTED|READONLY}, - {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED}, - {NULL} /* Sentinel */ + {"__closure__", T_OBJECT, OFF(func_closure), + RESTRICTED|READONLY}, + {"__doc__", T_OBJECT, OFF(func_doc), PY_WRITE_RESTRICTED}, + {"__globals__", T_OBJECT, OFF(func_globals), + RESTRICTED|READONLY}, + {"__module__", T_OBJECT, OFF(func_module), PY_WRITE_RESTRICTED}, + {NULL} /* Sentinel */ }; static PyObject * func_get_dict(PyFunctionObject *op) { - 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; + 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; - - /* 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; + PyObject *tmp; + + /* 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) { - Py_INCREF(op->func_code); - return op->func_code; + 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; - - /* 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, - "%U() requires a code object with %zd free vars," - " not %zd", - op->func_name, - nclosure, nfree); - return -1; - } - tmp = op->func_code; - Py_INCREF(value); - op->func_code = value; - Py_DECREF(tmp); - return 0; + PyObject *tmp; + Py_ssize_t nfree, nclosure; + + /* 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, + "%U() requires a code object with %zd free vars," + " not %zd", + 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; + Py_INCREF(op->func_name); + return op->func_name; } static int func_set_name(PyFunctionObject *op, PyObject *value) { - PyObject *tmp; + PyObject *tmp; - /* Not legal to del f.func_name or to set it to anything - * other than a string object. */ - if (value == NULL || !PyUnicode_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; + /* Not legal to del f.func_name or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_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 (op->func_defaults == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - Py_INCREF(op->func_defaults); - return op->func_defaults; + 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; + PyObject *tmp; - /* 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; + /* 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 PyObject * func_get_kwdefaults(PyFunctionObject *op) { - if (op->func_kwdefaults == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - Py_INCREF(op->func_kwdefaults); - return op->func_kwdefaults; + if (op->func_kwdefaults == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(op->func_kwdefaults); + return op->func_kwdefaults; } static int func_set_kwdefaults(PyFunctionObject *op, PyObject *value) { - PyObject *tmp; + PyObject *tmp; - if (value == Py_None) - value = NULL; - /* Legal to del f.func_kwdefaults. - * Can only set func_kwdefaults to NULL or a dict. */ - if (value != NULL && !PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__kwdefaults__ must be set to a dict object"); - return -1; - } - tmp = op->func_kwdefaults; - Py_XINCREF(value); - op->func_kwdefaults = value; - Py_XDECREF(tmp); - return 0; + if (value == Py_None) + value = NULL; + /* Legal to del f.func_kwdefaults. + * Can only set func_kwdefaults to NULL or a dict. */ + if (value != NULL && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + tmp = op->func_kwdefaults; + Py_XINCREF(value); + op->func_kwdefaults = value; + Py_XDECREF(tmp); + return 0; } static PyObject * func_get_annotations(PyFunctionObject *op) { - if (op->func_annotations == NULL) { - op->func_annotations = PyDict_New(); - if (op->func_annotations == NULL) - return NULL; - } - Py_INCREF(op->func_annotations); - return op->func_annotations; + if (op->func_annotations == NULL) { + op->func_annotations = PyDict_New(); + if (op->func_annotations == NULL) + return NULL; + } + Py_INCREF(op->func_annotations); + return op->func_annotations; } static int func_set_annotations(PyFunctionObject *op, PyObject *value) { - PyObject *tmp; - - if (value == Py_None) - value = NULL; - /* Legal to del f.func_annotations. - * Can only set func_annotations to NULL (through C api) - * or a dict. */ - if (value != NULL && !PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__annotations__ must be set to a dict object"); - return -1; - } - tmp = op->func_annotations; - Py_XINCREF(value); - op->func_annotations = value; - Py_XDECREF(tmp); - return 0; + PyObject *tmp; + + if (value == Py_None) + value = NULL; + /* Legal to del f.func_annotations. + * Can only set func_annotations to NULL (through C api) + * or a dict. */ + if (value != NULL && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + tmp = op->func_annotations; + Py_XINCREF(value); + op->func_annotations = value; + Py_XDECREF(tmp); + return 0; } static PyGetSetDef func_getsetlist[] = { - {"__code__", (getter)func_get_code, (setter)func_set_code}, - {"__defaults__", (getter)func_get_defaults, - (setter)func_set_defaults}, - {"__kwdefaults__", (getter)func_get_kwdefaults, - (setter)func_set_kwdefaults}, - {"__annotations__", (getter)func_get_annotations, - (setter)func_set_annotations}, - {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, - {"__name__", (getter)func_get_name, (setter)func_set_name}, - {NULL} /* Sentinel */ + {"__code__", (getter)func_get_code, (setter)func_set_code}, + {"__defaults__", (getter)func_get_defaults, + (setter)func_set_defaults}, + {"__kwdefaults__", (getter)func_get_kwdefaults, + (setter)func_set_kwdefaults}, + {"__annotations__", (getter)func_get_annotations, + (setter)func_set_annotations}, + {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, + {"__name__", (getter)func_get_name, (setter)func_set_name}, + {NULL} /* Sentinel */ }; PyDoc_STRVAR(func_doc, @@ -455,241 +455,241 @@ 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 + + if len(code.co_freevars) == 0: + closure = NULL else: - len(closure) == len(code.co_freevars) + 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 && !PyUnicode_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, - "%U requires closure of length %zd, not %zd", - 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; + 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 && !PyUnicode_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, + "%U requires closure of length %zd, not %zd", + 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_kwdefaults); - Py_XDECREF(op->func_doc); - Py_XDECREF(op->func_dict); - Py_XDECREF(op->func_closure); - Py_XDECREF(op->func_annotations); - PyObject_GC_Del(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_kwdefaults); + Py_XDECREF(op->func_doc); + Py_XDECREF(op->func_dict); + Py_XDECREF(op->func_closure); + Py_XDECREF(op->func_annotations); + PyObject_GC_Del(op); } static PyObject* func_repr(PyFunctionObject *op) { - return PyUnicode_FromFormat("", - op->func_name, op); + return PyUnicode_FromFormat("", + 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_kwdefaults); - Py_VISIT(f->func_doc); - Py_VISIT(f->func_name); - Py_VISIT(f->func_dict); - Py_VISIT(f->func_closure); - Py_VISIT(f->func_annotations); - return 0; + Py_VISIT(f->func_code); + Py_VISIT(f->func_globals); + Py_VISIT(f->func_module); + Py_VISIT(f->func_defaults); + Py_VISIT(f->func_kwdefaults); + Py_VISIT(f->func_doc); + Py_VISIT(f->func_name); + Py_VISIT(f->func_dict); + Py_VISIT(f->func_closure); + Py_VISIT(f->func_annotations); + 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_KW_DEFAULTS(func), - PyFunction_GET_CLOSURE(func)); - - Py_XDECREF(kwtuple); - - return result; + 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_KW_DEFAULTS(func), + 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) { - Py_INCREF(func); - return func; - } - return PyMethod_New(func, obj); + if (obj == Py_None || obj == NULL) { + Py_INCREF(func); + return func; + } + return PyMethod_New(func, obj); } 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_reserved */ - (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 */ + 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_reserved */ + (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 */ }; @@ -700,9 +700,9 @@ PyTypeObject PyFunction_Type = { To declare a class method, use this idiom: class C: - def f(cls, arg1, arg2, ...): ... - f = classmethod(f) - + 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 @@ -713,66 +713,66 @@ PyTypeObject PyFunction_Type = { */ typedef struct { - PyObject_HEAD - PyObject *cm_callable; + 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); + _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; + Py_VISIT(cm->cm_callable); + return 0; } static int cm_clear(classmethod *cm) { - Py_CLEAR(cm->cm_callable); - return 0; + Py_CLEAR(cm->cm_callable); + return 0; } static PyObject * cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { - classmethod *cm = (classmethod *)self; + 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); + 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); } static int cm_init(PyObject *self, PyObject *args, PyObject *kwds) { - classmethod *cm = (classmethod *)self; - PyObject *callable; + 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; + 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 */ + {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY}, + {NULL} /* Sentinel */ }; PyDoc_STRVAR(classmethod_doc, @@ -797,57 +797,57 @@ 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_reserved */ - 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 */ + 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_reserved */ + 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; + classmethod *cm = (classmethod *) + PyType_GenericAlloc(&PyClassMethod_Type, 0); + if (cm != NULL) { + Py_INCREF(callable); + cm->cm_callable = callable; + } + return (PyObject *)cm; } @@ -857,8 +857,8 @@ PyClassMethod_New(PyObject *callable) To declare a static method, use this idiom: class C: - def f(arg1, arg2, ...): ... - f = staticmethod(f) + 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. @@ -868,66 +868,66 @@ PyClassMethod_New(PyObject *callable) */ typedef struct { - PyObject_HEAD - PyObject *sm_callable; + 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); + _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; + Py_VISIT(sm->sm_callable); + return 0; } static int sm_clear(staticmethod *sm) { - Py_XDECREF(sm->sm_callable); - sm->sm_callable = NULL; + Py_XDECREF(sm->sm_callable); + sm->sm_callable = NULL; - return 0; + return 0; } static PyObject * sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { - staticmethod *sm = (staticmethod *)self; + 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; + 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; + 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; + 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 */ + {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY}, + {NULL} /* Sentinel */ }; PyDoc_STRVAR(staticmethod_doc, @@ -939,8 +939,8 @@ 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\ + 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\ @@ -949,55 +949,55 @@ 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_reserved */ - 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 */ + 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_reserved */ + 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; + staticmethod *sm = (staticmethod *) + PyType_GenericAlloc(&PyStaticMethod_Type, 0); + if (sm != NULL) { + Py_INCREF(callable); + sm->sm_callable = callable; + } + return (PyObject *)sm; } diff --git a/Objects/genobject.c b/Objects/genobject.c index fb8415f7ff..34ee7dcc1f 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -10,103 +10,103 @@ static int gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { - Py_VISIT((PyObject *)gen->gi_frame); - Py_VISIT(gen->gi_code); - return 0; + Py_VISIT((PyObject *)gen->gi_frame); + Py_VISIT(gen->gi_code); + return 0; } static void gen_dealloc(PyGenObject *gen) { - PyObject *self = (PyObject *) gen; + PyObject *self = (PyObject *) gen; - _PyObject_GC_UNTRACK(gen); + _PyObject_GC_UNTRACK(gen); - if (gen->gi_weakreflist != NULL) - PyObject_ClearWeakRefs(self); + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); - _PyObject_GC_TRACK(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. :( */ - } + 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); + _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. */ - 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); - - /* 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; + 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. */ + 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); + + /* 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, @@ -116,7 +116,7 @@ return next yielded value or raise StopIteration."); static PyObject * gen_send(PyGenObject *gen, PyObject *arg) { - return gen_send_ex(gen, arg, 0); + return gen_send_ex(gen, arg, 0); } PyDoc_STRVAR(close_doc, @@ -125,83 +125,83 @@ PyDoc_STRVAR(close_doc, 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; + 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. - */ + 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; + --self->ob_type->tp_frees; + --self->ob_type->tp_allocs; #endif } @@ -214,89 +214,89 @@ 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 , */ - 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 " - "deriving from BaseException, not %s", - typ->ob_type->tp_name); - goto failed_throw; - } - - PyErr_Restore(typ, val, tb); - return gen_send_ex(gen, Py_None, 1); + 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 , */ + 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 " + "deriving from BaseException, 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; + /* 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); + return gen_send_ex(gen, NULL, 0); } static PyObject * gen_repr(PyGenObject *gen) { - return PyUnicode_FromFormat("", - ((PyCodeObject *)gen->gi_code)->co_name, - gen); + return PyUnicode_FromFormat("", + ((PyCodeObject *)gen->gi_code)->co_name, + gen); } static PyObject * gen_get_name(PyGenObject *gen) { - PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name; - Py_INCREF(name); - return name; + PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name; + Py_INCREF(name); + return name; } @@ -304,109 +304,109 @@ 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} + {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, + {NULL} }; static PyMemberDef gen_memberlist[] = { - {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, - {"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY}, - {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, - {NULL} /* Sentinel */ + {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, + {"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY}, + {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, + {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 */ + {"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_reserved */ - (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 */ + 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_reserved */ + (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; + 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; + 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 */ + 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; - } + /* 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; + /* No blocks except loops, it's safe to skip finalization. */ + return 0; } diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 174bd98642..b534b4af8e 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -3,230 +3,230 @@ #include "Python.h" typedef struct { - PyObject_HEAD - long it_index; - PyObject *it_seq; /* Set to NULL when iterator is exhausted */ + 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; + 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); + _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; + 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; + 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 PyLong_FromSsize_t(len); - } - return PyLong_FromLong(0); + 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 PyLong_FromSsize_t(len); + } + return PyLong_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 */ + {"__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_reserved */ - 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 */ + 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_reserved */ + 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 */ + 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; + 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); + _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; + 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; + 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_reserved */ - 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 */ + 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_reserved */ + 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/Objects/listobject.c b/Objects/listobject.c index ae8721e653..0dab7843af 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -5,7 +5,7 @@ #ifdef STDC_HEADERS #include #else -#include /* For size_t */ +#include /* For size_t */ #endif /* Ensure ob_item has room for at least newsize elements, and set @@ -24,52 +24,52 @@ 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 <= ((~(size_t)0) / 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; + 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 <= ((~(size_t)0) / 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 */ @@ -81,12 +81,12 @@ 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))); + 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 @@ -100,77 +100,77 @@ static int numfree = 0; void PyList_Fini(void) { - PyListObject *op; + PyListObject *op; - while (numfree) { - op = free_list[--numfree]; - assert(PyList_CheckExact(op)); - PyObject_GC_Del(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; + PyListObject *op; + size_t nbytes; #ifdef SHOW_ALLOC_COUNT - static int initialized = 0; - if (!initialized) { - Py_AtExit(show_alloc); - initialized = 1; - } + 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); + 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++; + count_reuse++; #endif - } else { - op = PyObject_GC_New(PyListObject, &PyList_Type); - if (op == NULL) - return NULL; + } else { + op = PyObject_GC_New(PyListObject, &PyList_Type); + if (op == NULL) + return NULL; #ifdef SHOW_ALLOC_COUNT - count_alloc++; + 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; + } + 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); + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + else + return Py_SIZE(op); } static PyObject *indexerr = NULL; @@ -178,117 +178,117 @@ 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 = PyUnicode_FromString( - "list index out of range"); - if (indexerr == NULL) - return NULL; - } - PyErr_SetObject(PyExc_IndexError, indexerr); - return NULL; - } - return ((PyListObject *)op) -> ob_item[i]; + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (i < 0 || i >= Py_SIZE(op)) { + if (indexerr == NULL) { + indexerr = PyUnicode_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; + 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; + 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); + 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); + 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; - } + 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; + if (list_resize(self, n+1) == -1) + return -1; - Py_INCREF(v); - PyList_SET_ITEM(self, n, v); - return 0; + 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; + if (PyList_Check(op) && (newitem != NULL)) + return app1((PyListObject *)op, newitem); + PyErr_BadInternalCall(); + return -1; } /* Methods */ @@ -296,271 +296,271 @@ PyList_Append(PyObject *op, PyObject *newitem) 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) + 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 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 ? PyUnicode_FromString("[...]") : NULL; - } - - if (Py_SIZE(v) == 0) { - result = PyUnicode_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 = PyUnicode_FromString("["); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyList_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyUnicode_FromString("]"); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); - PyUnicode_AppendAndDel(&temp, s); - PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); + Py_ssize_t i; + PyObject *s, *temp; + PyObject *pieces = NULL, *result = NULL; + + i = Py_ReprEnter((PyObject*)v); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("[...]") : NULL; + } + + if (Py_SIZE(v) == 0) { + result = PyUnicode_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 = PyUnicode_FromString("["); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, 0); + PyUnicode_AppendAndDel(&s, temp); + PyList_SET_ITEM(pieces, 0, s); + if (s == NULL) + goto Done; + + s = PyUnicode_FromString("]"); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); + PyUnicode_AppendAndDel(&temp, s); + PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); + if (temp == NULL) + goto Done; + + /* Paste them all together with ", " between. */ + s = PyUnicode_FromString(", "); + if (s == NULL) + goto Done; + result = PyUnicode_Join(s, pieces); + Py_DECREF(s); Done: - Py_XDECREF(pieces); - Py_ReprLeave((PyObject *)v); - return result; + Py_XDECREF(pieces); + Py_ReprLeave((PyObject *)v); + return result; } static Py_ssize_t list_length(PyListObject *a) { - return Py_SIZE(a); + return Py_SIZE(a); } static int list_contains(PyListObject *a, PyObject *el) { - Py_ssize_t i; - int cmp; + 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; + 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 = PyUnicode_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]; + if (i < 0 || i >= Py_SIZE(a)) { + if (indexerr == NULL) { + indexerr = PyUnicode_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; + 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); + 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; - } + 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; + 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; - size = Py_SIZE(a) * n; - if (n && size/n != Py_SIZE(a)) - return PyErr_NoMemory(); - 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; + Py_ssize_t i, j; + Py_ssize_t size; + PyListObject *np; + PyObject **p, **items; + PyObject *elem; + if (n < 0) + n = 0; + size = Py_SIZE(a) * n; + if (n && size/n != Py_SIZE(a)) + return PyErr_NoMemory(); + 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; + 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. @@ -572,368 +572,368 @@ list_clear(PyListObject *a) 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 */ + /* 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; + 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; + 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); + 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; + 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; - } + 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 (n < 1) { + (void)list_clear(self); + Py_INCREF(self); + return (PyObject *)self; + } - if (size > PY_SSIZE_T_MAX / n) { - return PyErr_NoMemory(); - } + if (size > PY_SSIZE_T_MAX / n) { + return PyErr_NoMemory(); + } - if (list_resize(self, size*n) == -1) - return NULL; + 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; + 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; + 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; + 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; + 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; + 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; + Py_DECREF(it); + return NULL; } PyObject * _PyList_Extend(PyListObject *self, PyObject *b) { - return listextend(self, b); + return listextend(self, b); } static PyObject * list_inplace_concat(PyListObject *self, PyObject *other) { - PyObject *result; + PyObject *result; - result = listextend(self, other); - if (result == NULL) - return result; - Py_DECREF(result); - Py_INCREF(self); - return (PyObject *)self; + 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; + 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); + assert(lo && hi); - --hi; - while (lo < hi) { - PyObject *t = *lo; - *lo = *hi; - *hi = t; - ++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 @@ -951,7 +951,7 @@ reverse_slice(PyObject **lo, PyObject **hi) started. It makes more sense in context . X and Y are PyObject*s. */ #define IFLT(X, Y) if ((k = ISLT(X, Y)) < 0) goto fail; \ - if (k) + 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 @@ -967,48 +967,48 @@ reverse_slice(PyObject **lo, PyObject **hi) static int binarysort(PyObject **lo, PyObject **hi, PyObject **start) { - 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; + 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 -1; } /* @@ -1032,35 +1032,35 @@ Returns -1 in case of error. static Py_ssize_t count_run(PyObject **lo, PyObject **hi, 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; + 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; + return -1; } /* @@ -1087,78 +1087,78 @@ 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) { - 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; + 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; + return -1; } /* @@ -1178,78 +1178,78 @@ 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) { - 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; + 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; + return -1; } /* The maximum number of entries in a MergeState's pending-runs stack. @@ -1272,48 +1272,48 @@ fail: * a convenient way to pass state around among the helper functions. */ struct s_slice { - PyObject **base; - Py_ssize_t len; + PyObject **base; + Py_ssize_t len; }; typedef struct s_MergeState { - /* 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]; + /* 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) { - assert(ms != NULL); - ms->a = ms->temparray; - ms->alloced = MERGESTATE_TEMP_SIZE; - ms->n = 0; - ms->min_gallop = MIN_GALLOP; + assert(ms != NULL); + 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 @@ -1323,11 +1323,11 @@ merge_init(MergeState *ms) 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; + 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. @@ -1336,28 +1336,28 @@ merge_freemem(MergeState *ms) 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)) + 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. @@ -1369,125 +1369,125 @@ 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 **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; - 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); - 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); - 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); - 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; - } + Py_ssize_t k; + 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; + 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); + 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); + 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); + 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; + result = 0; Fail: - if (na) - memcpy(dest, pa, na * sizeof(PyObject*)); - return result; + 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; + 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 @@ -1499,134 +1499,134 @@ CopyB: 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 **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; - 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); - 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); - 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); - 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; - } + Py_ssize_t k; + 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; + 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); + 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); + 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); + 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; + result = 0; Fail: - if (nb) - memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*)); - return result; + 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; + 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. @@ -1635,56 +1635,56 @@ CopyA: static Py_ssize_t merge_at(MergeState *ms, Py_ssize_t i) { - PyObject **pa, **pb; - Py_ssize_t na, nb; - Py_ssize_t k; - - 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). - */ - k = gallop_right(*pb, pa, na, 0); - 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); - 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); + PyObject **pa, **pb; + Py_ssize_t na, nb; + Py_ssize_t k; + + 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). + */ + k = gallop_right(*pb, pa, na, 0); + 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); + 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 @@ -1700,25 +1700,25 @@ merge_at(MergeState *ms, Py_ssize_t i) 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) { - 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; + 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) { + 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 @@ -1729,17 +1729,17 @@ merge_collapse(MergeState *ms) static int merge_force_collapse(MergeState *ms) { - struct s_slice *p = ms->pending; + 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; + 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 @@ -1755,14 +1755,14 @@ merge_force_collapse(MergeState *ms) 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 */ + 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; + 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 @@ -1773,9 +1773,9 @@ merge_compute_minrun(Py_ssize_t n) a full record. */ typedef struct { - PyObject_HEAD - PyObject *key; - PyObject *value; + PyObject_HEAD + PyObject *key; + PyObject *value; } sortwrapperobject; PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key."); @@ -1785,51 +1785,51 @@ static void sortwrapper_dealloc(sortwrapperobject *); PyTypeObject PySortWrapper_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_reserved */ - 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 */ - sortwrapper_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)sortwrapper_richcompare, /* tp_richcompare */ + 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_reserved */ + 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 */ + 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, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - return PyObject_RichCompare(a->key, b->key, op); + if (!PyObject_TypeCheck(b, &PySortWrapper_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); + Py_XDECREF(so->key); + Py_XDECREF(so->value); + PyObject_Del(so); } /* Returns a new reference to a sortwrapper. @@ -1838,30 +1838,30 @@ sortwrapper_dealloc(sortwrapperobject *so) static PyObject * build_sortwrapper(PyObject *key, PyObject *value) { - sortwrapperobject *so; + sortwrapperobject *so; - so = PyObject_New(sortwrapperobject, &PySortWrapper_Type); - if (so == NULL) - return NULL; - so->key = key; - so->value = value; - return (PyObject *)so; + so = PyObject_New(sortwrapperobject, &PySortWrapper_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; + PyObject *value; - if (!PyObject_TypeCheck(so, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - value = ((sortwrapperobject *)so)->value; - Py_INCREF(value); - return value; + if (!PyObject_TypeCheck(so, &PySortWrapper_Type)) { + PyErr_SetString(PyExc_TypeError, + "expected a sortwrapperobject"); + return NULL; + } + value = ((sortwrapperobject *)so)->value; + Py_INCREF(value); + return value; } /* An adaptive, stable, natural mergesort. See listsort.txt. @@ -1872,163 +1872,163 @@ sortwrapper_getvalue(PyObject *so) 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 *result = NULL; /* guilty until proved innocent */ - int reverse = 0; - PyObject *keyfunc = NULL; - Py_ssize_t i; - PyObject *key, *value, *kvpair; - static char *kwlist[] = {"key", "reverse", 0}; - - assert(self != NULL); - assert (PyList_Check(self)); - if (args != NULL) { - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:sort", - kwlist, &keyfunc, &reverse)) - return NULL; - if (Py_SIZE(args) > 0) { - PyErr_SetString(PyExc_TypeError, - "must use keyword argument for key function"); - return NULL; - } - } - if (keyfunc == Py_None) - keyfunc = NULL; - - /* 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); - - 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, &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) < 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); + 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 *result = NULL; /* guilty until proved innocent */ + int reverse = 0; + PyObject *keyfunc = NULL; + Py_ssize_t i; + PyObject *key, *value, *kvpair; + static char *kwlist[] = {"key", "reverse", 0}; + + assert(self != NULL); + assert (PyList_Check(self)); + if (args != NULL) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:sort", + kwlist, &keyfunc, &reverse)) + return NULL; + if (Py_SIZE(args) > 0) { + PyErr_SetString(PyExc_TypeError, + "must use keyword argument for key function"); + return NULL; + } + } + if (keyfunc == Py_None) + keyfunc = NULL; + + /* 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); + + 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, &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) < 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; + 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); + 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_XINCREF(result); - return result; + 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_XINCREF(result); + return result; } #undef IFLT #undef ISLT @@ -2036,262 +2036,262 @@ dsu_fail: 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; + 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; + 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; + 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; + 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; + 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 PyLong_FromSsize_t(i); - else if (cmp < 0) - return NULL; - } - if (err_format == NULL) { - err_format = PyUnicode_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 = PyUnicode_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; + 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 PyLong_FromSsize_t(i); + else if (cmp < 0) + return NULL; + } + if (err_format == NULL) { + err_format = PyUnicode_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 = PyUnicode_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; + 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 PyLong_FromSsize_t(count); + 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 PyLong_FromSsize_t(count); } static PyObject * listremove(PyListObject *self, PyObject *v) { - Py_ssize_t i; + 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; + 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; + Py_ssize_t i; - for (i = Py_SIZE(o); --i >= 0; ) - Py_VISIT(o->ob_item[i]); - return 0; + 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); + 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}; + PyObject *arg = NULL; + static char *kwlist[] = {"sequence", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg)) - return -1; + 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); + /* 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; + /* 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; + Py_ssize_t res; - res = sizeof(PyListObject) + self->allocated * sizeof(void*); - return PyLong_FromSsize_t(res); + res = sizeof(PyListObject) + self->allocated * sizeof(void*); + return PyLong_FromSsize_t(res); } static PyObject *list_iter(PyObject *seq); @@ -2328,32 +2328,32 @@ PyDoc_STRVAR(sort_doc, 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 */ + {"__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 */ - 0, /* sq_slice */ - (ssizeobjargproc)list_ass_item, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)list_contains, /* sq_contains */ - (binaryfunc)list_inplace_concat, /* sq_inplace_concat */ - (ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */ + (lenfunc)list_length, /* sq_length */ + (binaryfunc)list_concat, /* sq_concat */ + (ssizeargfunc)list_repeat, /* sq_repeat */ + (ssizeargfunc)list_item, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)list_ass_item, /* sq_ass_item */ + 0, /* 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, @@ -2363,275 +2363,275 @@ PyDoc_STRVAR(list_doc, 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; - } + 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; - } + 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 + (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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list", + sizeof(PyListObject), + 0, + (destructor)list_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + PyObject_HEAD + long it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ } listiterobject; static PyObject *list_iter(PyObject *); @@ -2643,119 +2643,119 @@ 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 */ + {"__length_hint__", (PyCFunction)listiter_len, METH_NOARGS, length_hint_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyListIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "list_iterator", /* 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_reserved */ - 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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list_iterator", /* 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_reserved */ + 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; + 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; + 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); + _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; + Py_VISIT(it->it_seq); + return 0; } static PyObject * listiter_next(listiterobject *it) { - PyListObject *seq; - PyObject *item; + PyListObject *seq; + PyObject *item; - assert(it != NULL); - seq = it->it_seq; - if (seq == NULL) - return NULL; - assert(PyList_Check(seq)); + 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; - } + 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; + 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 PyLong_FromSsize_t(len); - } - return PyLong_FromLong(0); + Py_ssize_t len; + if (it->it_seq) { + len = PyList_GET_SIZE(it->it_seq) - it->it_index; + if (len >= 0) + return PyLong_FromSsize_t(len); + } + return PyLong_FromLong(0); } /*********************** List Reverse Iterator **************************/ typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ + PyObject_HEAD + Py_ssize_t it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ } listreviterobject; static PyObject *list_reversed(PyListObject *, PyObject *); @@ -2765,101 +2765,101 @@ 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 */ + {"__length_hint__", (PyCFunction)listreviter_len, METH_NOARGS, length_hint_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyListRevIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "list_reverseiterator", /* 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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list_reverseiterator", /* 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_reserved */ + 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; + 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; + 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); + 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; + 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; + 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; + 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); + 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/Objects/longobject.c b/Objects/longobject.c index 2229aed2f3..d4b26d65b9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -11,16 +11,16 @@ #include #ifndef NSMALLPOSINTS -#define NSMALLPOSINTS 257 +#define NSMALLPOSINTS 257 #endif #ifndef NSMALLNEGINTS -#define NSMALLNEGINTS 5 +#define NSMALLNEGINTS 5 #endif /* convert a PyLong of size 1, 0 or -1 to an sdigit */ -#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ - (Py_SIZE(x) == 0 ? (sdigit)0 : \ - (sdigit)(x)->ob_digit[0])) +#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ + (Py_SIZE(x) == 0 ? (sdigit)0 : \ + (sdigit)(x)->ob_digit[0])) #define ABS(x) ((x) < 0 ? -(x) : (x)) #if NSMALLNEGINTS + NSMALLPOSINTS > 0 @@ -37,32 +37,32 @@ int quick_int_allocs, quick_neg_int_allocs; static PyObject * get_small_int(sdigit ival) { - PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); - Py_INCREF(v); + PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); + Py_INCREF(v); #ifdef COUNT_ALLOCS - if (ival >= 0) - quick_int_allocs++; - else - quick_neg_int_allocs++; + if (ival >= 0) + quick_int_allocs++; + else + quick_neg_int_allocs++; #endif - return v; + return v; } #define CHECK_SMALL_INT(ival) \ - do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ - return get_small_int((sdigit)ival); \ - } while(0) + do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ + return get_small_int((sdigit)ival); \ + } while(0) -static PyLongObject * +static PyLongObject * maybe_small_long(PyLongObject *v) { - if (v && ABS(Py_SIZE(v)) <= 1) { - sdigit ival = MEDIUM_VALUE(v); - if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { - Py_DECREF(v); - return (PyLongObject *)get_small_int(ival); - } - } - return v; + if (v && ABS(Py_SIZE(v)) <= 1) { + sdigit ival = MEDIUM_VALUE(v); + if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { + Py_DECREF(v); + return (PyLongObject *)get_small_int(ival); + } + } + return v; } #else #define CHECK_SMALL_INT(ival) @@ -72,10 +72,10 @@ maybe_small_long(PyLongObject *v) /* If a freshly-allocated long is already shared, it must be a small integer, so negating it must go to PyLong_FromLong */ #define NEGATE(x) \ - do if (Py_REFCNT(x) == 1) Py_SIZE(x) = -Py_SIZE(x); \ - else { PyObject* tmp=PyLong_FromLong(-MEDIUM_VALUE(x)); \ - Py_DECREF(x); (x) = (PyLongObject*)tmp; } \ - while(0) + do if (Py_REFCNT(x) == 1) Py_SIZE(x) = -Py_SIZE(x); \ + else { PyObject* tmp=PyLong_FromLong(-MEDIUM_VALUE(x)); \ + Py_DECREF(x); (x) = (PyLongObject*)tmp; } \ + while(0) /* For long multiplication, use the O(N**2) school algorithm unless * both operands contain more than KARATSUBA_CUTOFF digits (this * being an internal Python long digit, in base BASE). @@ -96,7 +96,7 @@ maybe_small_long(PyLongObject *v) #define MIN(x, y) ((x) > (y) ? (y) : (x)) #define SIGCHECK(PyTryBlock) \ - if (PyErr_CheckSignals()) PyTryBlock \ + if (PyErr_CheckSignals()) PyTryBlock \ /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature @@ -105,68 +105,68 @@ maybe_small_long(PyLongObject *v) static PyLongObject * long_normalize(register PyLongObject *v) { - Py_ssize_t j = ABS(Py_SIZE(v)); - Py_ssize_t i = j; - - while (i > 0 && v->ob_digit[i-1] == 0) - --i; - if (i != j) - Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; - return v; + Py_ssize_t j = ABS(Py_SIZE(v)); + Py_ssize_t i = j; + + while (i > 0 && v->ob_digit[i-1] == 0) + --i; + if (i != j) + Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i; + return v; } /* Allocate a new long int object with size digits. Return NULL and set exception if we run out of memory. */ #define MAX_LONG_DIGITS \ - ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) + ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) PyLongObject * _PyLong_New(Py_ssize_t size) { - PyLongObject *result; - /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + - sizeof(digit)*size. Previous incarnations of this code used - sizeof(PyVarObject) instead of the offsetof, but this risks being - incorrect in the presence of padding between the PyVarObject header - and the digits. */ - if (size > (Py_ssize_t)MAX_LONG_DIGITS) { - PyErr_SetString(PyExc_OverflowError, - "too many digits in integer"); - return NULL; - } - result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + - size*sizeof(digit)); - if (!result) { - PyErr_NoMemory(); - return NULL; - } - return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); + PyLongObject *result; + /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + + sizeof(digit)*size. Previous incarnations of this code used + sizeof(PyVarObject) instead of the offsetof, but this risks being + incorrect in the presence of padding between the PyVarObject header + and the digits. */ + if (size > (Py_ssize_t)MAX_LONG_DIGITS) { + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + return NULL; + } + result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) + + size*sizeof(digit)); + if (!result) { + PyErr_NoMemory(); + return NULL; + } + return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); } PyObject * _PyLong_Copy(PyLongObject *src) { - PyLongObject *result; - Py_ssize_t i; - - assert(src != NULL); - i = Py_SIZE(src); - if (i < 0) - i = -(i); - if (i < 2) { - sdigit ival = src->ob_digit[0]; - if (Py_SIZE(src) < 0) - ival = -ival; - CHECK_SMALL_INT(ival); - } - result = _PyLong_New(i); - if (result != NULL) { - Py_SIZE(result) = Py_SIZE(src); - while (--i >= 0) - result->ob_digit[i] = src->ob_digit[i]; - } - return (PyObject *)result; + PyLongObject *result; + Py_ssize_t i; + + assert(src != NULL); + i = Py_SIZE(src); + if (i < 0) + i = -(i); + if (i < 2) { + sdigit ival = src->ob_digit[0]; + if (Py_SIZE(src) < 0) + ival = -ival; + CHECK_SMALL_INT(ival); + } + result = _PyLong_New(i); + if (result != NULL) { + Py_SIZE(result) = Py_SIZE(src); + while (--i >= 0) + result->ob_digit[i] = src->ob_digit[i]; + } + return (PyObject *)result; } /* Create a new long int object from a C long int */ @@ -174,68 +174,68 @@ _PyLong_Copy(PyLongObject *src) PyObject * PyLong_FromLong(long ival) { - PyLongObject *v; - unsigned long abs_ival; - unsigned long t; /* unsigned so >> doesn't propagate sign bit */ - int ndigits = 0; - int sign = 1; - - CHECK_SMALL_INT(ival); - - if (ival < 0) { - /* negate: can't write this as abs_ival = -ival since that - invokes undefined behaviour when ival is LONG_MIN */ - abs_ival = 0U-(unsigned long)ival; - sign = -1; - } - else { - abs_ival = (unsigned long)ival; - } - - /* Fast path for single-digit ints */ - if (!(abs_ival >> PyLong_SHIFT)) { - v = _PyLong_New(1); - if (v) { - Py_SIZE(v) = sign; - v->ob_digit[0] = Py_SAFE_DOWNCAST( - abs_ival, unsigned long, digit); - } - return (PyObject*)v; - } + PyLongObject *v; + unsigned long abs_ival; + unsigned long t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int sign = 1; + + CHECK_SMALL_INT(ival); + + if (ival < 0) { + /* negate: can't write this as abs_ival = -ival since that + invokes undefined behaviour when ival is LONG_MIN */ + abs_ival = 0U-(unsigned long)ival; + sign = -1; + } + else { + abs_ival = (unsigned long)ival; + } + + /* Fast path for single-digit ints */ + if (!(abs_ival >> PyLong_SHIFT)) { + v = _PyLong_New(1); + if (v) { + Py_SIZE(v) = sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival, unsigned long, digit); + } + return (PyObject*)v; + } #if PyLong_SHIFT==15 - /* 2 digits */ - if (!(abs_ival >> 2*PyLong_SHIFT)) { - v = _PyLong_New(2); - if (v) { - Py_SIZE(v) = 2*sign; - v->ob_digit[0] = Py_SAFE_DOWNCAST( - abs_ival & PyLong_MASK, unsigned long, digit); - v->ob_digit[1] = Py_SAFE_DOWNCAST( - abs_ival >> PyLong_SHIFT, unsigned long, digit); - } - return (PyObject*)v; - } + /* 2 digits */ + if (!(abs_ival >> 2*PyLong_SHIFT)) { + v = _PyLong_New(2); + if (v) { + Py_SIZE(v) = 2*sign; + v->ob_digit[0] = Py_SAFE_DOWNCAST( + abs_ival & PyLong_MASK, unsigned long, digit); + v->ob_digit[1] = Py_SAFE_DOWNCAST( + abs_ival >> PyLong_SHIFT, unsigned long, digit); + } + return (PyObject*)v; + } #endif - /* Larger numbers: loop to determine number of digits */ - t = abs_ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = ndigits*sign; - t = abs_ival; - while (t) { - *p++ = Py_SAFE_DOWNCAST( - t & PyLong_MASK, unsigned long, digit); - t >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + /* Larger numbers: loop to determine number of digits */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits*sign; + t = abs_ival; + while (t) { + *p++ = Py_SAFE_DOWNCAST( + t & PyLong_MASK, unsigned long, digit); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C unsigned long int */ @@ -243,28 +243,28 @@ PyLong_FromLong(long ival) PyObject * PyLong_FromUnsignedLong(unsigned long ival) { - PyLongObject *v; - unsigned long t; - int ndigits = 0; - - if (ival < PyLong_BASE) - return PyLong_FromLong(ival); - /* Count the number of Python digits. */ - t = (unsigned long)ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; - while (ival) { - *p++ = (digit)(ival & PyLong_MASK); - ival >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + PyLongObject *v; + unsigned long t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong(ival); + /* Count the number of Python digits. */ + t = (unsigned long)ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C double */ @@ -272,41 +272,41 @@ PyLong_FromUnsignedLong(unsigned long ival) PyObject * PyLong_FromDouble(double dval) { - PyLongObject *v; - double frac; - int i, ndig, expo, neg; - neg = 0; - if (Py_IS_INFINITY(dval)) { - PyErr_SetString(PyExc_OverflowError, - "cannot convert float infinity to integer"); - return NULL; - } - if (Py_IS_NAN(dval)) { - PyErr_SetString(PyExc_ValueError, - "cannot convert float NaN to integer"); - return NULL; - } - if (dval < 0.0) { - neg = 1; - dval = -dval; - } - frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */ - if (expo <= 0) - return PyLong_FromLong(0L); - ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */ - v = _PyLong_New(ndig); - if (v == NULL) - return NULL; - frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); - for (i = ndig; --i >= 0; ) { - digit bits = (digit)frac; - v->ob_digit[i] = bits; - frac = frac - (double)bits; - frac = ldexp(frac, PyLong_SHIFT); - } - if (neg) - Py_SIZE(v) = -(Py_SIZE(v)); - return (PyObject *)v; + PyLongObject *v; + double frac; + int i, ndig, expo, neg; + neg = 0; + if (Py_IS_INFINITY(dval)) { + PyErr_SetString(PyExc_OverflowError, + "cannot convert float infinity to integer"); + return NULL; + } + if (Py_IS_NAN(dval)) { + PyErr_SetString(PyExc_ValueError, + "cannot convert float NaN to integer"); + return NULL; + } + if (dval < 0.0) { + neg = 1; + dval = -dval; + } + frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */ + if (expo <= 0) + return PyLong_FromLong(0L); + ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */ + v = _PyLong_New(ndig); + if (v == NULL) + return NULL; + frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); + for (i = ndig; --i >= 0; ) { + digit bits = (digit)frac; + v->ob_digit[i] = bits; + frac = frac - (double)bits; + frac = ldexp(frac, PyLong_SHIFT); + } + if (neg) + Py_SIZE(v) = -(Py_SIZE(v)); + return (PyObject *)v; } /* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define @@ -318,8 +318,8 @@ PyLong_FromDouble(double dval) * However, some other compilers warn about applying unary minus to an * unsigned operand. Hence the weird "0-". */ -#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) -#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) +#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) +#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN) /* Get a C long int from a long int object. Returns -1 and sets an error condition if overflow occurs. */ @@ -327,102 +327,102 @@ PyLong_FromDouble(double dval) long PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) { - /* This version by Tim Peters */ - register PyLongObject *v; - unsigned long x, prev; - long res; - Py_ssize_t i; - int sign; - int do_decref = 0; /* if nb_int was called */ - - *overflow = 0; - if (vv == NULL) { - PyErr_BadInternalCall(); - return -1; - } - - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) - return -1; - do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } - } - - res = -1; - v = (PyLongObject *)vv; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) { - *overflow = sign; - goto exit; - } - } - /* Haven't lost any bits, but casting to long requires extra - * care (see comment above). - */ - if (x <= (unsigned long)LONG_MAX) { - res = (long)x * sign; - } - else if (sign < 0 && x == PY_ABS_LONG_MIN) { - res = LONG_MIN; - } - else { - *overflow = sign; - /* res is already set to -1 */ - } - } + /* This version by Tim Peters */ + register PyLongObject *v; + unsigned long x, prev; + long res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + return -1; + } + vv = (*nb->nb_int) (vv); + if (vv == NULL) + return -1; + do_decref = 1; + if (!PyLong_Check(vv)) { + Py_DECREF(vv); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + + res = -1; + v = (PyLongObject *)vv; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned long)LONG_MAX) { + res = (long)x * sign; + } + else if (sign < 0 && x == PY_ABS_LONG_MIN) { + res = LONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } exit: - if (do_decref) { - Py_DECREF(vv); - } - return res; + if (do_decref) { + Py_DECREF(vv); + } + return res; } -long +long PyLong_AsLong(PyObject *obj) { - int overflow; - long result = PyLong_AsLongAndOverflow(obj, &overflow); - if (overflow) { - /* XXX: could be cute and give a different - message for overflow == -1 */ - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C long"); - } - return result; + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C long"); + } + return result; } /* Get a Py_ssize_t from a long int object. @@ -430,54 +430,54 @@ PyLong_AsLong(PyObject *obj) Py_ssize_t PyLong_AsSsize_t(PyObject *vv) { - register PyLongObject *v; - size_t x, prev; - Py_ssize_t i; - int sign; - - if (vv == NULL) { - PyErr_BadInternalCall(); - return -1; - } - if (!PyLong_Check(vv)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return -1; - } - - v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; - } - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) - goto overflow; - } - /* Haven't lost any bits, but casting to a signed type requires - * extra care (see comment above). - */ - if (x <= (size_t)PY_SSIZE_T_MAX) { - return (Py_ssize_t)x * sign; - } - else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) { - return PY_SSIZE_T_MIN; - } - /* else overflow */ + register PyLongObject *v; + size_t x, prev; + Py_ssize_t i; + int sign; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + switch (i) { + case -1: return -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) + goto overflow; + } + /* Haven't lost any bits, but casting to a signed type requires + * extra care (see comment above). + */ + if (x <= (size_t)PY_SSIZE_T_MAX) { + return (Py_ssize_t)x * sign; + } + else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) { + return PY_SSIZE_T_MIN; + } + /* else overflow */ overflow: - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C ssize_t"); - return -1; + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C ssize_t"); + return -1; } /* Get a C unsigned long int from a long int object. @@ -486,41 +486,41 @@ PyLong_AsSsize_t(PyObject *vv) { unsigned long PyLong_AsUnsignedLong(PyObject *vv) { - register PyLongObject *v; - unsigned long x, prev; - Py_ssize_t i; - - if (vv == NULL) { - PyErr_BadInternalCall(); - return (unsigned long)-1; - } - if (!PyLong_Check(vv)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned long)-1; - } - - v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned int"); - return (unsigned long) -1; - } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) { - PyErr_SetString(PyExc_OverflowError, - "python int too large to convert to C unsigned long"); - return (unsigned long) -1; - } - } - return x; + register PyLongObject *v; + unsigned long x, prev; + Py_ssize_t i; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long)-1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned int"); + return (unsigned long) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "python int too large to convert to C unsigned long"); + return (unsigned long) -1; + } + } + return x; } /* Get a C unsigned long int from a long int object. @@ -529,41 +529,41 @@ PyLong_AsUnsignedLong(PyObject *vv) size_t PyLong_AsSize_t(PyObject *vv) { - register PyLongObject *v; - size_t x, prev; - Py_ssize_t i; - - if (vv == NULL) { - PyErr_BadInternalCall(); - return (size_t) -1; - } - if (!PyLong_Check(vv)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (size_t)-1; - } - - v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to size_t"); - return (size_t) -1; - } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C size_t"); - return (unsigned long) -1; - } - } - return x; + register PyLongObject *v; + size_t x, prev; + Py_ssize_t i; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (size_t) -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (size_t)-1; + } + + v = (PyLongObject *)vv; + i = Py_SIZE(v); + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C size_t"); + return (unsigned long) -1; + } + } + return x; } /* Get a C unsigned long int from a long int object, ignoring the high bits. @@ -572,354 +572,354 @@ PyLong_AsSize_t(PyObject *vv) static unsigned long _PyLong_AsUnsignedLongMask(PyObject *vv) { - register PyLongObject *v; - unsigned long x; - Py_ssize_t i; - int sign; - - if (vv == NULL || !PyLong_Check(vv)) { - PyErr_BadInternalCall(); - return (unsigned long) -1; - } - v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -i; - } - while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - } - return x * sign; + register PyLongObject *v; + unsigned long x; + Py_ssize_t i; + int sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + i = Py_SIZE(v); + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + } + return x * sign; } unsigned long PyLong_AsUnsignedLongMask(register PyObject *op) { - PyNumberMethods *nb; - PyLongObject *lo; - unsigned long val; - - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongMask(op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned long)-1; - } - - lo = (PyLongObject*) (*nb->nb_int) (op); - if (lo == NULL) - return (unsigned long)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned long)-1; - return val; - } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return (unsigned long)-1; - } + PyNumberMethods *nb; + PyLongObject *lo; + unsigned long val; + + if (op && PyLong_Check(op)) + return _PyLong_AsUnsignedLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long)-1; + } + + lo = (PyLongObject*) (*nb->nb_int) (op); + if (lo == NULL) + return (unsigned long)-1; + if (PyLong_Check(lo)) { + val = _PyLong_AsUnsignedLongMask((PyObject *)lo); + Py_DECREF(lo); + if (PyErr_Occurred()) + return (unsigned long)-1; + return val; + } + else + { + Py_DECREF(lo); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return (unsigned long)-1; + } } int _PyLong_Sign(PyObject *vv) { - PyLongObject *v = (PyLongObject *)vv; + PyLongObject *v = (PyLongObject *)vv; - assert(v != NULL); - assert(PyLong_Check(v)); + assert(v != NULL); + assert(PyLong_Check(v)); - return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); + return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); } size_t _PyLong_NumBits(PyObject *vv) { - PyLongObject *v = (PyLongObject *)vv; - size_t result = 0; - Py_ssize_t ndigits; - - assert(v != NULL); - assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); - if (ndigits > 0) { - digit msd = v->ob_digit[ndigits - 1]; - - result = (ndigits - 1) * PyLong_SHIFT; - if (result / PyLong_SHIFT != (size_t)(ndigits - 1)) - goto Overflow; - do { - ++result; - if (result == 0) - goto Overflow; - msd >>= 1; - } while (msd); - } - return result; + PyLongObject *v = (PyLongObject *)vv; + size_t result = 0; + Py_ssize_t ndigits; + + assert(v != NULL); + assert(PyLong_Check(v)); + ndigits = ABS(Py_SIZE(v)); + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + if (ndigits > 0) { + digit msd = v->ob_digit[ndigits - 1]; + + result = (ndigits - 1) * PyLong_SHIFT; + if (result / PyLong_SHIFT != (size_t)(ndigits - 1)) + goto Overflow; + do { + ++result; + if (result == 0) + goto Overflow; + msd >>= 1; + } while (msd); + } + return result; Overflow: - PyErr_SetString(PyExc_OverflowError, "int has too many bits " - "to express in a platform size_t"); - return (size_t)-1; + PyErr_SetString(PyExc_OverflowError, "int has too many bits " + "to express in a platform size_t"); + return (size_t)-1; } PyObject * _PyLong_FromByteArray(const unsigned char* bytes, size_t n, - int little_endian, int is_signed) + int little_endian, int is_signed) { - const unsigned char* pstartbyte;/* LSB of bytes */ - int incr; /* direction to move pstartbyte */ - const unsigned char* pendbyte; /* MSB of bytes */ - size_t numsignificantbytes; /* number of bytes that matter */ - Py_ssize_t ndigits; /* number of Python long digits */ - PyLongObject* v; /* result */ - Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ - - if (n == 0) - return PyLong_FromLong(0L); - - if (little_endian) { - pstartbyte = bytes; - pendbyte = bytes + n - 1; - incr = 1; - } - else { - pstartbyte = bytes + n - 1; - pendbyte = bytes; - incr = -1; - } - - if (is_signed) - is_signed = *pendbyte >= 0x80; - - /* Compute numsignificantbytes. This consists of finding the most - significant byte. Leading 0 bytes are insignficant if the number - is positive, and leading 0xff bytes if negative. */ - { - size_t i; - const unsigned char* p = pendbyte; - const int pincr = -incr; /* search MSB to LSB */ - const unsigned char insignficant = is_signed ? 0xff : 0x00; - - for (i = 0; i < n; ++i, p += pincr) { - if (*p != insignficant) - break; - } - numsignificantbytes = n - i; - /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so - actually has 2 significant bytes. OTOH, 0xff0001 == - -0x00ffff, so we wouldn't *need* to bump it there; but we - do for 0xffff = -0x0001. To be safe without bothering to - check every case, bump it regardless. */ - if (is_signed && numsignificantbytes < n) - ++numsignificantbytes; - } - - /* How many Python long digits do we need? We have - 8*numsignificantbytes bits, and each Python long digit has - PyLong_SHIFT bits, so it's the ceiling of the quotient. */ - /* catch overflow before it happens */ - if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) { - PyErr_SetString(PyExc_OverflowError, - "byte array too long to convert to int"); - return NULL; - } - ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT; - v = _PyLong_New(ndigits); - if (v == NULL) - return NULL; - - /* Copy the bits over. The tricky parts are computing 2's-comp on - the fly for signed numbers, and dealing with the mismatch between - 8-bit bytes and (probably) 15-bit Python digits.*/ - { - size_t i; - twodigits carry = 1; /* for 2's-comp calculation */ - twodigits accum = 0; /* sliding register */ - unsigned int accumbits = 0; /* number of bits in accum */ - const unsigned char* p = pstartbyte; - - for (i = 0; i < numsignificantbytes; ++i, p += incr) { - twodigits thisbyte = *p; - /* Compute correction for 2's comp, if needed. */ - if (is_signed) { - thisbyte = (0xff ^ thisbyte) + carry; - carry = thisbyte >> 8; - thisbyte &= 0xff; - } - /* Because we're going LSB to MSB, thisbyte is - more significant than what's already in accum, - so needs to be prepended to accum. */ - accum |= (twodigits)thisbyte << accumbits; - accumbits += 8; - if (accumbits >= PyLong_SHIFT) { - /* There's enough to fill a Python digit. */ - assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)(accum & - PyLong_MASK); - ++idigit; - accum >>= PyLong_SHIFT; - accumbits -= PyLong_SHIFT; - assert(accumbits < PyLong_SHIFT); - } - } - assert(accumbits < PyLong_SHIFT); - if (accumbits) { - assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)accum; - ++idigit; - } - } - - Py_SIZE(v) = is_signed ? -idigit : idigit; - return (PyObject *)long_normalize(v); + const unsigned char* pstartbyte;/* LSB of bytes */ + int incr; /* direction to move pstartbyte */ + const unsigned char* pendbyte; /* MSB of bytes */ + size_t numsignificantbytes; /* number of bytes that matter */ + Py_ssize_t ndigits; /* number of Python long digits */ + PyLongObject* v; /* result */ + Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ + + if (n == 0) + return PyLong_FromLong(0L); + + if (little_endian) { + pstartbyte = bytes; + pendbyte = bytes + n - 1; + incr = 1; + } + else { + pstartbyte = bytes + n - 1; + pendbyte = bytes; + incr = -1; + } + + if (is_signed) + is_signed = *pendbyte >= 0x80; + + /* Compute numsignificantbytes. This consists of finding the most + significant byte. Leading 0 bytes are insignficant if the number + is positive, and leading 0xff bytes if negative. */ + { + size_t i; + const unsigned char* p = pendbyte; + const int pincr = -incr; /* search MSB to LSB */ + const unsigned char insignficant = is_signed ? 0xff : 0x00; + + for (i = 0; i < n; ++i, p += pincr) { + if (*p != insignficant) + break; + } + numsignificantbytes = n - i; + /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so + actually has 2 significant bytes. OTOH, 0xff0001 == + -0x00ffff, so we wouldn't *need* to bump it there; but we + do for 0xffff = -0x0001. To be safe without bothering to + check every case, bump it regardless. */ + if (is_signed && numsignificantbytes < n) + ++numsignificantbytes; + } + + /* How many Python long digits do we need? We have + 8*numsignificantbytes bits, and each Python long digit has + PyLong_SHIFT bits, so it's the ceiling of the quotient. */ + /* catch overflow before it happens */ + if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) { + PyErr_SetString(PyExc_OverflowError, + "byte array too long to convert to int"); + return NULL; + } + ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT; + v = _PyLong_New(ndigits); + if (v == NULL) + return NULL; + + /* Copy the bits over. The tricky parts are computing 2's-comp on + the fly for signed numbers, and dealing with the mismatch between + 8-bit bytes and (probably) 15-bit Python digits.*/ + { + size_t i; + twodigits carry = 1; /* for 2's-comp calculation */ + twodigits accum = 0; /* sliding register */ + unsigned int accumbits = 0; /* number of bits in accum */ + const unsigned char* p = pstartbyte; + + for (i = 0; i < numsignificantbytes; ++i, p += incr) { + twodigits thisbyte = *p; + /* Compute correction for 2's comp, if needed. */ + if (is_signed) { + thisbyte = (0xff ^ thisbyte) + carry; + carry = thisbyte >> 8; + thisbyte &= 0xff; + } + /* Because we're going LSB to MSB, thisbyte is + more significant than what's already in accum, + so needs to be prepended to accum. */ + accum |= (twodigits)thisbyte << accumbits; + accumbits += 8; + if (accumbits >= PyLong_SHIFT) { + /* There's enough to fill a Python digit. */ + assert(idigit < ndigits); + v->ob_digit[idigit] = (digit)(accum & + PyLong_MASK); + ++idigit; + accum >>= PyLong_SHIFT; + accumbits -= PyLong_SHIFT; + assert(accumbits < PyLong_SHIFT); + } + } + assert(accumbits < PyLong_SHIFT); + if (accumbits) { + assert(idigit < ndigits); + v->ob_digit[idigit] = (digit)accum; + ++idigit; + } + } + + Py_SIZE(v) = is_signed ? -idigit : idigit; + return (PyObject *)long_normalize(v); } int _PyLong_AsByteArray(PyLongObject* v, - unsigned char* bytes, size_t n, - int little_endian, int is_signed) + unsigned char* bytes, size_t n, + int little_endian, int is_signed) { - Py_ssize_t i; /* index into v->ob_digit */ - Py_ssize_t ndigits; /* |v->ob_size| */ - twodigits accum; /* sliding register */ - unsigned int accumbits; /* # bits in accum */ - int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ - digit carry; /* for computing 2's-comp */ - size_t j; /* # bytes filled */ - unsigned char* p; /* pointer to next byte in bytes */ - int pincr; /* direction to move p */ - - assert(v != NULL && PyLong_Check(v)); - - if (Py_SIZE(v) < 0) { - ndigits = -(Py_SIZE(v)); - if (!is_signed) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative int to unsigned"); - return -1; - } - do_twos_comp = 1; - } - else { - ndigits = Py_SIZE(v); - do_twos_comp = 0; - } - - if (little_endian) { - p = bytes; - pincr = 1; - } - else { - p = bytes + n - 1; - pincr = -1; - } - - /* Copy over all the Python digits. - It's crucial that every Python digit except for the MSD contribute - exactly PyLong_SHIFT bits to the total, so first assert that the long is - normalized. */ - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); - j = 0; - accum = 0; - accumbits = 0; - carry = do_twos_comp ? 1 : 0; - for (i = 0; i < ndigits; ++i) { - digit thisdigit = v->ob_digit[i]; - if (do_twos_comp) { - thisdigit = (thisdigit ^ PyLong_MASK) + carry; - carry = thisdigit >> PyLong_SHIFT; - thisdigit &= PyLong_MASK; - } - /* Because we're going LSB to MSB, thisdigit is more - significant than what's already in accum, so needs to be - prepended to accum. */ - accum |= (twodigits)thisdigit << accumbits; - - /* The most-significant digit may be (probably is) at least - partly empty. */ - if (i == ndigits - 1) { - /* Count # of sign bits -- they needn't be stored, - * although for signed conversion we need later to - * make sure at least one sign bit gets stored. */ - digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : - thisdigit; - while (s != 0) { - s >>= 1; - accumbits++; - } - } - else - accumbits += PyLong_SHIFT; - - /* Store as many bytes as possible. */ - while (accumbits >= 8) { - if (j >= n) - goto Overflow; - ++j; - *p = (unsigned char)(accum & 0xff); - p += pincr; - accumbits -= 8; - accum >>= 8; - } - } - - /* Store the straggler (if any). */ - assert(accumbits < 8); - assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ - if (accumbits > 0) { - if (j >= n) - goto Overflow; - ++j; - if (do_twos_comp) { - /* Fill leading bits of the byte with sign bits - (appropriately pretending that the long had an - infinite supply of sign bits). */ - accum |= (~(twodigits)0) << accumbits; - } - *p = (unsigned char)(accum & 0xff); - p += pincr; - } - else if (j == n && n > 0 && is_signed) { - /* The main loop filled the byte array exactly, so the code - just above didn't get to ensure there's a sign bit, and the - loop below wouldn't add one either. Make sure a sign bit - exists. */ - unsigned char msb = *(p - pincr); - int sign_bit_set = msb >= 0x80; - assert(accumbits == 0); - if (sign_bit_set == do_twos_comp) - return 0; - else - goto Overflow; - } - - /* Fill remaining bytes with copies of the sign bit. */ - { - unsigned char signbyte = do_twos_comp ? 0xffU : 0U; - for ( ; j < n; ++j, p += pincr) - *p = signbyte; - } - - return 0; + Py_ssize_t i; /* index into v->ob_digit */ + Py_ssize_t ndigits; /* |v->ob_size| */ + twodigits accum; /* sliding register */ + unsigned int accumbits; /* # bits in accum */ + int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ + digit carry; /* for computing 2's-comp */ + size_t j; /* # bytes filled */ + unsigned char* p; /* pointer to next byte in bytes */ + int pincr; /* direction to move p */ + + assert(v != NULL && PyLong_Check(v)); + + if (Py_SIZE(v) < 0) { + ndigits = -(Py_SIZE(v)); + if (!is_signed) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative int to unsigned"); + return -1; + } + do_twos_comp = 1; + } + else { + ndigits = Py_SIZE(v); + do_twos_comp = 0; + } + + if (little_endian) { + p = bytes; + pincr = 1; + } + else { + p = bytes + n - 1; + pincr = -1; + } + + /* Copy over all the Python digits. + It's crucial that every Python digit except for the MSD contribute + exactly PyLong_SHIFT bits to the total, so first assert that the long is + normalized. */ + assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + j = 0; + accum = 0; + accumbits = 0; + carry = do_twos_comp ? 1 : 0; + for (i = 0; i < ndigits; ++i) { + digit thisdigit = v->ob_digit[i]; + if (do_twos_comp) { + thisdigit = (thisdigit ^ PyLong_MASK) + carry; + carry = thisdigit >> PyLong_SHIFT; + thisdigit &= PyLong_MASK; + } + /* Because we're going LSB to MSB, thisdigit is more + significant than what's already in accum, so needs to be + prepended to accum. */ + accum |= (twodigits)thisdigit << accumbits; + + /* The most-significant digit may be (probably is) at least + partly empty. */ + if (i == ndigits - 1) { + /* Count # of sign bits -- they needn't be stored, + * although for signed conversion we need later to + * make sure at least one sign bit gets stored. */ + digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : + thisdigit; + while (s != 0) { + s >>= 1; + accumbits++; + } + } + else + accumbits += PyLong_SHIFT; + + /* Store as many bytes as possible. */ + while (accumbits >= 8) { + if (j >= n) + goto Overflow; + ++j; + *p = (unsigned char)(accum & 0xff); + p += pincr; + accumbits -= 8; + accum >>= 8; + } + } + + /* Store the straggler (if any). */ + assert(accumbits < 8); + assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */ + if (accumbits > 0) { + if (j >= n) + goto Overflow; + ++j; + if (do_twos_comp) { + /* Fill leading bits of the byte with sign bits + (appropriately pretending that the long had an + infinite supply of sign bits). */ + accum |= (~(twodigits)0) << accumbits; + } + *p = (unsigned char)(accum & 0xff); + p += pincr; + } + else if (j == n && n > 0 && is_signed) { + /* The main loop filled the byte array exactly, so the code + just above didn't get to ensure there's a sign bit, and the + loop below wouldn't add one either. Make sure a sign bit + exists. */ + unsigned char msb = *(p - pincr); + int sign_bit_set = msb >= 0x80; + assert(accumbits == 0); + if (sign_bit_set == do_twos_comp) + return 0; + else + goto Overflow; + } + + /* Fill remaining bytes with copies of the sign bit. */ + { + unsigned char signbyte = do_twos_comp ? 0xffU : 0U; + for ( ; j < n; ++j, p += pincr) + *p = signbyte; + } + + return 0; Overflow: - PyErr_SetString(PyExc_OverflowError, "int too big to convert"); - return -1; + PyErr_SetString(PyExc_OverflowError, "int too big to convert"); + return -1; } @@ -934,10 +934,10 @@ PyLong_FromVoidPtr(void *p) #if SIZEOF_LONG_LONG < SIZEOF_VOID_P # error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" #endif - /* special-case null pointer */ - if (!p) - return PyLong_FromLong(0); - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); + /* special-case null pointer */ + if (!p) + return PyLong_FromLong(0); + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); } @@ -946,17 +946,17 @@ PyLong_FromVoidPtr(void *p) void * PyLong_AsVoidPtr(PyObject *vv) { - /* This function will allow int or long objects. If vv is neither, - then the PyLong_AsLong*() functions will raise the exception: - PyExc_SystemError, "bad argument to internal function" - */ + /* This function will allow int or long objects. If vv is neither, + then the PyLong_AsLong*() functions will raise the exception: + PyExc_SystemError, "bad argument to internal function" + */ #if SIZEOF_VOID_P <= SIZEOF_LONG - long x; + long x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) - x = PyLong_AsLong(vv); - else - x = PyLong_AsUnsignedLong(vv); + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + x = PyLong_AsLong(vv); + else + x = PyLong_AsUnsignedLong(vv); #else #ifndef HAVE_LONG_LONG @@ -965,18 +965,18 @@ PyLong_AsVoidPtr(PyObject *vv) #if SIZEOF_LONG_LONG < SIZEOF_VOID_P # error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" #endif - PY_LONG_LONG x; + PY_LONG_LONG x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) - x = PyLong_AsLongLong(vv); - else - x = PyLong_AsUnsignedLongLong(vv); + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + x = PyLong_AsLongLong(vv); + else + x = PyLong_AsUnsignedLongLong(vv); #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ - if (x == -1 && PyErr_Occurred()) - return NULL; - return (void *)x; + if (x == -1 && PyErr_Occurred()) + return NULL; + return (void *)x; } #ifdef HAVE_LONG_LONG @@ -986,50 +986,50 @@ PyLong_AsVoidPtr(PyObject *vv) */ #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one -#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) +#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) /* Create a new long int object from a C PY_LONG_LONG int. */ PyObject * PyLong_FromLongLong(PY_LONG_LONG ival) { - PyLongObject *v; - unsigned PY_LONG_LONG abs_ival; - unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ - int ndigits = 0; - int negative = 0; - - CHECK_SMALL_INT(ival); - if (ival < 0) { - /* avoid signed overflow on negation; see comments - in PyLong_FromLong above. */ - abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1; - negative = 1; - } - else { - abs_ival = (unsigned PY_LONG_LONG)ival; - } - - /* Count the number of Python digits. - We used to pick 5 ("big enough for anything"), but that's a - waste of time and space given that 5*15 = 75 bits are rarely - needed. */ - t = abs_ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; - t = abs_ival; - while (t) { - *p++ = (digit)(t & PyLong_MASK); - t >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + PyLongObject *v; + unsigned PY_LONG_LONG abs_ival; + unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + CHECK_SMALL_INT(ival); + if (ival < 0) { + /* avoid signed overflow on negation; see comments + in PyLong_FromLong above. */ + abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1; + negative = 1; + } + else { + abs_ival = (unsigned PY_LONG_LONG)ival; + } + + /* Count the number of Python digits. + We used to pick 5 ("big enough for anything"), but that's a + waste of time and space given that 5*15 = 75 bits are rarely + needed. */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = negative ? -ndigits : ndigits; + t = abs_ival; + while (t) { + *p++ = (digit)(t & PyLong_MASK); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C unsigned PY_LONG_LONG int. */ @@ -1037,28 +1037,28 @@ PyLong_FromLongLong(PY_LONG_LONG ival) PyObject * PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) { - PyLongObject *v; - unsigned PY_LONG_LONG t; - int ndigits = 0; - - if (ival < PyLong_BASE) - return PyLong_FromLong((long)ival); - /* Count the number of Python digits. */ - t = (unsigned PY_LONG_LONG)ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; - while (ival) { - *p++ = (digit)(ival & PyLong_MASK); - ival >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + PyLongObject *v; + unsigned PY_LONG_LONG t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong((long)ival); + /* Count the number of Python digits. */ + t = (unsigned PY_LONG_LONG)ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C Py_ssize_t. */ @@ -1066,39 +1066,39 @@ PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) PyObject * PyLong_FromSsize_t(Py_ssize_t ival) { - PyLongObject *v; - size_t abs_ival; - size_t t; /* unsigned so >> doesn't propagate sign bit */ - int ndigits = 0; - int negative = 0; - - CHECK_SMALL_INT(ival); - if (ival < 0) { - /* avoid signed overflow when ival = SIZE_T_MIN */ - abs_ival = (size_t)(-1-ival)+1; - negative = 1; - } - else { - abs_ival = (size_t)ival; - } - - /* Count the number of Python digits. */ - t = abs_ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = negative ? -ndigits : ndigits; - t = abs_ival; - while (t) { - *p++ = (digit)(t & PyLong_MASK); - t >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + PyLongObject *v; + size_t abs_ival; + size_t t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + CHECK_SMALL_INT(ival); + if (ival < 0) { + /* avoid signed overflow when ival = SIZE_T_MIN */ + abs_ival = (size_t)(-1-ival)+1; + negative = 1; + } + else { + abs_ival = (size_t)ival; + } + + /* Count the number of Python digits. */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = negative ? -ndigits : ndigits; + t = abs_ival; + while (t) { + *p++ = (digit)(t & PyLong_MASK); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Create a new long int object from a C size_t. */ @@ -1106,28 +1106,28 @@ PyLong_FromSsize_t(Py_ssize_t ival) PyObject * PyLong_FromSize_t(size_t ival) { - PyLongObject *v; - size_t t; - int ndigits = 0; - - if (ival < PyLong_BASE) - return PyLong_FromLong((long)ival); - /* Count the number of Python digits. */ - t = ival; - while (t) { - ++ndigits; - t >>= PyLong_SHIFT; - } - v = _PyLong_New(ndigits); - if (v != NULL) { - digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; - while (ival) { - *p++ = (digit)(ival & PyLong_MASK); - ival >>= PyLong_SHIFT; - } - } - return (PyObject *)v; + PyLongObject *v; + size_t t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong((long)ival); + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; } /* Get a C PY_LONG_LONG int from a long int object. @@ -1136,51 +1136,51 @@ PyLong_FromSize_t(size_t ival) PY_LONG_LONG PyLong_AsLongLong(PyObject *vv) { - PyLongObject *v; - PY_LONG_LONG bytes; - int one = 1; - int res; - - if (vv == NULL) { - PyErr_BadInternalCall(); - return -1; - } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - PyObject *io; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return -1; - } - io = (*nb->nb_int) (vv); - if (io == NULL) - return -1; - if (PyLong_Check(io)) { - bytes = PyLong_AsLongLong(io); - Py_DECREF(io); - return bytes; - } - Py_DECREF(io); - PyErr_SetString(PyExc_TypeError, "integer conversion failed"); - return -1; - } - - v = (PyLongObject*)vv; - switch(Py_SIZE(v)) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; - } - res = _PyLong_AsByteArray( - (PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); - - /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ - if (res < 0) - return (PY_LONG_LONG)-1; - else - return bytes; + PyLongObject *v; + PY_LONG_LONG bytes; + int one = 1; + int res; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + PyObject *io; + if ((nb = vv->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + io = (*nb->nb_int) (vv); + if (io == NULL) + return -1; + if (PyLong_Check(io)) { + bytes = PyLong_AsLongLong(io); + Py_DECREF(io); + return bytes; + } + Py_DECREF(io); + PyErr_SetString(PyExc_TypeError, "integer conversion failed"); + return -1; + } + + v = (PyLongObject*)vv; + switch(Py_SIZE(v)) { + case -1: return -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + res = _PyLong_AsByteArray( + (PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); + + /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ + if (res < 0) + return (PY_LONG_LONG)-1; + else + return bytes; } /* Get a C unsigned PY_LONG_LONG int from a long int object. @@ -1189,31 +1189,31 @@ PyLong_AsLongLong(PyObject *vv) unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *vv) { - PyLongObject *v; - unsigned PY_LONG_LONG bytes; - int one = 1; - int res; - - if (vv == NULL || !PyLong_Check(vv)) { - PyErr_BadInternalCall(); - return (unsigned PY_LONG_LONG)-1; - } - - v = (PyLongObject*)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } - - res = _PyLong_AsByteArray( - (PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); - - /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ - if (res < 0) - return (unsigned PY_LONG_LONG)res; - else - return bytes; + PyLongObject *v; + unsigned PY_LONG_LONG bytes; + int one = 1; + int res; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned PY_LONG_LONG)-1; + } + + v = (PyLongObject*)vv; + switch(Py_SIZE(v)) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + + res = _PyLong_AsByteArray( + (PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); + + /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ + if (res < 0) + return (unsigned PY_LONG_LONG)res; + else + return bytes; } /* Get a C unsigned long int from a long int object, ignoring the high bits. @@ -1222,66 +1222,66 @@ PyLong_AsUnsignedLongLong(PyObject *vv) static unsigned PY_LONG_LONG _PyLong_AsUnsignedLongLongMask(PyObject *vv) { - register PyLongObject *v; - unsigned PY_LONG_LONG x; - Py_ssize_t i; - int sign; - - if (vv == NULL || !PyLong_Check(vv)) { - PyErr_BadInternalCall(); - return (unsigned long) -1; - } - v = (PyLongObject *)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } - i = Py_SIZE(v); - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -i; - } - while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; - } - return x * sign; + register PyLongObject *v; + unsigned PY_LONG_LONG x; + Py_ssize_t i; + int sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + switch(Py_SIZE(v)) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + i = Py_SIZE(v); + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << PyLong_SHIFT) | v->ob_digit[i]; + } + return x * sign; } unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(register PyObject *op) { - PyNumberMethods *nb; - PyLongObject *lo; - unsigned PY_LONG_LONG val; - - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongLongMask(op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned PY_LONG_LONG)-1; - } - - lo = (PyLongObject*) (*nb->nb_int) (op); - if (lo == NULL) - return (unsigned PY_LONG_LONG)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned PY_LONG_LONG)-1; - return val; - } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return (unsigned PY_LONG_LONG)-1; - } + PyNumberMethods *nb; + PyLongObject *lo; + unsigned PY_LONG_LONG val; + + if (op && PyLong_Check(op)) + return _PyLong_AsUnsignedLongLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned PY_LONG_LONG)-1; + } + + lo = (PyLongObject*) (*nb->nb_int) (op); + if (lo == NULL) + return (unsigned PY_LONG_LONG)-1; + if (PyLong_Check(lo)) { + val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); + Py_DECREF(lo); + if (PyErr_Occurred()) + return (unsigned PY_LONG_LONG)-1; + return val; + } + else + { + Py_DECREF(lo); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return (unsigned PY_LONG_LONG)-1; + } } #undef IS_LITTLE_ENDIAN @@ -1296,116 +1296,116 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op) PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) { - /* This version by Tim Peters */ - register PyLongObject *v; - unsigned PY_LONG_LONG x, prev; - PY_LONG_LONG res; - Py_ssize_t i; - int sign; - int do_decref = 0; /* if nb_int was called */ - - *overflow = 0; - if (vv == NULL) { - PyErr_BadInternalCall(); - return -1; - } - - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) - return -1; - do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } - } - - res = -1; - v = (PyLongObject *)vv; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; - if ((x >> PyLong_SHIFT) != prev) { - *overflow = sign; - goto exit; - } - } - /* Haven't lost any bits, but casting to long requires extra - * care (see comment above). - */ - if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { - res = (PY_LONG_LONG)x * sign; - } - else if (sign < 0 && x == PY_ABS_LLONG_MIN) { - res = PY_LLONG_MIN; - } - else { - *overflow = sign; - /* res is already set to -1 */ - } - } + /* This version by Tim Peters */ + register PyLongObject *v; + unsigned PY_LONG_LONG x, prev; + PY_LONG_LONG res; + Py_ssize_t i; + int sign; + int do_decref = 0; /* if nb_int was called */ + + *overflow = 0; + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + nb = vv->ob_type->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + return -1; + } + vv = (*nb->nb_int) (vv); + if (vv == NULL) + return -1; + do_decref = 1; + if (!PyLong_Check(vv)) { + Py_DECREF(vv); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + + res = -1; + v = (PyLongObject *)vv; + i = Py_SIZE(v); + + switch (i) { + case -1: + res = -(sdigit)v->ob_digit[0]; + break; + case 0: + res = 0; + break; + case 1: + res = v->ob_digit[0]; + break; + default: + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + while (--i >= 0) { + prev = x; + x = (x << PyLong_SHIFT) + v->ob_digit[i]; + if ((x >> PyLong_SHIFT) != prev) { + *overflow = sign; + goto exit; + } + } + /* Haven't lost any bits, but casting to long requires extra + * care (see comment above). + */ + if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { + res = (PY_LONG_LONG)x * sign; + } + else if (sign < 0 && x == PY_ABS_LLONG_MIN) { + res = PY_LLONG_MIN; + } + else { + *overflow = sign; + /* res is already set to -1 */ + } + } exit: - if (do_decref) { - Py_DECREF(vv); - } - return res; + if (do_decref) { + Py_DECREF(vv); + } + return res; } #endif /* HAVE_LONG_LONG */ #define CHECK_BINOP(v,w) \ - if (!PyLong_Check(v) || !PyLong_Check(w)) { \ - Py_INCREF(Py_NotImplemented); \ - return Py_NotImplemented; \ - } + if (!PyLong_Check(v) || !PyLong_Check(w)) { \ + Py_INCREF(Py_NotImplemented); \ + return Py_NotImplemented; \ + } /* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < 2**k if d is nonzero, else 0. */ 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 + 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_digit(digit d) { - int d_bits = 0; - while (d >= 32) { - d_bits += 6; - d >>= 6; - } - d_bits += (int)BitLengthTable[d]; - return d_bits; + int d_bits = 0; + while (d >= 32) { + d_bits += 6; + d >>= 6; + } + d_bits += (int)BitLengthTable[d]; + return d_bits; } /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n] @@ -1415,23 +1415,23 @@ bits_in_digit(digit d) static digit v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) { - Py_ssize_t i; - digit carry = 0; - - assert(m >= n); - for (i = 0; i < n; ++i) { - carry += x[i] + y[i]; - x[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - assert((carry & 1) == carry); - } - for (; carry && i < m; ++i) { - carry += x[i]; - x[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - assert((carry & 1) == carry); - } - return carry; + Py_ssize_t i; + digit carry = 0; + + assert(m >= n); + for (i = 0; i < n; ++i) { + carry += x[i] + y[i]; + x[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + assert((carry & 1) == carry); + } + for (; carry && i < m; ++i) { + carry += x[i]; + x[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + assert((carry & 1) == carry); + } + return carry; } /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n] @@ -1441,23 +1441,23 @@ v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) static digit v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) { - Py_ssize_t i; - digit borrow = 0; - - assert(m >= n); - for (i = 0; i < n; ++i) { - borrow = x[i] - y[i] - borrow; - x[i] = borrow & PyLong_MASK; - borrow >>= PyLong_SHIFT; - borrow &= 1; /* keep only 1 sign bit */ - } - for (; borrow && i < m; ++i) { - borrow = x[i] - borrow; - x[i] = borrow & PyLong_MASK; - borrow >>= PyLong_SHIFT; - borrow &= 1; - } - return borrow; + Py_ssize_t i; + digit borrow = 0; + + assert(m >= n); + for (i = 0; i < n; ++i) { + borrow = x[i] - y[i] - borrow; + x[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* keep only 1 sign bit */ + } + for (; borrow && i < m; ++i) { + borrow = x[i] - borrow; + x[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; + } + return borrow; } /* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put @@ -1466,16 +1466,16 @@ v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) static digit v_lshift(digit *z, digit *a, Py_ssize_t m, int d) { - Py_ssize_t i; - digit carry = 0; - - assert(0 <= d && d < PyLong_SHIFT); - for (i=0; i < m; i++) { - twodigits acc = (twodigits)a[i] << d | carry; - z[i] = (digit)acc & PyLong_MASK; - carry = (digit)(acc >> PyLong_SHIFT); - } - return carry; + Py_ssize_t i; + digit carry = 0; + + assert(0 <= d && d < PyLong_SHIFT); + for (i=0; i < m; i++) { + twodigits acc = (twodigits)a[i] << d | carry; + z[i] = (digit)acc & PyLong_MASK; + carry = (digit)(acc >> PyLong_SHIFT); + } + return carry; } /* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put @@ -1484,17 +1484,17 @@ v_lshift(digit *z, digit *a, Py_ssize_t m, int d) static digit v_rshift(digit *z, digit *a, Py_ssize_t m, int d) { - Py_ssize_t i; - digit carry = 0; - digit mask = ((digit)1 << d) - 1U; - - assert(0 <= d && d < PyLong_SHIFT); - for (i=m; i-- > 0;) { - twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i]; - carry = (digit)acc & mask; - z[i] = (digit)(acc >> d); - } - return carry; + Py_ssize_t i; + digit carry = 0; + digit mask = ((digit)1 << d) - 1U; + + assert(0 <= d && d < PyLong_SHIFT); + for (i=m; i-- > 0;) { + twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i]; + carry = (digit)acc & mask; + z[i] = (digit)(acc >> d); + } + return carry; } /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient @@ -1506,18 +1506,18 @@ v_rshift(digit *z, digit *a, Py_ssize_t m, int d) static digit inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) { - twodigits rem = 0; - - assert(n > 0 && n <= PyLong_MASK); - pin += size; - pout += size; - while (--size >= 0) { - digit hi; - rem = (rem << PyLong_SHIFT) | *--pin; - *--pout = hi = (digit)(rem / n); - rem -= (twodigits)hi * n; - } - return (digit)rem; + twodigits rem = 0; + + assert(n > 0 && n <= PyLong_MASK); + pin += size; + pout += size; + while (--size >= 0) { + digit hi; + rem = (rem << PyLong_SHIFT) | *--pin; + *--pout = hi = (digit)(rem / n); + rem -= (twodigits)hi * n; + } + return (digit)rem; } /* Divide a long integer by a digit, returning both the quotient @@ -1527,15 +1527,15 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = ABS(Py_SIZE(a)); - PyLongObject *z; - - assert(n > 0 && n <= PyLong_MASK); - z = _PyLong_New(size); - if (z == NULL) - return NULL; - *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); - return long_normalize(z); + const Py_ssize_t size = ABS(Py_SIZE(a)); + PyLongObject *z; + + assert(n > 0 && n <= PyLong_MASK); + z = _PyLong_New(size); + if (z == NULL) + return NULL; + *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); + return long_normalize(z); } /* Convert a long integer to a base 10 string. Returns a new non-shared @@ -1545,111 +1545,111 @@ divrem1(PyLongObject *a, digit n, digit *prem) static PyObject * long_to_decimal_string(PyObject *aa) { - PyLongObject *scratch, *a; - PyObject *str; - Py_ssize_t size, strlen, size_a, i, j; - digit *pout, *pin, rem, tenpow; - Py_UNICODE *p; - int negative; - - a = (PyLongObject *)aa; - if (a == NULL || !PyLong_Check(a)) { - PyErr_BadInternalCall(); - return NULL; - } - size_a = ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; - - /* quick and dirty upper bound for the number of digits - required to express a in base _PyLong_DECIMAL_BASE: - - #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE)) - - But log2(a) < size_a * PyLong_SHIFT, and - log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT - > 3 * _PyLong_DECIMAL_SHIFT - */ - if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { - PyErr_SetString(PyExc_OverflowError, - "long is too large to format"); - return NULL; - } - /* the expression size_a * PyLong_SHIFT is now safe from overflow */ - size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT); - scratch = _PyLong_New(size); - if (scratch == NULL) - return NULL; - - /* convert array of base _PyLong_BASE digits in pin to an array of - base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, - Volume 2 (3rd edn), section 4.4, Method 1b). */ - pin = a->ob_digit; - pout = scratch->ob_digit; - size = 0; - for (i = size_a; --i >= 0; ) { - digit hi = pin[i]; - for (j = 0; j < size; j++) { - twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; - hi = (digit)(z / _PyLong_DECIMAL_BASE); - pout[j] = (digit)(z - (twodigits)hi * - _PyLong_DECIMAL_BASE); - } - while (hi) { - pout[size++] = hi % _PyLong_DECIMAL_BASE; - hi /= _PyLong_DECIMAL_BASE; - } - /* check for keyboard interrupt */ - SIGCHECK({ - Py_DECREF(scratch); - return NULL; - }) - } - /* pout should have at least one digit, so that the case when a = 0 - works correctly */ - if (size == 0) - pout[size++] = 0; - - /* calculate exact length of output string, and allocate */ - strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT; - tenpow = 10; - rem = pout[size-1]; - while (rem >= tenpow) { - tenpow *= 10; - strlen++; - } - str = PyUnicode_FromUnicode(NULL, strlen); - if (str == NULL) { - Py_DECREF(scratch); - return NULL; - } - - /* fill the string right-to-left */ - p = PyUnicode_AS_UNICODE(str) + strlen; - *p = '\0'; - /* pout[0] through pout[size-2] contribute exactly - _PyLong_DECIMAL_SHIFT digits each */ - for (i=0; i < size - 1; i++) { - rem = pout[i]; - for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { - *--p = '0' + rem % 10; - rem /= 10; - } - } - /* pout[size-1]: always produce at least one decimal digit */ - rem = pout[i]; - do { - *--p = '0' + rem % 10; - rem /= 10; - } while (rem != 0); - - /* and sign */ - if (negative) - *--p = '-'; - - /* check we've counted correctly */ - assert(p == PyUnicode_AS_UNICODE(str)); - Py_DECREF(scratch); - return (PyObject *)str; + PyLongObject *scratch, *a; + PyObject *str; + Py_ssize_t size, strlen, size_a, i, j; + digit *pout, *pin, rem, tenpow; + Py_UNICODE *p; + int negative; + + a = (PyLongObject *)aa; + if (a == NULL || !PyLong_Check(a)) { + PyErr_BadInternalCall(); + return NULL; + } + size_a = ABS(Py_SIZE(a)); + negative = Py_SIZE(a) < 0; + + /* quick and dirty upper bound for the number of digits + required to express a in base _PyLong_DECIMAL_BASE: + + #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE)) + + But log2(a) < size_a * PyLong_SHIFT, and + log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT + > 3 * _PyLong_DECIMAL_SHIFT + */ + if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { + PyErr_SetString(PyExc_OverflowError, + "long is too large to format"); + return NULL; + } + /* the expression size_a * PyLong_SHIFT is now safe from overflow */ + size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT); + scratch = _PyLong_New(size); + if (scratch == NULL) + return NULL; + + /* convert array of base _PyLong_BASE digits in pin to an array of + base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, + Volume 2 (3rd edn), section 4.4, Method 1b). */ + pin = a->ob_digit; + pout = scratch->ob_digit; + size = 0; + for (i = size_a; --i >= 0; ) { + digit hi = pin[i]; + for (j = 0; j < size; j++) { + twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi; + hi = (digit)(z / _PyLong_DECIMAL_BASE); + pout[j] = (digit)(z - (twodigits)hi * + _PyLong_DECIMAL_BASE); + } + while (hi) { + pout[size++] = hi % _PyLong_DECIMAL_BASE; + hi /= _PyLong_DECIMAL_BASE; + } + /* check for keyboard interrupt */ + SIGCHECK({ + Py_DECREF(scratch); + return NULL; + }) + } + /* pout should have at least one digit, so that the case when a = 0 + works correctly */ + if (size == 0) + pout[size++] = 0; + + /* calculate exact length of output string, and allocate */ + strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT; + tenpow = 10; + rem = pout[size-1]; + while (rem >= tenpow) { + tenpow *= 10; + strlen++; + } + str = PyUnicode_FromUnicode(NULL, strlen); + if (str == NULL) { + Py_DECREF(scratch); + return NULL; + } + + /* fill the string right-to-left */ + p = PyUnicode_AS_UNICODE(str) + strlen; + *p = '\0'; + /* pout[0] through pout[size-2] contribute exactly + _PyLong_DECIMAL_SHIFT digits each */ + for (i=0; i < size - 1; i++) { + rem = pout[i]; + for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { + *--p = '0' + rem % 10; + rem /= 10; + } + } + /* pout[size-1]: always produce at least one decimal digit */ + rem = pout[i]; + do { + *--p = '0' + rem % 10; + rem /= 10; + } while (rem != 0); + + /* and sign */ + if (negative) + *--p = '-'; + + /* check we've counted correctly */ + assert(p == PyUnicode_AS_UNICODE(str)); + Py_DECREF(scratch); + return (PyObject *)str; } /* Convert a long int object to a string, using a given conversion base, @@ -1659,102 +1659,102 @@ long_to_decimal_string(PyObject *aa) PyObject * _PyLong_Format(PyObject *aa, int base) { - register PyLongObject *a = (PyLongObject *)aa; - PyObject *str; - Py_ssize_t i, sz; - Py_ssize_t size_a; - Py_UNICODE *p, sign = '\0'; - int bits; - - assert(base == 2 || base == 8 || base == 10 || base == 16); - if (base == 10) - return long_to_decimal_string((PyObject *)a); - - if (a == NULL || !PyLong_Check(a)) { - PyErr_BadInternalCall(); - return NULL; - } - size_a = ABS(Py_SIZE(a)); - - /* Compute a rough upper bound for the length of the string */ - switch (base) { - case 16: - bits = 4; - break; - case 8: - bits = 3; - break; - case 2: - bits = 1; - break; - default: - assert(0); /* shouldn't ever get here */ - bits = 0; /* to silence gcc warning */ - } - /* compute length of output string: allow 2 characters for prefix and - 1 for possible '-' sign. */ - if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { - PyErr_SetString(PyExc_OverflowError, - "int is too large to format"); - return NULL; - } - /* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below - is safe from overflow */ - sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits; - assert(sz >= 0); - str = PyUnicode_FromUnicode(NULL, sz); - if (str == NULL) - return NULL; - p = PyUnicode_AS_UNICODE(str) + sz; - *p = '\0'; - if (Py_SIZE(a) < 0) - sign = '-'; - - if (Py_SIZE(a) == 0) { - *--p = '0'; - } - else { - /* JRH: special case for power-of-2 bases */ - twodigits accum = 0; - int accumbits = 0; /* # of bits in accum */ - for (i = 0; i < size_a; ++i) { - accum |= (twodigits)a->ob_digit[i] << accumbits; - accumbits += PyLong_SHIFT; - assert(accumbits >= bits); - do { - Py_UNICODE cdigit; - cdigit = (Py_UNICODE)(accum & (base - 1)); - cdigit += (cdigit < 10) ? '0' : 'a'-10; - assert(p > PyUnicode_AS_UNICODE(str)); - *--p = cdigit; - accumbits -= bits; - accum >>= bits; - } while (i < size_a-1 ? accumbits >= bits : accum > 0); - } - } - - if (base == 16) - *--p = 'x'; - else if (base == 8) - *--p = 'o'; - else /* (base == 2) */ - *--p = 'b'; - *--p = '0'; - if (sign) - *--p = sign; - if (p != PyUnicode_AS_UNICODE(str)) { - Py_UNICODE *q = PyUnicode_AS_UNICODE(str); - assert(p > q); - do { - } while ((*q++ = *p++) != '\0'); - q--; - if (PyUnicode_Resize(&str,(Py_ssize_t) (q - - PyUnicode_AS_UNICODE(str)))) { - Py_DECREF(str); - return NULL; - } - } - return (PyObject *)str; + register PyLongObject *a = (PyLongObject *)aa; + PyObject *str; + Py_ssize_t i, sz; + Py_ssize_t size_a; + Py_UNICODE *p, sign = '\0'; + int bits; + + assert(base == 2 || base == 8 || base == 10 || base == 16); + if (base == 10) + return long_to_decimal_string((PyObject *)a); + + if (a == NULL || !PyLong_Check(a)) { + PyErr_BadInternalCall(); + return NULL; + } + size_a = ABS(Py_SIZE(a)); + + /* Compute a rough upper bound for the length of the string */ + switch (base) { + case 16: + bits = 4; + break; + case 8: + bits = 3; + break; + case 2: + bits = 1; + break; + default: + assert(0); /* shouldn't ever get here */ + bits = 0; /* to silence gcc warning */ + } + /* compute length of output string: allow 2 characters for prefix and + 1 for possible '-' sign. */ + if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { + PyErr_SetString(PyExc_OverflowError, + "int is too large to format"); + return NULL; + } + /* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below + is safe from overflow */ + sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits; + assert(sz >= 0); + str = PyUnicode_FromUnicode(NULL, sz); + if (str == NULL) + return NULL; + p = PyUnicode_AS_UNICODE(str) + sz; + *p = '\0'; + if (Py_SIZE(a) < 0) + sign = '-'; + + if (Py_SIZE(a) == 0) { + *--p = '0'; + } + else { + /* JRH: special case for power-of-2 bases */ + twodigits accum = 0; + int accumbits = 0; /* # of bits in accum */ + for (i = 0; i < size_a; ++i) { + accum |= (twodigits)a->ob_digit[i] << accumbits; + accumbits += PyLong_SHIFT; + assert(accumbits >= bits); + do { + Py_UNICODE cdigit; + cdigit = (Py_UNICODE)(accum & (base - 1)); + cdigit += (cdigit < 10) ? '0' : 'a'-10; + assert(p > PyUnicode_AS_UNICODE(str)); + *--p = cdigit; + accumbits -= bits; + accum >>= bits; + } while (i < size_a-1 ? accumbits >= bits : accum > 0); + } + } + + if (base == 16) + *--p = 'x'; + else if (base == 8) + *--p = 'o'; + else /* (base == 2) */ + *--p = 'b'; + *--p = '0'; + if (sign) + *--p = sign; + if (p != PyUnicode_AS_UNICODE(str)) { + Py_UNICODE *q = PyUnicode_AS_UNICODE(str); + assert(p > q); + do { + } while ((*q++ = *p++) != '\0'); + q--; + if (PyUnicode_Resize(&str,(Py_ssize_t) (q - + PyUnicode_AS_UNICODE(str)))) { + Py_DECREF(str); + return NULL; + } + } + return (PyObject *)str; } /* Table of digit values for 8-bit string -> integer conversion. @@ -1765,22 +1765,22 @@ _PyLong_Format(PyObject *aa, int base) * base B digit iff _PyLong_DigitValue[Py_CHARPyLong_MASK(c)] < B. */ unsigned char _PyLong_DigitValue[256] = { - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37, - 37, 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, 35, 37, 37, 37, 37, 37, - 37, 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, 35, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37, + 37, 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, 35, 37, 37, 37, 37, 37, + 37, 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, 35, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, }; /* *str points to the first digit in a string of base `base` digits. base @@ -1792,111 +1792,111 @@ unsigned char _PyLong_DigitValue[256] = { static PyLongObject * long_from_binary_base(char **str, int base) { - char *p = *str; - char *start = p; - int bits_per_char; - Py_ssize_t n; - PyLongObject *z; - twodigits accum; - int bits_in_accum; - digit *pdigit; - - assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0); - n = base; - for (bits_per_char = -1; n; ++bits_per_char) - n >>= 1; - /* n <- total # of bits needed, while setting p to end-of-string */ - while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) - ++p; - *str = p; - /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */ - n = (p - start) * bits_per_char + PyLong_SHIFT - 1; - if (n / bits_per_char < p - start) { - PyErr_SetString(PyExc_ValueError, - "int string too large to convert"); - return NULL; - } - n = n / PyLong_SHIFT; - z = _PyLong_New(n); - if (z == NULL) - return NULL; - /* Read string from right, and fill in long from left; i.e., - * from least to most significant in both. - */ - accum = 0; - bits_in_accum = 0; - pdigit = z->ob_digit; - while (--p >= start) { - int k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)]; - assert(k >= 0 && k < base); - accum |= (twodigits)k << bits_in_accum; - bits_in_accum += bits_per_char; - if (bits_in_accum >= PyLong_SHIFT) { - *pdigit++ = (digit)(accum & PyLong_MASK); - assert(pdigit - z->ob_digit <= n); - accum >>= PyLong_SHIFT; - bits_in_accum -= PyLong_SHIFT; - assert(bits_in_accum < PyLong_SHIFT); - } - } - if (bits_in_accum) { - assert(bits_in_accum <= PyLong_SHIFT); - *pdigit++ = (digit)accum; - assert(pdigit - z->ob_digit <= n); - } - while (pdigit - z->ob_digit < n) - *pdigit++ = 0; - return long_normalize(z); + char *p = *str; + char *start = p; + int bits_per_char; + Py_ssize_t n; + PyLongObject *z; + twodigits accum; + int bits_in_accum; + digit *pdigit; + + assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0); + n = base; + for (bits_per_char = -1; n; ++bits_per_char) + n >>= 1; + /* n <- total # of bits needed, while setting p to end-of-string */ + while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) + ++p; + *str = p; + /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */ + n = (p - start) * bits_per_char + PyLong_SHIFT - 1; + if (n / bits_per_char < p - start) { + PyErr_SetString(PyExc_ValueError, + "int string too large to convert"); + return NULL; + } + n = n / PyLong_SHIFT; + z = _PyLong_New(n); + if (z == NULL) + return NULL; + /* Read string from right, and fill in long from left; i.e., + * from least to most significant in both. + */ + accum = 0; + bits_in_accum = 0; + pdigit = z->ob_digit; + while (--p >= start) { + int k = (int)_PyLong_DigitValue[Py_CHARMASK(*p)]; + assert(k >= 0 && k < base); + accum |= (twodigits)k << bits_in_accum; + bits_in_accum += bits_per_char; + if (bits_in_accum >= PyLong_SHIFT) { + *pdigit++ = (digit)(accum & PyLong_MASK); + assert(pdigit - z->ob_digit <= n); + accum >>= PyLong_SHIFT; + bits_in_accum -= PyLong_SHIFT; + assert(bits_in_accum < PyLong_SHIFT); + } + } + if (bits_in_accum) { + assert(bits_in_accum <= PyLong_SHIFT); + *pdigit++ = (digit)accum; + assert(pdigit - z->ob_digit <= n); + } + while (pdigit - z->ob_digit < n) + *pdigit++ = 0; + return long_normalize(z); } PyObject * PyLong_FromString(char *str, char **pend, int base) { - int sign = 1, error_if_nonzero = 0; - char *start, *orig_str = str; - PyLongObject *z = NULL; - PyObject *strobj; - Py_ssize_t slen; - - if ((base != 0 && base < 2) || base > 36) { - PyErr_SetString(PyExc_ValueError, - "int() arg 2 must be >= 2 and <= 36"); - return NULL; - } - while (*str != '\0' && isspace(Py_CHARMASK(*str))) - str++; - if (*str == '+') - ++str; - else if (*str == '-') { - ++str; - sign = -1; - } - if (base == 0) { - if (str[0] != '0') - base = 10; - else if (str[1] == 'x' || str[1] == 'X') - base = 16; - else if (str[1] == 'o' || str[1] == 'O') - base = 8; - else if (str[1] == 'b' || str[1] == 'B') - base = 2; - else { - /* "old" (C-style) octal literal, now invalid. - it might still be zero though */ - error_if_nonzero = 1; - base = 10; - } - } - if (str[0] == '0' && - ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || - (base == 8 && (str[1] == 'o' || str[1] == 'O')) || - (base == 2 && (str[1] == 'b' || str[1] == 'B')))) - str += 2; - - start = str; - if ((base & (base - 1)) == 0) - z = long_from_binary_base(&str, base); - else { + int sign = 1, error_if_nonzero = 0; + char *start, *orig_str = str; + PyLongObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; + + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + while (*str != '\0' && isspace(Py_CHARMASK(*str))) + str++; + if (*str == '+') + ++str; + else if (*str == '-') { + ++str; + sign = -1; + } + if (base == 0) { + if (str[0] != '0') + base = 10; + else if (str[1] == 'x' || str[1] == 'X') + base = 16; + else if (str[1] == 'o' || str[1] == 'O') + base = 8; + else if (str[1] == 'b' || str[1] == 'B') + base = 2; + else { + /* "old" (C-style) octal literal, now invalid. + it might still be zero though */ + error_if_nonzero = 1; + base = 10; + } + } + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) + str += 2; + + start = str; + if ((base & (base - 1)) == 0) + z = long_from_binary_base(&str, base); + else { /*** Binary bases can be converted in time linear in the number of digits, because Python's representation base is binary. Other bases (including decimal!) use @@ -1982,227 +1982,227 @@ that triggers it(!). Instead the code was tested by artificially allocating just 1 digit at the start, so that the copying code was exercised for every digit beyond the first. ***/ - register twodigits c; /* current input character */ - Py_ssize_t size_z; - int i; - int convwidth; - twodigits convmultmax, convmult; - digit *pz, *pzstop; - char* scan; - - static double log_base_BASE[37] = {0.0e0,}; - static int convwidth_base[37] = {0,}; - static twodigits convmultmax_base[37] = {0,}; - - if (log_base_BASE[base] == 0.0) { - twodigits convmax = base; - int i = 1; - - log_base_BASE[base] = log((double)base) / - log((double)PyLong_BASE); - for (;;) { - twodigits next = convmax * base; - if (next > PyLong_BASE) - break; - convmax = next; - ++i; - } - convmultmax_base[base] = convmax; - assert(i > 0); - convwidth_base[base] = i; - } - - /* Find length of the string of numeric characters. */ - scan = str; - while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base) - ++scan; - - /* Create a long object that can contain the largest possible - * integer with this base and length. Note that there's no - * need to initialize z->ob_digit -- no slot is read up before - * being stored into. - */ - size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1; - /* Uncomment next line to test exceedingly rare copy code */ - /* size_z = 1; */ - assert(size_z > 0); - z = _PyLong_New(size_z); - if (z == NULL) - return NULL; - Py_SIZE(z) = 0; - - /* `convwidth` consecutive input digits are treated as a single - * digit in base `convmultmax`. - */ - convwidth = convwidth_base[base]; - convmultmax = convmultmax_base[base]; - - /* Work ;-) */ - while (str < scan) { - /* grab up to convwidth digits from the input string */ - c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; - for (i = 1; i < convwidth && str != scan; ++i, ++str) { - c = (twodigits)(c * base + - (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); - assert(c < PyLong_BASE); - } - - convmult = convmultmax; - /* Calculate the shift only if we couldn't get - * convwidth digits. - */ - if (i != convwidth) { - convmult = base; - for ( ; i > 1; --i) - convmult *= base; - } - - /* Multiply z by convmult, and add c. */ - pz = z->ob_digit; - pzstop = pz + Py_SIZE(z); - for (; pz < pzstop; ++pz) { - c += (twodigits)*pz * convmult; - *pz = (digit)(c & PyLong_MASK); - c >>= PyLong_SHIFT; - } - /* carry off the current end? */ - if (c) { - assert(c < PyLong_BASE); - if (Py_SIZE(z) < size_z) { - *pz = (digit)c; - ++Py_SIZE(z); - } - else { - PyLongObject *tmp; - /* Extremely rare. Get more space. */ - assert(Py_SIZE(z) == size_z); - tmp = _PyLong_New(size_z + 1); - if (tmp == NULL) { - Py_DECREF(z); - return NULL; - } - memcpy(tmp->ob_digit, - z->ob_digit, - sizeof(digit) * size_z); - Py_DECREF(z); - z = tmp; - z->ob_digit[size_z] = (digit)c; - ++size_z; - } - } - } - } - if (z == NULL) - return NULL; - if (error_if_nonzero) { - /* reset the base to 0, else the exception message - doesn't make too much sense */ - base = 0; - if (Py_SIZE(z) != 0) - goto onError; - /* there might still be other problems, therefore base - remains zero here for the same reason */ - } - if (str == start) - goto onError; - if (sign < 0) - Py_SIZE(z) = -(Py_SIZE(z)); - while (*str && isspace(Py_CHARMASK(*str))) - str++; - if (*str != '\0') - goto onError; - if (pend) - *pend = str; - long_normalize(z); - return (PyObject *) maybe_small_long(z); + register twodigits c; /* current input character */ + Py_ssize_t size_z; + int i; + int convwidth; + twodigits convmultmax, convmult; + digit *pz, *pzstop; + char* scan; + + static double log_base_BASE[37] = {0.0e0,}; + static int convwidth_base[37] = {0,}; + static twodigits convmultmax_base[37] = {0,}; + + if (log_base_BASE[base] == 0.0) { + twodigits convmax = base; + int i = 1; + + log_base_BASE[base] = log((double)base) / + log((double)PyLong_BASE); + for (;;) { + twodigits next = convmax * base; + if (next > PyLong_BASE) + break; + convmax = next; + ++i; + } + convmultmax_base[base] = convmax; + assert(i > 0); + convwidth_base[base] = i; + } + + /* Find length of the string of numeric characters. */ + scan = str; + while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base) + ++scan; + + /* Create a long object that can contain the largest possible + * integer with this base and length. Note that there's no + * need to initialize z->ob_digit -- no slot is read up before + * being stored into. + */ + size_z = (Py_ssize_t)((scan - str) * log_base_BASE[base]) + 1; + /* Uncomment next line to test exceedingly rare copy code */ + /* size_z = 1; */ + assert(size_z > 0); + z = _PyLong_New(size_z); + if (z == NULL) + return NULL; + Py_SIZE(z) = 0; + + /* `convwidth` consecutive input digits are treated as a single + * digit in base `convmultmax`. + */ + convwidth = convwidth_base[base]; + convmultmax = convmultmax_base[base]; + + /* Work ;-) */ + while (str < scan) { + /* grab up to convwidth digits from the input string */ + c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; + for (i = 1; i < convwidth && str != scan; ++i, ++str) { + c = (twodigits)(c * base + + (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); + assert(c < PyLong_BASE); + } + + convmult = convmultmax; + /* Calculate the shift only if we couldn't get + * convwidth digits. + */ + if (i != convwidth) { + convmult = base; + for ( ; i > 1; --i) + convmult *= base; + } + + /* Multiply z by convmult, and add c. */ + pz = z->ob_digit; + pzstop = pz + Py_SIZE(z); + for (; pz < pzstop; ++pz) { + c += (twodigits)*pz * convmult; + *pz = (digit)(c & PyLong_MASK); + c >>= PyLong_SHIFT; + } + /* carry off the current end? */ + if (c) { + assert(c < PyLong_BASE); + if (Py_SIZE(z) < size_z) { + *pz = (digit)c; + ++Py_SIZE(z); + } + else { + PyLongObject *tmp; + /* Extremely rare. Get more space. */ + assert(Py_SIZE(z) == size_z); + tmp = _PyLong_New(size_z + 1); + if (tmp == NULL) { + Py_DECREF(z); + return NULL; + } + memcpy(tmp->ob_digit, + z->ob_digit, + sizeof(digit) * size_z); + Py_DECREF(z); + z = tmp; + z->ob_digit[size_z] = (digit)c; + ++size_z; + } + } + } + } + if (z == NULL) + return NULL; + if (error_if_nonzero) { + /* reset the base to 0, else the exception message + doesn't make too much sense */ + base = 0; + if (Py_SIZE(z) != 0) + goto onError; + /* there might still be other problems, therefore base + remains zero here for the same reason */ + } + if (str == start) + goto onError; + if (sign < 0) + Py_SIZE(z) = -(Py_SIZE(z)); + while (*str && isspace(Py_CHARMASK(*str))) + str++; + if (*str != '\0') + goto onError; + if (pend) + *pend = str; + long_normalize(z); + return (PyObject *) maybe_small_long(z); onError: - Py_XDECREF(z); - slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; - strobj = PyUnicode_FromStringAndSize(orig_str, slen); - if (strobj == NULL) - return NULL; - PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", - base, strobj); - Py_DECREF(strobj); - return NULL; + Py_XDECREF(z); + slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; + strobj = PyUnicode_FromStringAndSize(orig_str, slen); + if (strobj == NULL) + return NULL; + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %R", + base, strobj); + Py_DECREF(strobj); + return NULL; } PyObject * PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) { - PyObject *result; - char *buffer = (char *)PyMem_MALLOC(length+1); - - if (buffer == NULL) - return NULL; - - if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) { - PyMem_FREE(buffer); - return NULL; - } - result = PyLong_FromString(buffer, NULL, base); - PyMem_FREE(buffer); - return result; + PyObject *result; + char *buffer = (char *)PyMem_MALLOC(length+1); + + if (buffer == NULL) + return NULL; + + if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) { + PyMem_FREE(buffer); + return NULL; + } + result = PyLong_FromString(buffer, NULL, base); + PyMem_FREE(buffer); + return result; } /* forward */ static PyLongObject *x_divrem - (PyLongObject *, PyLongObject *, PyLongObject **); + (PyLongObject *, PyLongObject *, PyLongObject **); static PyObject *long_long(PyObject *v); /* Long division with remainder, top-level routine */ static int long_divrem(PyLongObject *a, PyLongObject *b, - PyLongObject **pdiv, PyLongObject **prem) + PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); - PyLongObject *z; - - if (size_b == 0) { - PyErr_SetString(PyExc_ZeroDivisionError, - "integer division or modulo by zero"); - return -1; - } - if (size_a < size_b || - (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { - /* |a| < |b|. */ - *pdiv = (PyLongObject*)PyLong_FromLong(0); - if (*pdiv == NULL) - return -1; - Py_INCREF(a); - *prem = (PyLongObject *) a; - return 0; - } - if (size_b == 1) { - digit rem = 0; - z = divrem1(a, b->ob_digit[0], &rem); - if (z == NULL) - return -1; - *prem = (PyLongObject *) PyLong_FromLong((long)rem); - if (*prem == NULL) { - Py_DECREF(z); - return -1; - } - } - else { - z = x_divrem(a, b, prem); - if (z == NULL) - return -1; - } - /* Set the signs. - The quotient z has the sign of a*b; - the remainder r has the sign of a, - so a = b*z + r. */ - if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) - NEGATE(z); - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) - NEGATE(*prem); - *pdiv = maybe_small_long(z); - return 0; + Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + PyLongObject *z; + + if (size_b == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "integer division or modulo by zero"); + return -1; + } + if (size_a < size_b || + (size_a == size_b && + a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + /* |a| < |b|. */ + *pdiv = (PyLongObject*)PyLong_FromLong(0); + if (*pdiv == NULL) + return -1; + Py_INCREF(a); + *prem = (PyLongObject *) a; + return 0; + } + if (size_b == 1) { + digit rem = 0; + z = divrem1(a, b->ob_digit[0], &rem); + if (z == NULL) + return -1; + *prem = (PyLongObject *) PyLong_FromLong((long)rem); + if (*prem == NULL) { + Py_DECREF(z); + return -1; + } + } + else { + z = x_divrem(a, b, prem); + if (z == NULL) + return -1; + } + /* Set the signs. + The quotient z has the sign of a*b; + the remainder r has the sign of a, + so a = b*z + r. */ + if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) + NEGATE(z); + if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) + NEGATE(*prem); + *pdiv = maybe_small_long(z); + return 0; } /* Unsigned long division with remainder -- the algorithm. The arguments v1 @@ -2211,125 +2211,125 @@ long_divrem(PyLongObject *a, PyLongObject *b, static PyLongObject * x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) { - PyLongObject *v, *w, *a; - Py_ssize_t i, k, size_v, size_w; - int d; - digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak; - twodigits vv; - sdigit zhi; - stwodigits z; - - /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd - edn.), section 4.3.1, Algorithm D], except that we don't explicitly - handle the special case when the initial estimate q for a quotient - digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and - that won't overflow a digit. */ - - /* allocate space; w will also be used to hold the final remainder */ - size_v = ABS(Py_SIZE(v1)); - size_w = ABS(Py_SIZE(w1)); - assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ - v = _PyLong_New(size_v+1); - if (v == NULL) { - *prem = NULL; - return NULL; - } - w = _PyLong_New(size_w); - if (w == NULL) { - Py_DECREF(v); - *prem = NULL; - return NULL; - } - - /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. - shift v1 left by the same amount. Results go into w and v. */ - d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]); - carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); - assert(carry == 0); - carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); - if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { - v->ob_digit[size_v] = carry; - size_v++; - } - - /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has - at most (and usually exactly) k = size_v - size_w digits. */ - k = size_v - size_w; - assert(k >= 0); - a = _PyLong_New(k); - if (a == NULL) { - Py_DECREF(w); - Py_DECREF(v); - *prem = NULL; - return NULL; - } - v0 = v->ob_digit; - w0 = w->ob_digit; - wm1 = w0[size_w-1]; - wm2 = w0[size_w-2]; - for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { - /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving - single-digit quotient q, remainder in vk[0:size_w]. */ - - SIGCHECK({ - Py_DECREF(a); - Py_DECREF(w); - Py_DECREF(v); - *prem = NULL; - return NULL; - }) - - /* estimate quotient digit q; may overestimate by 1 (rare) */ - vtop = vk[size_w]; - assert(vtop <= wm1); - vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1]; - q = (digit)(vv / wm1); - r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */ - while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT) - | vk[size_w-2])) { - --q; - r += wm1; - if (r >= PyLong_BASE) - break; - } - assert(q <= PyLong_BASE); - - /* subtract q*w0[0:size_w] from vk[0:size_w+1] */ - zhi = 0; - for (i = 0; i < size_w; ++i) { - /* invariants: -PyLong_BASE <= -q <= zhi <= 0; - -PyLong_BASE * q <= z < PyLong_BASE */ - z = (sdigit)vk[i] + zhi - - (stwodigits)q * (stwodigits)w0[i]; - vk[i] = (digit)z & PyLong_MASK; - zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, - z, PyLong_SHIFT); - } - - /* add w back if q was too large (this branch taken rarely) */ - assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0); - if ((sdigit)vtop + zhi < 0) { - carry = 0; - for (i = 0; i < size_w; ++i) { - carry += vk[i] + w0[i]; - vk[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - } - --q; - } - - /* store quotient digit */ - assert(q < PyLong_BASE); - *--ak = q; - } - - /* unshift remainder; we reuse w to store the result */ - carry = v_rshift(w0, v0, size_w, d); - assert(carry==0); - Py_DECREF(v); - - *prem = long_normalize(w); - return long_normalize(a); + PyLongObject *v, *w, *a; + Py_ssize_t i, k, size_v, size_w; + int d; + digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak; + twodigits vv; + sdigit zhi; + stwodigits z; + + /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd + edn.), section 4.3.1, Algorithm D], except that we don't explicitly + handle the special case when the initial estimate q for a quotient + digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and + that won't overflow a digit. */ + + /* allocate space; w will also be used to hold the final remainder */ + size_v = ABS(Py_SIZE(v1)); + size_w = ABS(Py_SIZE(w1)); + assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ + v = _PyLong_New(size_v+1); + if (v == NULL) { + *prem = NULL; + return NULL; + } + w = _PyLong_New(size_w); + if (w == NULL) { + Py_DECREF(v); + *prem = NULL; + return NULL; + } + + /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. + shift v1 left by the same amount. Results go into w and v. */ + d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]); + carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); + assert(carry == 0); + carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); + if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { + v->ob_digit[size_v] = carry; + size_v++; + } + + /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has + at most (and usually exactly) k = size_v - size_w digits. */ + k = size_v - size_w; + assert(k >= 0); + a = _PyLong_New(k); + if (a == NULL) { + Py_DECREF(w); + Py_DECREF(v); + *prem = NULL; + return NULL; + } + v0 = v->ob_digit; + w0 = w->ob_digit; + wm1 = w0[size_w-1]; + wm2 = w0[size_w-2]; + for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { + /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving + single-digit quotient q, remainder in vk[0:size_w]. */ + + SIGCHECK({ + Py_DECREF(a); + Py_DECREF(w); + Py_DECREF(v); + *prem = NULL; + return NULL; + }) + + /* estimate quotient digit q; may overestimate by 1 (rare) */ + vtop = vk[size_w]; + assert(vtop <= wm1); + vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1]; + q = (digit)(vv / wm1); + r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */ + while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT) + | vk[size_w-2])) { + --q; + r += wm1; + if (r >= PyLong_BASE) + break; + } + assert(q <= PyLong_BASE); + + /* subtract q*w0[0:size_w] from vk[0:size_w+1] */ + zhi = 0; + for (i = 0; i < size_w; ++i) { + /* invariants: -PyLong_BASE <= -q <= zhi <= 0; + -PyLong_BASE * q <= z < PyLong_BASE */ + z = (sdigit)vk[i] + zhi - + (stwodigits)q * (stwodigits)w0[i]; + vk[i] = (digit)z & PyLong_MASK; + zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, + z, PyLong_SHIFT); + } + + /* add w back if q was too large (this branch taken rarely) */ + assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0); + if ((sdigit)vtop + zhi < 0) { + carry = 0; + for (i = 0; i < size_w; ++i) { + carry += vk[i] + w0[i]; + vk[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + --q; + } + + /* store quotient digit */ + assert(q < PyLong_BASE); + *--ak = q; + } + + /* unshift remainder; we reuse w to store the result */ + carry = v_rshift(w0, v0, size_w, d); + assert(carry==0); + Py_DECREF(v); + + *prem = long_normalize(w); + return long_normalize(a); } /* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <= @@ -2349,111 +2349,111 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) double _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) { - Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size; - /* See below for why x_digits is always large enough. */ - digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT]; - double dx; - /* Correction term for round-half-to-even rounding. For a digit x, - "x + half_even_correction[x & 7]" gives x rounded to the nearest - multiple of 4, rounding ties to a multiple of 8. */ - static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; - - a_size = ABS(Py_SIZE(a)); - if (a_size == 0) { - /* Special case for 0: significand 0.0, exponent 0. */ - *e = 0; - return 0.0; - } - a_bits = bits_in_digit(a->ob_digit[a_size-1]); - /* The following is an overflow-free version of the check - "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ - if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && - (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || - a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) - goto overflow; - a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; - - /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] - (shifting left if a_bits <= DBL_MANT_DIG + 2). - - Number of digits needed for result: write // for floor division. - Then if shifting left, we end up using - - 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT - - digits. If shifting right, we use - - a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT - - digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with - the inequalities - - m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT - m // PyLong_SHIFT - n // PyLong_SHIFT <= - 1 + (m - n - 1) // PyLong_SHIFT, - - valid for any integers m and n, we find that x_size satisfies - - x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT - - in both cases. - */ - if (a_bits <= DBL_MANT_DIG + 2) { - shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; - shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; - x_size = 0; - while (x_size < shift_digits) - x_digits[x_size++] = 0; - rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, - (int)shift_bits); - x_size += a_size; - x_digits[x_size++] = rem; - } - else { - shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; - shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; - rem = v_rshift(x_digits, a->ob_digit + shift_digits, - a_size - shift_digits, (int)shift_bits); - x_size = a_size - shift_digits; - /* For correct rounding below, we need the least significant - bit of x to be 'sticky' for this shift: if any of the bits - shifted out was nonzero, we set the least significant bit - of x. */ - if (rem) - x_digits[0] |= 1; - else - while (shift_digits > 0) - if (a->ob_digit[--shift_digits]) { - x_digits[0] |= 1; - break; - } - } - assert(1 <= x_size && x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit))); - - /* Round, and convert to double. */ - x_digits[0] += half_even_correction[x_digits[0] & 7]; - dx = x_digits[--x_size]; - while (x_size > 0) - dx = dx * PyLong_BASE + x_digits[--x_size]; - - /* Rescale; make correction if result is 1.0. */ - dx /= 4.0 * EXP2_DBL_MANT_DIG; - if (dx == 1.0) { - if (a_bits == PY_SSIZE_T_MAX) - goto overflow; - dx = 0.5; - a_bits += 1; - } - - *e = a_bits; - return Py_SIZE(a) < 0 ? -dx : dx; + Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size; + /* See below for why x_digits is always large enough. */ + digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT]; + double dx; + /* Correction term for round-half-to-even rounding. For a digit x, + "x + half_even_correction[x & 7]" gives x rounded to the nearest + multiple of 4, rounding ties to a multiple of 8. */ + static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; + + a_size = ABS(Py_SIZE(a)); + if (a_size == 0) { + /* Special case for 0: significand 0.0, exponent 0. */ + *e = 0; + return 0.0; + } + a_bits = bits_in_digit(a->ob_digit[a_size-1]); + /* The following is an overflow-free version of the check + "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ + if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && + (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || + a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) + goto overflow; + a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; + + /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] + (shifting left if a_bits <= DBL_MANT_DIG + 2). + + Number of digits needed for result: write // for floor division. + Then if shifting left, we end up using + + 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT + + digits. If shifting right, we use + + a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT + + digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with + the inequalities + + m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT + m // PyLong_SHIFT - n // PyLong_SHIFT <= + 1 + (m - n - 1) // PyLong_SHIFT, + + valid for any integers m and n, we find that x_size satisfies + + x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT + + in both cases. + */ + if (a_bits <= DBL_MANT_DIG + 2) { + shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; + shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; + x_size = 0; + while (x_size < shift_digits) + x_digits[x_size++] = 0; + rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + (int)shift_bits); + x_size += a_size; + x_digits[x_size++] = rem; + } + else { + shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; + shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; + rem = v_rshift(x_digits, a->ob_digit + shift_digits, + a_size - shift_digits, (int)shift_bits); + x_size = a_size - shift_digits; + /* For correct rounding below, we need the least significant + bit of x to be 'sticky' for this shift: if any of the bits + shifted out was nonzero, we set the least significant bit + of x. */ + if (rem) + x_digits[0] |= 1; + else + while (shift_digits > 0) + if (a->ob_digit[--shift_digits]) { + x_digits[0] |= 1; + break; + } + } + assert(1 <= x_size && x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit))); + + /* Round, and convert to double. */ + x_digits[0] += half_even_correction[x_digits[0] & 7]; + dx = x_digits[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x_digits[--x_size]; + + /* Rescale; make correction if result is 1.0. */ + dx /= 4.0 * EXP2_DBL_MANT_DIG; + if (dx == 1.0) { + if (a_bits == PY_SSIZE_T_MAX) + goto overflow; + dx = 0.5; + a_bits += 1; + } + + *e = a_bits; + return Py_SIZE(a) < 0 ? -dx : dx; overflow: - /* exponent > PY_SSIZE_T_MAX */ - PyErr_SetString(PyExc_OverflowError, - "huge integer: number of bits overflows a Py_ssize_t"); - *e = 0; - return -1.0; + /* exponent > PY_SSIZE_T_MAX */ + PyErr_SetString(PyExc_OverflowError, + "huge integer: number of bits overflows a Py_ssize_t"); + *e = 0; + return -1.0; } /* Get a C double from a long int object. Rounds to the nearest double, @@ -2462,20 +2462,20 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) double PyLong_AsDouble(PyObject *v) { - Py_ssize_t exponent; - double x; - - if (v == NULL || !PyLong_Check(v)) { - PyErr_BadInternalCall(); - return -1.0; - } - x = _PyLong_Frexp((PyLongObject *)v, &exponent); - if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { - PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to float"); - return -1.0; - } - return ldexp(x, (int)exponent); + Py_ssize_t exponent; + double x; + + if (v == NULL || !PyLong_Check(v)) { + PyErr_BadInternalCall(); + return -1.0; + } + x = _PyLong_Frexp((PyLongObject *)v, &exponent); + if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { + PyErr_SetString(PyExc_OverflowError, + "long int too large to convert to float"); + return -1.0; + } + return ldexp(x, (int)exponent); } /* Methods */ @@ -2483,109 +2483,109 @@ PyLong_AsDouble(PyObject *v) static void long_dealloc(PyObject *v) { - Py_TYPE(v)->tp_free(v); + Py_TYPE(v)->tp_free(v); } static int long_compare(PyLongObject *a, PyLongObject *b) { - Py_ssize_t sign; - - if (Py_SIZE(a) != Py_SIZE(b)) { - sign = Py_SIZE(a) - Py_SIZE(b); - } - else { - Py_ssize_t i = ABS(Py_SIZE(a)); - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) - ; - if (i < 0) - sign = 0; - else { - sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; - if (Py_SIZE(a) < 0) - sign = -sign; - } - } - return sign < 0 ? -1 : sign > 0 ? 1 : 0; + Py_ssize_t sign; + + if (Py_SIZE(a) != Py_SIZE(b)) { + sign = Py_SIZE(a) - Py_SIZE(b); + } + else { + Py_ssize_t i = ABS(Py_SIZE(a)); + while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + ; + if (i < 0) + sign = 0; + else { + sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; + if (Py_SIZE(a) < 0) + sign = -sign; + } + } + return sign < 0 ? -1 : sign > 0 ? 1 : 0; } #define TEST_COND(cond) \ - ((cond) ? Py_True : Py_False) + ((cond) ? Py_True : Py_False) static PyObject * long_richcompare(PyObject *self, PyObject *other, int op) { - int result; - PyObject *v; - CHECK_BINOP(self, other); - if (self == other) - result = 0; - else - result = long_compare((PyLongObject*)self, (PyLongObject*)other); - /* Convert the return value to a Boolean */ - switch (op) { - case Py_EQ: - v = TEST_COND(result == 0); - break; - case Py_NE: - v = TEST_COND(result != 0); - break; - case Py_LE: - v = TEST_COND(result <= 0); - break; - case Py_GE: - v = TEST_COND(result >= 0); - break; - case Py_LT: - v = TEST_COND(result == -1); - break; - case Py_GT: - v = TEST_COND(result == 1); - break; - default: - PyErr_BadArgument(); - return NULL; - } - Py_INCREF(v); - return v; + int result; + PyObject *v; + CHECK_BINOP(self, other); + if (self == other) + result = 0; + else + result = long_compare((PyLongObject*)self, (PyLongObject*)other); + /* Convert the return value to a Boolean */ + switch (op) { + case Py_EQ: + v = TEST_COND(result == 0); + break; + case Py_NE: + v = TEST_COND(result != 0); + break; + case Py_LE: + v = TEST_COND(result <= 0); + break; + case Py_GE: + v = TEST_COND(result >= 0); + break; + case Py_LT: + v = TEST_COND(result == -1); + break; + case Py_GT: + v = TEST_COND(result == 1); + break; + default: + PyErr_BadArgument(); + return NULL; + } + Py_INCREF(v); + return v; } static long long_hash(PyLongObject *v) { - unsigned long x; - Py_ssize_t i; - int sign; - - i = Py_SIZE(v); - switch(i) { - case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; - } - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } - /* The following loop produces a C unsigned long x such that x is - congruent to the absolute value of v modulo ULONG_MAX. The - resulting x is nonzero if and only if v is. */ - while (--i >= 0) { - /* Force a native long #-bits (32 or 64) circular shift */ - x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT); - x += v->ob_digit[i]; - /* If the addition above overflowed we compensate by - incrementing. This preserves the value modulo - ULONG_MAX. */ - if (x < v->ob_digit[i]) - x++; - } - x = x * sign; - if (x == (unsigned long)-1) - x = (unsigned long)-2; - return (long)x; + unsigned long x; + Py_ssize_t i; + int sign; + + i = Py_SIZE(v); + switch(i) { + case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -(i); + } + /* The following loop produces a C unsigned long x such that x is + congruent to the absolute value of v modulo ULONG_MAX. The + resulting x is nonzero if and only if v is. */ + while (--i >= 0) { + /* Force a native long #-bits (32 or 64) circular shift */ + x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT); + x += v->ob_digit[i]; + /* If the addition above overflowed we compensate by + incrementing. This preserves the value modulo + ULONG_MAX. */ + if (x < v->ob_digit[i]) + x++; + } + x = x * sign; + if (x == (unsigned long)-1) + x = (unsigned long)-2; + return (long)x; } @@ -2594,33 +2594,33 @@ long_hash(PyLongObject *v) static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); - PyLongObject *z; - Py_ssize_t i; - digit carry = 0; - - /* Ensure a is the larger of the two: */ - if (size_a < size_b) { - { PyLongObject *temp = a; a = b; b = temp; } - { Py_ssize_t size_temp = size_a; - size_a = size_b; - size_b = size_temp; } - } - z = _PyLong_New(size_a+1); - if (z == NULL) - return NULL; - for (i = 0; i < size_b; ++i) { - carry += a->ob_digit[i] + b->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - } - for (; i < size_a; ++i) { - carry += a->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - } - z->ob_digit[i] = carry; - return long_normalize(z); + Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + PyLongObject *z; + Py_ssize_t i; + digit carry = 0; + + /* Ensure a is the larger of the two: */ + if (size_a < size_b) { + { PyLongObject *temp = a; a = b; b = temp; } + { Py_ssize_t size_temp = size_a; + size_a = size_b; + size_b = size_temp; } + } + z = _PyLong_New(size_a+1); + if (z == NULL) + return NULL; + for (i = 0; i < size_b; ++i) { + carry += a->ob_digit[i] + b->ob_digit[i]; + z->ob_digit[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + for (; i < size_a; ++i) { + carry += a->ob_digit[i]; + z->ob_digit[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + z->ob_digit[i] = carry; + return long_normalize(z); } /* Subtract the absolute values of two integers. */ @@ -2628,113 +2628,113 @@ x_add(PyLongObject *a, PyLongObject *b) static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); - PyLongObject *z; - Py_ssize_t i; - int sign = 1; - digit borrow = 0; - - /* Ensure a is the larger of the two: */ - if (size_a < size_b) { - sign = -1; - { PyLongObject *temp = a; a = b; b = temp; } - { Py_ssize_t size_temp = size_a; - size_a = size_b; - size_b = size_temp; } - } - else if (size_a == size_b) { - /* Find highest digit where a and b differ: */ - i = size_a; - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) - ; - if (i < 0) - return (PyLongObject *)PyLong_FromLong(0); - if (a->ob_digit[i] < b->ob_digit[i]) { - sign = -1; - { PyLongObject *temp = a; a = b; b = temp; } - } - size_a = size_b = i+1; - } - z = _PyLong_New(size_a); - if (z == NULL) - return NULL; - for (i = 0; i < size_b; ++i) { - /* The following assumes unsigned arithmetic - works module 2**N for some N>PyLong_SHIFT. */ - borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; - borrow >>= PyLong_SHIFT; - borrow &= 1; /* Keep only one sign bit */ - } - for (; i < size_a; ++i) { - borrow = a->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; - borrow >>= PyLong_SHIFT; - borrow &= 1; /* Keep only one sign bit */ - } - assert(borrow == 0); - if (sign < 0) - NEGATE(z); - return long_normalize(z); + Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + PyLongObject *z; + Py_ssize_t i; + int sign = 1; + digit borrow = 0; + + /* Ensure a is the larger of the two: */ + if (size_a < size_b) { + sign = -1; + { PyLongObject *temp = a; a = b; b = temp; } + { Py_ssize_t size_temp = size_a; + size_a = size_b; + size_b = size_temp; } + } + else if (size_a == size_b) { + /* Find highest digit where a and b differ: */ + i = size_a; + while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + ; + if (i < 0) + return (PyLongObject *)PyLong_FromLong(0); + if (a->ob_digit[i] < b->ob_digit[i]) { + sign = -1; + { PyLongObject *temp = a; a = b; b = temp; } + } + size_a = size_b = i+1; + } + z = _PyLong_New(size_a); + if (z == NULL) + return NULL; + for (i = 0; i < size_b; ++i) { + /* The following assumes unsigned arithmetic + works module 2**N for some N>PyLong_SHIFT. */ + borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; + z->ob_digit[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* Keep only one sign bit */ + } + for (; i < size_a; ++i) { + borrow = a->ob_digit[i] - borrow; + z->ob_digit[i] = borrow & PyLong_MASK; + borrow >>= PyLong_SHIFT; + borrow &= 1; /* Keep only one sign bit */ + } + assert(borrow == 0); + if (sign < 0) + NEGATE(z); + return long_normalize(z); } static PyObject * long_add(PyLongObject *a, PyLongObject *b) { - PyLongObject *z; - - CHECK_BINOP(a, b); - - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { - PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + - MEDIUM_VALUE(b)); - return result; - } - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { - z = x_add(a, b); - if (z != NULL && Py_SIZE(z) != 0) - Py_SIZE(z) = -(Py_SIZE(z)); - } - else - z = x_sub(b, a); - } - else { - if (Py_SIZE(b) < 0) - z = x_sub(a, b); - else - z = x_add(a, b); - } - return (PyObject *)z; + PyLongObject *z; + + CHECK_BINOP(a, b); + + if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + + MEDIUM_VALUE(b)); + return result; + } + if (Py_SIZE(a) < 0) { + if (Py_SIZE(b) < 0) { + z = x_add(a, b); + if (z != NULL && Py_SIZE(z) != 0) + Py_SIZE(z) = -(Py_SIZE(z)); + } + else + z = x_sub(b, a); + } + else { + if (Py_SIZE(b) < 0) + z = x_sub(a, b); + else + z = x_add(a, b); + } + return (PyObject *)z; } static PyObject * long_sub(PyLongObject *a, PyLongObject *b) { - PyLongObject *z; - - CHECK_BINOP(a, b); - - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { - PyObject* r; - r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); - return r; - } - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) - z = x_sub(a, b); - else - z = x_add(a, b); - if (z != NULL && Py_SIZE(z) != 0) - Py_SIZE(z) = -(Py_SIZE(z)); - } - else { - if (Py_SIZE(b) < 0) - z = x_add(a, b); - else - z = x_sub(a, b); - } - return (PyObject *)z; + PyLongObject *z; + + CHECK_BINOP(a, b); + + if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + PyObject* r; + r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); + return r; + } + if (Py_SIZE(a) < 0) { + if (Py_SIZE(b) < 0) + z = x_sub(a, b); + else + z = x_add(a, b); + if (z != NULL && Py_SIZE(z) != 0) + Py_SIZE(z) = -(Py_SIZE(z)); + } + else { + if (Py_SIZE(b) < 0) + z = x_add(a, b); + else + z = x_sub(a, b); + } + return (PyObject *)z; } /* Grade school multiplication, ignoring the signs. @@ -2743,85 +2743,85 @@ long_sub(PyLongObject *a, PyLongObject *b) static PyLongObject * x_mul(PyLongObject *a, PyLongObject *b) { - PyLongObject *z; - Py_ssize_t size_a = ABS(Py_SIZE(a)); - Py_ssize_t size_b = ABS(Py_SIZE(b)); - Py_ssize_t i; - - z = _PyLong_New(size_a + size_b); - if (z == NULL) - return NULL; - - memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); - if (a == b) { - /* Efficient squaring per HAC, Algorithm 14.16: - * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf - * Gives slightly less than a 2x speedup when a == b, - * via exploiting that each entry in the multiplication - * pyramid appears twice (except for the size_a squares). - */ - for (i = 0; i < size_a; ++i) { - twodigits carry; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + (i << 1); - digit *pa = a->ob_digit + i + 1; - digit *paend = a->ob_digit + size_a; - - SIGCHECK({ - Py_DECREF(z); - return NULL; - }) - - carry = *pz + f * f; - *pz++ = (digit)(carry & PyLong_MASK); - carry >>= PyLong_SHIFT; - assert(carry <= PyLong_MASK); - - /* Now f is added in twice in each column of the - * pyramid it appears. Same as adding f<<1 once. - */ - f <<= 1; - while (pa < paend) { - carry += *pz + *pa++ * f; - *pz++ = (digit)(carry & PyLong_MASK); - carry >>= PyLong_SHIFT; - assert(carry <= (PyLong_MASK << 1)); - } - if (carry) { - carry += *pz; - *pz++ = (digit)(carry & PyLong_MASK); - carry >>= PyLong_SHIFT; - } - if (carry) - *pz += (digit)(carry & PyLong_MASK); - assert((carry >> PyLong_SHIFT) == 0); - } - } - else { /* a is not the same as b -- gradeschool long mult */ - for (i = 0; i < size_a; ++i) { - twodigits carry = 0; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + i; - digit *pb = b->ob_digit; - digit *pbend = b->ob_digit + size_b; - - SIGCHECK({ - Py_DECREF(z); - return NULL; - }) - - while (pb < pbend) { - carry += *pz + *pb++ * f; - *pz++ = (digit)(carry & PyLong_MASK); - carry >>= PyLong_SHIFT; - assert(carry <= PyLong_MASK); - } - if (carry) - *pz += (digit)(carry & PyLong_MASK); - assert((carry >> PyLong_SHIFT) == 0); - } - } - return long_normalize(z); + PyLongObject *z; + Py_ssize_t size_a = ABS(Py_SIZE(a)); + Py_ssize_t size_b = ABS(Py_SIZE(b)); + Py_ssize_t i; + + z = _PyLong_New(size_a + size_b); + if (z == NULL) + return NULL; + + memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); + if (a == b) { + /* Efficient squaring per HAC, Algorithm 14.16: + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * Gives slightly less than a 2x speedup when a == b, + * via exploiting that each entry in the multiplication + * pyramid appears twice (except for the size_a squares). + */ + for (i = 0; i < size_a; ++i) { + twodigits carry; + twodigits f = a->ob_digit[i]; + digit *pz = z->ob_digit + (i << 1); + digit *pa = a->ob_digit + i + 1; + digit *paend = a->ob_digit + size_a; + + SIGCHECK({ + Py_DECREF(z); + return NULL; + }) + + carry = *pz + f * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= PyLong_MASK); + + /* Now f is added in twice in each column of the + * pyramid it appears. Same as adding f<<1 once. + */ + f <<= 1; + while (pa < paend) { + carry += *pz + *pa++ * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= (PyLong_MASK << 1)); + } + if (carry) { + carry += *pz; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + } + if (carry) + *pz += (digit)(carry & PyLong_MASK); + assert((carry >> PyLong_SHIFT) == 0); + } + } + else { /* a is not the same as b -- gradeschool long mult */ + for (i = 0; i < size_a; ++i) { + twodigits carry = 0; + twodigits f = a->ob_digit[i]; + digit *pz = z->ob_digit + i; + digit *pb = b->ob_digit; + digit *pbend = b->ob_digit + size_b; + + SIGCHECK({ + Py_DECREF(z); + return NULL; + }) + + while (pb < pbend) { + carry += *pz + *pb++ * f; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= PyLong_MASK); + } + if (carry) + *pz += (digit)(carry & PyLong_MASK); + assert((carry >> PyLong_SHIFT) == 0); + } + } + return long_normalize(z); } /* A helper for Karatsuba multiplication (k_mul). @@ -2834,26 +2834,26 @@ x_mul(PyLongObject *a, PyLongObject *b) static int kmul_split(PyLongObject *n, Py_ssize_t size, PyLongObject **high, PyLongObject **low) { - PyLongObject *hi, *lo; - Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = ABS(Py_SIZE(n)); - - size_lo = MIN(size_n, size); - size_hi = size_n - size_lo; - - if ((hi = _PyLong_New(size_hi)) == NULL) - return -1; - if ((lo = _PyLong_New(size_lo)) == NULL) { - Py_DECREF(hi); - return -1; - } - - memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); - memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); - - *high = long_normalize(hi); - *low = long_normalize(lo); - return 0; + PyLongObject *hi, *lo; + Py_ssize_t size_lo, size_hi; + const Py_ssize_t size_n = ABS(Py_SIZE(n)); + + size_lo = MIN(size_n, size); + size_hi = size_n - size_lo; + + if ((hi = _PyLong_New(size_hi)) == NULL) + return -1; + if ((lo = _PyLong_New(size_lo)) == NULL) { + Py_DECREF(hi); + return -1; + } + + memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); + memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); + + *high = long_normalize(hi); + *low = long_normalize(lo); + return 0; } static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); @@ -2865,169 +2865,169 @@ static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); - PyLongObject *ah = NULL; - PyLongObject *al = NULL; - PyLongObject *bh = NULL; - PyLongObject *bl = NULL; - PyLongObject *ret = NULL; - PyLongObject *t1, *t2, *t3; - Py_ssize_t shift; /* the number of digits we split off */ - Py_ssize_t i; - - /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl - * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl - * Then the original product is - * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl - * By picking X to be a power of 2, "*X" is just shifting, and it's - * been reduced to 3 multiplies on numbers half the size. - */ - - /* We want to split based on the larger number; fiddle so that b - * is largest. - */ - if (asize > bsize) { - t1 = a; - a = b; - b = t1; - - i = asize; - asize = bsize; - bsize = i; - } - - /* Use gradeschool math when either number is too small. */ - i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF; - if (asize <= i) { - if (asize == 0) - return (PyLongObject *)PyLong_FromLong(0); - else - return x_mul(a, b); - } - - /* If a is small compared to b, splitting on b gives a degenerate - * case with ah==0, and Karatsuba may be (even much) less efficient - * than "grade school" then. However, we can still win, by viewing - * b as a string of "big digits", each of width a->ob_size. That - * leads to a sequence of balanced calls to k_mul. - */ - if (2 * asize <= bsize) - return k_lopsided_mul(a, b); - - /* Split a & b into hi & lo pieces. */ - shift = bsize >> 1; - if (kmul_split(a, shift, &ah, &al) < 0) goto fail; - assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ - - if (a == b) { - bh = ah; - bl = al; - Py_INCREF(bh); - Py_INCREF(bl); - } - else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; - - /* The plan: - * 1. Allocate result space (asize + bsize digits: that's always - * enough). - * 2. Compute ah*bh, and copy into result at 2*shift. - * 3. Compute al*bl, and copy into result at 0. Note that this - * can't overlap with #2. - * 4. Subtract al*bl from the result, starting at shift. This may - * underflow (borrow out of the high digit), but we don't care: - * we're effectively doing unsigned arithmetic mod - * BASE**(sizea + sizeb), and so long as the *final* result fits, - * borrows and carries out of the high digit can be ignored. - * 5. Subtract ah*bh from the result, starting at shift. - * 6. Compute (ah+al)*(bh+bl), and add it into the result starting - * at shift. - */ - - /* 1. Allocate result space. */ - ret = _PyLong_New(asize + bsize); - if (ret == NULL) goto fail; + Py_ssize_t asize = ABS(Py_SIZE(a)); + Py_ssize_t bsize = ABS(Py_SIZE(b)); + PyLongObject *ah = NULL; + PyLongObject *al = NULL; + PyLongObject *bh = NULL; + PyLongObject *bl = NULL; + PyLongObject *ret = NULL; + PyLongObject *t1, *t2, *t3; + Py_ssize_t shift; /* the number of digits we split off */ + Py_ssize_t i; + + /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl + * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl + * Then the original product is + * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl + * By picking X to be a power of 2, "*X" is just shifting, and it's + * been reduced to 3 multiplies on numbers half the size. + */ + + /* We want to split based on the larger number; fiddle so that b + * is largest. + */ + if (asize > bsize) { + t1 = a; + a = b; + b = t1; + + i = asize; + asize = bsize; + bsize = i; + } + + /* Use gradeschool math when either number is too small. */ + i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF; + if (asize <= i) { + if (asize == 0) + return (PyLongObject *)PyLong_FromLong(0); + else + return x_mul(a, b); + } + + /* If a is small compared to b, splitting on b gives a degenerate + * case with ah==0, and Karatsuba may be (even much) less efficient + * than "grade school" then. However, we can still win, by viewing + * b as a string of "big digits", each of width a->ob_size. That + * leads to a sequence of balanced calls to k_mul. + */ + if (2 * asize <= bsize) + return k_lopsided_mul(a, b); + + /* Split a & b into hi & lo pieces. */ + shift = bsize >> 1; + if (kmul_split(a, shift, &ah, &al) < 0) goto fail; + assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ + + if (a == b) { + bh = ah; + bl = al; + Py_INCREF(bh); + Py_INCREF(bl); + } + else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; + + /* The plan: + * 1. Allocate result space (asize + bsize digits: that's always + * enough). + * 2. Compute ah*bh, and copy into result at 2*shift. + * 3. Compute al*bl, and copy into result at 0. Note that this + * can't overlap with #2. + * 4. Subtract al*bl from the result, starting at shift. This may + * underflow (borrow out of the high digit), but we don't care: + * we're effectively doing unsigned arithmetic mod + * BASE**(sizea + sizeb), and so long as the *final* result fits, + * borrows and carries out of the high digit can be ignored. + * 5. Subtract ah*bh from the result, starting at shift. + * 6. Compute (ah+al)*(bh+bl), and add it into the result starting + * at shift. + */ + + /* 1. Allocate result space. */ + ret = _PyLong_New(asize + bsize); + if (ret == NULL) goto fail; #ifdef Py_DEBUG - /* Fill with trash, to catch reference to uninitialized digits. */ - memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); + /* Fill with trash, to catch reference to uninitialized digits. */ + memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); #endif - /* 2. t1 <- ah*bh, and copy into high digits of result. */ - if ((t1 = k_mul(ah, bh)) == NULL) goto fail; - assert(Py_SIZE(t1) >= 0); - assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); - memcpy(ret->ob_digit + 2*shift, t1->ob_digit, - Py_SIZE(t1) * sizeof(digit)); - - /* Zero-out the digits higher than the ah*bh copy. */ - i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); - if (i) - memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, - i * sizeof(digit)); - - /* 3. t2 <- al*bl, and copy into the low digits. */ - if ((t2 = k_mul(al, bl)) == NULL) { - Py_DECREF(t1); - goto fail; - } - assert(Py_SIZE(t2) >= 0); - assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ - memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); - - /* Zero out remaining digits. */ - i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ - if (i) - memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); - - /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first - * because it's fresher in cache. - */ - i = Py_SIZE(ret) - shift; /* # digits after shift */ - (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); - Py_DECREF(t2); - - (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); - Py_DECREF(t1); - - /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ - if ((t1 = x_add(ah, al)) == NULL) goto fail; - Py_DECREF(ah); - Py_DECREF(al); - ah = al = NULL; - - if (a == b) { - t2 = t1; - Py_INCREF(t2); - } - else if ((t2 = x_add(bh, bl)) == NULL) { - Py_DECREF(t1); - goto fail; - } - Py_DECREF(bh); - Py_DECREF(bl); - bh = bl = NULL; - - t3 = k_mul(t1, t2); - Py_DECREF(t1); - Py_DECREF(t2); - if (t3 == NULL) goto fail; - assert(Py_SIZE(t3) >= 0); - - /* Add t3. It's not obvious why we can't run out of room here. - * See the (*) comment after this function. - */ - (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); - Py_DECREF(t3); - - return long_normalize(ret); + /* 2. t1 <- ah*bh, and copy into high digits of result. */ + if ((t1 = k_mul(ah, bh)) == NULL) goto fail; + assert(Py_SIZE(t1) >= 0); + assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); + memcpy(ret->ob_digit + 2*shift, t1->ob_digit, + Py_SIZE(t1) * sizeof(digit)); + + /* Zero-out the digits higher than the ah*bh copy. */ + i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); + if (i) + memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, + i * sizeof(digit)); + + /* 3. t2 <- al*bl, and copy into the low digits. */ + if ((t2 = k_mul(al, bl)) == NULL) { + Py_DECREF(t1); + goto fail; + } + assert(Py_SIZE(t2) >= 0); + assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ + memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); + + /* Zero out remaining digits. */ + i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ + if (i) + memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); + + /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first + * because it's fresher in cache. + */ + i = Py_SIZE(ret) - shift; /* # digits after shift */ + (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); + Py_DECREF(t2); + + (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); + Py_DECREF(t1); + + /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ + if ((t1 = x_add(ah, al)) == NULL) goto fail; + Py_DECREF(ah); + Py_DECREF(al); + ah = al = NULL; + + if (a == b) { + t2 = t1; + Py_INCREF(t2); + } + else if ((t2 = x_add(bh, bl)) == NULL) { + Py_DECREF(t1); + goto fail; + } + Py_DECREF(bh); + Py_DECREF(bl); + bh = bl = NULL; + + t3 = k_mul(t1, t2); + Py_DECREF(t1); + Py_DECREF(t2); + if (t3 == NULL) goto fail; + assert(Py_SIZE(t3) >= 0); + + /* Add t3. It's not obvious why we can't run out of room here. + * See the (*) comment after this function. + */ + (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); + Py_DECREF(t3); + + return long_normalize(ret); fail: - Py_XDECREF(ret); - Py_XDECREF(ah); - Py_XDECREF(al); - Py_XDECREF(bh); - Py_XDECREF(bl); - return NULL; + Py_XDECREF(ret); + Py_XDECREF(ah); + Py_XDECREF(al); + Py_XDECREF(bh); + Py_XDECREF(bl); + return NULL; } /* (*) Why adding t3 can't "run out of room" above. @@ -3086,85 +3086,85 @@ ah*bh and al*bl too. static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); - Py_ssize_t nbdone; /* # of b digits already multiplied */ - PyLongObject *ret; - PyLongObject *bslice = NULL; - - assert(asize > KARATSUBA_CUTOFF); - assert(2 * asize <= bsize); - - /* Allocate result space, and zero it out. */ - ret = _PyLong_New(asize + bsize); - if (ret == NULL) - return NULL; - memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); - - /* Successive slices of b are copied into bslice. */ - bslice = _PyLong_New(asize); - if (bslice == NULL) - goto fail; - - nbdone = 0; - while (bsize > 0) { - PyLongObject *product; - const Py_ssize_t nbtouse = MIN(bsize, asize); - - /* Multiply the next slice of b by a. */ - memcpy(bslice->ob_digit, b->ob_digit + nbdone, - nbtouse * sizeof(digit)); - Py_SIZE(bslice) = nbtouse; - product = k_mul(a, bslice); - if (product == NULL) - goto fail; - - /* Add into result. */ - (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, - product->ob_digit, Py_SIZE(product)); - Py_DECREF(product); - - bsize -= nbtouse; - nbdone += nbtouse; - } - - Py_DECREF(bslice); - return long_normalize(ret); + const Py_ssize_t asize = ABS(Py_SIZE(a)); + Py_ssize_t bsize = ABS(Py_SIZE(b)); + Py_ssize_t nbdone; /* # of b digits already multiplied */ + PyLongObject *ret; + PyLongObject *bslice = NULL; + + assert(asize > KARATSUBA_CUTOFF); + assert(2 * asize <= bsize); + + /* Allocate result space, and zero it out. */ + ret = _PyLong_New(asize + bsize); + if (ret == NULL) + return NULL; + memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); + + /* Successive slices of b are copied into bslice. */ + bslice = _PyLong_New(asize); + if (bslice == NULL) + goto fail; + + nbdone = 0; + while (bsize > 0) { + PyLongObject *product; + const Py_ssize_t nbtouse = MIN(bsize, asize); + + /* Multiply the next slice of b by a. */ + memcpy(bslice->ob_digit, b->ob_digit + nbdone, + nbtouse * sizeof(digit)); + Py_SIZE(bslice) = nbtouse; + product = k_mul(a, bslice); + if (product == NULL) + goto fail; + + /* Add into result. */ + (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, + product->ob_digit, Py_SIZE(product)); + Py_DECREF(product); + + bsize -= nbtouse; + nbdone += nbtouse; + } + + Py_DECREF(bslice); + return long_normalize(ret); fail: - Py_DECREF(ret); - Py_XDECREF(bslice); - return NULL; + Py_DECREF(ret); + Py_XDECREF(bslice); + return NULL; } static PyObject * long_mul(PyLongObject *a, PyLongObject *b) { - PyLongObject *z; + PyLongObject *z; - CHECK_BINOP(a, b); + CHECK_BINOP(a, b); - /* fast path for single-digit multiplication */ - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { - stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); + /* fast path for single-digit multiplication */ + if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); #ifdef HAVE_LONG_LONG - return PyLong_FromLongLong((PY_LONG_LONG)v); + return PyLong_FromLongLong((PY_LONG_LONG)v); #else - /* if we don't have long long then we're almost certainly - using 15-bit digits, so v will fit in a long. In the - unlikely event that we're using 30-bit digits on a platform - without long long, a large v will just cause us to fall - through to the general multiplication code below. */ - if (v >= LONG_MIN && v <= LONG_MAX) - return PyLong_FromLong((long)v); + /* if we don't have long long then we're almost certainly + using 15-bit digits, so v will fit in a long. In the + unlikely event that we're using 30-bit digits on a platform + without long long, a large v will just cause us to fall + through to the general multiplication code below. */ + if (v >= LONG_MIN && v <= LONG_MAX) + return PyLong_FromLong((long)v); #endif - } + } - z = k_mul(a, b); - /* Negate if exactly one of the inputs is negative. */ - if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) - NEGATE(z); - return (PyObject *)z; + z = k_mul(a, b); + /* Negate if exactly one of the inputs is negative. */ + if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) + NEGATE(z); + return (PyObject *)z; } /* The / and % operators are now defined in terms of divmod(). @@ -3173,11 +3173,11 @@ long_mul(PyLongObject *a, PyLongObject *b) |a| by |b|, with the sign of a. This is also expressed as a - b*trunc(a/b), if trunc truncates towards zero. Some examples: - a b a rem b a mod b - 13 10 3 3 - -13 10 -3 7 - 13 -10 3 -7 - -13 -10 -3 -3 + a b a rem b a mod b + 13 10 3 3 + -13 10 -3 7 + 13 -10 3 -7 + -13 -10 -3 -3 So, to get from rem to mod, we have to add b if a and b have different signs. We then subtract one from the 'div' part of the outcome to keep the invariant intact. */ @@ -3190,57 +3190,57 @@ long_mul(PyLongObject *a, PyLongObject *b) */ static int l_divmod(PyLongObject *v, PyLongObject *w, - PyLongObject **pdiv, PyLongObject **pmod) + PyLongObject **pdiv, PyLongObject **pmod) { - PyLongObject *div, *mod; - - if (long_divrem(v, w, &div, &mod) < 0) - return -1; - if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || - (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { - PyLongObject *temp; - PyLongObject *one; - temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; - if (mod == NULL) { - Py_DECREF(div); - return -1; - } - one = (PyLongObject *) PyLong_FromLong(1L); - if (one == NULL || - (temp = (PyLongObject *) long_sub(div, one)) == NULL) { - Py_DECREF(mod); - Py_DECREF(div); - Py_XDECREF(one); - return -1; - } - Py_DECREF(one); - Py_DECREF(div); - div = temp; - } - if (pdiv != NULL) - *pdiv = div; - else - Py_DECREF(div); - - if (pmod != NULL) - *pmod = mod; - else - Py_DECREF(mod); - - return 0; + PyLongObject *div, *mod; + + if (long_divrem(v, w, &div, &mod) < 0) + return -1; + if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || + (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + PyLongObject *temp; + PyLongObject *one; + temp = (PyLongObject *) long_add(mod, w); + Py_DECREF(mod); + mod = temp; + if (mod == NULL) { + Py_DECREF(div); + return -1; + } + one = (PyLongObject *) PyLong_FromLong(1L); + if (one == NULL || + (temp = (PyLongObject *) long_sub(div, one)) == NULL) { + Py_DECREF(mod); + Py_DECREF(div); + Py_XDECREF(one); + return -1; + } + Py_DECREF(one); + Py_DECREF(div); + div = temp; + } + if (pdiv != NULL) + *pdiv = div; + else + Py_DECREF(div); + + if (pmod != NULL) + *pmod = mod; + else + Py_DECREF(mod); + + return 0; } static PyObject * long_div(PyObject *a, PyObject *b) { - PyLongObject *div; + PyLongObject *div; - CHECK_BINOP(a, b); - if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0) - div = NULL; - return (PyObject *)div; + CHECK_BINOP(a, b); + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, NULL) < 0) + div = NULL; + return (PyObject *)div; } /* PyLong/PyLong -> float, with correctly rounded result. */ @@ -3251,631 +3251,631 @@ long_div(PyObject *a, PyObject *b) static PyObject * long_true_divide(PyObject *v, PyObject *w) { - PyLongObject *a, *b, *x; - Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; - digit mask, low; - int inexact, negate, a_is_small, b_is_small; - double dx, result; - - CHECK_BINOP(v, w); - a = (PyLongObject *)v; - b = (PyLongObject *)w; - - /* - Method in a nutshell: - - 0. reduce to case a, b > 0; filter out obvious underflow/overflow - 1. choose a suitable integer 'shift' - 2. use integer arithmetic to compute x = floor(2**-shift*a/b) - 3. adjust x for correct rounding - 4. convert x to a double dx with the same value - 5. return ldexp(dx, shift). - - In more detail: - - 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b - returns either 0.0 or -0.0, depending on the sign of b. For a and - b both nonzero, ignore signs of a and b, and add the sign back in - at the end. Now write a_bits and b_bits for the bit lengths of a - and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise - for b). Then - - 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). - - So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and - so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - - DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of - the way, we can assume that - - DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. - - 1. The integer 'shift' is chosen so that x has the right number of - bits for a double, plus two or three extra bits that will be used - in the rounding decisions. Writing a_bits and b_bits for the - number of significant bits in a and b respectively, a - straightforward formula for shift is: - - shift = a_bits - b_bits - DBL_MANT_DIG - 2 - - This is fine in the usual case, but if a/b is smaller than the - smallest normal float then it can lead to double rounding on an - IEEE 754 platform, giving incorrectly rounded results. So we - adjust the formula slightly. The actual formula used is: - - shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 - - 2. The quantity x is computed by first shifting a (left -shift bits - if shift <= 0, right shift bits if shift > 0) and then dividing by - b. For both the shift and the division, we keep track of whether - the result is inexact, in a flag 'inexact'; this information is - needed at the rounding stage. - - With the choice of shift above, together with our assumption that - a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows - that x >= 1. - - 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace - this with an exactly representable float of the form - - round(x/2**extra_bits) * 2**(extra_bits+shift). - - For float representability, we need x/2**extra_bits < - 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - - DBL_MANT_DIG. This translates to the condition: - - extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG - - To round, we just modify the bottom digit of x in-place; this can - end up giving a digit with value > PyLONG_MASK, but that's not a - problem since digits can hold values up to 2*PyLONG_MASK+1. - - With the original choices for shift above, extra_bits will always - be 2 or 3. Then rounding under the round-half-to-even rule, we - round up iff the most significant of the extra bits is 1, and - either: (a) the computation of x in step 2 had an inexact result, - or (b) at least one other of the extra bits is 1, or (c) the least - significant bit of x (above those to be rounded) is 1. - - 4. Conversion to a double is straightforward; all floating-point - operations involved in the conversion are exact, so there's no - danger of rounding errors. - - 5. Use ldexp(x, shift) to compute x*2**shift, the final result. - The result will always be exactly representable as a double, except - in the case that it overflows. To avoid dependence on the exact - behaviour of ldexp on overflow, we check for overflow before - applying ldexp. The result of ldexp is adjusted for sign before - returning. - */ - - /* Reduce to case where a and b are both positive. */ - a_size = ABS(Py_SIZE(a)); - b_size = ABS(Py_SIZE(b)); - negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); - if (b_size == 0) { - PyErr_SetString(PyExc_ZeroDivisionError, - "division by zero"); - goto error; - } - if (a_size == 0) - goto underflow_or_zero; - - /* Fast path for a and b small (exactly representable in a double). - Relies on floating-point division being correctly rounded; results - may be subject to double rounding on x86 machines that operate with - the x87 FPU set to 64-bit precision. */ - a_is_small = a_size <= MANT_DIG_DIGITS || - (a_size == MANT_DIG_DIGITS+1 && - a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); - b_is_small = b_size <= MANT_DIG_DIGITS || - (b_size == MANT_DIG_DIGITS+1 && - b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); - if (a_is_small && b_is_small) { - double da, db; - da = a->ob_digit[--a_size]; - while (a_size > 0) - da = da * PyLong_BASE + a->ob_digit[--a_size]; - db = b->ob_digit[--b_size]; - while (b_size > 0) - db = db * PyLong_BASE + b->ob_digit[--b_size]; - result = da / db; - goto success; - } - - /* Catch obvious cases of underflow and overflow */ - diff = a_size - b_size; - if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) - /* Extreme overflow */ - goto overflow; - else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) - /* Extreme underflow */ - goto underflow_or_zero; - /* Next line is now safe from overflowing a Py_ssize_t */ - diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - - bits_in_digit(b->ob_digit[b_size - 1]); - /* Now diff = a_bits - b_bits. */ - if (diff > DBL_MAX_EXP) - goto overflow; - else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) - goto underflow_or_zero; - - /* Choose value for shift; see comments for step 1 above. */ - shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; - - inexact = 0; - - /* x = abs(a * 2**-shift) */ - if (shift <= 0) { - Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; - digit rem; - /* x = a << -shift */ - if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { - /* In practice, it's probably impossible to end up - here. Both a and b would have to be enormous, - using close to SIZE_T_MAX bytes of memory each. */ - PyErr_SetString(PyExc_OverflowError, - "intermediate overflow during division"); - goto error; - } - x = _PyLong_New(a_size + shift_digits + 1); - if (x == NULL) - goto error; - for (i = 0; i < shift_digits; i++) - x->ob_digit[i] = 0; - rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, - a_size, -shift % PyLong_SHIFT); - x->ob_digit[a_size + shift_digits] = rem; - } - else { - Py_ssize_t shift_digits = shift / PyLong_SHIFT; - digit rem; - /* x = a >> shift */ - assert(a_size >= shift_digits); - x = _PyLong_New(a_size - shift_digits); - if (x == NULL) - goto error; - rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, - a_size - shift_digits, shift % PyLong_SHIFT); - /* set inexact if any of the bits shifted out is nonzero */ - if (rem) - inexact = 1; - while (!inexact && shift_digits > 0) - if (a->ob_digit[--shift_digits]) - inexact = 1; - } - long_normalize(x); - x_size = Py_SIZE(x); - - /* x //= b. If the remainder is nonzero, set inexact. We own the only - reference to x, so it's safe to modify it in-place. */ - if (b_size == 1) { - digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, - b->ob_digit[0]); - long_normalize(x); - if (rem) - inexact = 1; - } - else { - PyLongObject *div, *rem; - div = x_divrem(x, b, &rem); - Py_DECREF(x); - x = div; - if (x == NULL) - goto error; - if (Py_SIZE(rem)) - inexact = 1; - Py_DECREF(rem); - } - x_size = ABS(Py_SIZE(x)); - assert(x_size > 0); /* result of division is never zero */ - x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); - - /* The number of extra bits that have to be rounded away. */ - extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; - assert(extra_bits == 2 || extra_bits == 3); - - /* Round by directly modifying the low digit of x. */ - mask = (digit)1 << (extra_bits - 1); - low = x->ob_digit[0] | inexact; - if (low & mask && low & (3*mask-1)) - low += mask; - x->ob_digit[0] = low & ~(mask-1U); - - /* Convert x to a double dx; the conversion is exact. */ - dx = x->ob_digit[--x_size]; - while (x_size > 0) - dx = dx * PyLong_BASE + x->ob_digit[--x_size]; - Py_DECREF(x); - - /* Check whether ldexp result will overflow a double. */ - if (shift + x_bits >= DBL_MAX_EXP && - (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits))) - goto overflow; - result = ldexp(dx, (int)shift); + PyLongObject *a, *b, *x; + Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; + digit mask, low; + int inexact, negate, a_is_small, b_is_small; + double dx, result; + + CHECK_BINOP(v, w); + a = (PyLongObject *)v; + b = (PyLongObject *)w; + + /* + Method in a nutshell: + + 0. reduce to case a, b > 0; filter out obvious underflow/overflow + 1. choose a suitable integer 'shift' + 2. use integer arithmetic to compute x = floor(2**-shift*a/b) + 3. adjust x for correct rounding + 4. convert x to a double dx with the same value + 5. return ldexp(dx, shift). + + In more detail: + + 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b + returns either 0.0 or -0.0, depending on the sign of b. For a and + b both nonzero, ignore signs of a and b, and add the sign back in + at the end. Now write a_bits and b_bits for the bit lengths of a + and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise + for b). Then + + 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1). + + So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and + so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP - + DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of + the way, we can assume that + + DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP. + + 1. The integer 'shift' is chosen so that x has the right number of + bits for a double, plus two or three extra bits that will be used + in the rounding decisions. Writing a_bits and b_bits for the + number of significant bits in a and b respectively, a + straightforward formula for shift is: + + shift = a_bits - b_bits - DBL_MANT_DIG - 2 + + This is fine in the usual case, but if a/b is smaller than the + smallest normal float then it can lead to double rounding on an + IEEE 754 platform, giving incorrectly rounded results. So we + adjust the formula slightly. The actual formula used is: + + shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2 + + 2. The quantity x is computed by first shifting a (left -shift bits + if shift <= 0, right shift bits if shift > 0) and then dividing by + b. For both the shift and the division, we keep track of whether + the result is inexact, in a flag 'inexact'; this information is + needed at the rounding stage. + + With the choice of shift above, together with our assumption that + a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows + that x >= 1. + + 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace + this with an exactly representable float of the form + + round(x/2**extra_bits) * 2**(extra_bits+shift). + + For float representability, we need x/2**extra_bits < + 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP - + DBL_MANT_DIG. This translates to the condition: + + extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG + + To round, we just modify the bottom digit of x in-place; this can + end up giving a digit with value > PyLONG_MASK, but that's not a + problem since digits can hold values up to 2*PyLONG_MASK+1. + + With the original choices for shift above, extra_bits will always + be 2 or 3. Then rounding under the round-half-to-even rule, we + round up iff the most significant of the extra bits is 1, and + either: (a) the computation of x in step 2 had an inexact result, + or (b) at least one other of the extra bits is 1, or (c) the least + significant bit of x (above those to be rounded) is 1. + + 4. Conversion to a double is straightforward; all floating-point + operations involved in the conversion are exact, so there's no + danger of rounding errors. + + 5. Use ldexp(x, shift) to compute x*2**shift, the final result. + The result will always be exactly representable as a double, except + in the case that it overflows. To avoid dependence on the exact + behaviour of ldexp on overflow, we check for overflow before + applying ldexp. The result of ldexp is adjusted for sign before + returning. + */ + + /* Reduce to case where a and b are both positive. */ + a_size = ABS(Py_SIZE(a)); + b_size = ABS(Py_SIZE(b)); + negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + if (b_size == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "division by zero"); + goto error; + } + if (a_size == 0) + goto underflow_or_zero; + + /* Fast path for a and b small (exactly representable in a double). + Relies on floating-point division being correctly rounded; results + may be subject to double rounding on x86 machines that operate with + the x87 FPU set to 64-bit precision. */ + a_is_small = a_size <= MANT_DIG_DIGITS || + (a_size == MANT_DIG_DIGITS+1 && + a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b_is_small = b_size <= MANT_DIG_DIGITS || + (b_size == MANT_DIG_DIGITS+1 && + b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + if (a_is_small && b_is_small) { + double da, db; + da = a->ob_digit[--a_size]; + while (a_size > 0) + da = da * PyLong_BASE + a->ob_digit[--a_size]; + db = b->ob_digit[--b_size]; + while (b_size > 0) + db = db * PyLong_BASE + b->ob_digit[--b_size]; + result = da / db; + goto success; + } + + /* Catch obvious cases of underflow and overflow */ + diff = a_size - b_size; + if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1) + /* Extreme overflow */ + goto overflow; + else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT) + /* Extreme underflow */ + goto underflow_or_zero; + /* Next line is now safe from overflowing a Py_ssize_t */ + diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) - + bits_in_digit(b->ob_digit[b_size - 1]); + /* Now diff = a_bits - b_bits. */ + if (diff > DBL_MAX_EXP) + goto overflow; + else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1) + goto underflow_or_zero; + + /* Choose value for shift; see comments for step 1 above. */ + shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; + + inexact = 0; + + /* x = abs(a * 2**-shift) */ + if (shift <= 0) { + Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT; + digit rem; + /* x = a << -shift */ + if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) { + /* In practice, it's probably impossible to end up + here. Both a and b would have to be enormous, + using close to SIZE_T_MAX bytes of memory each. */ + PyErr_SetString(PyExc_OverflowError, + "intermediate overflow during division"); + goto error; + } + x = _PyLong_New(a_size + shift_digits + 1); + if (x == NULL) + goto error; + for (i = 0; i < shift_digits; i++) + x->ob_digit[i] = 0; + rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + a_size, -shift % PyLong_SHIFT); + x->ob_digit[a_size + shift_digits] = rem; + } + else { + Py_ssize_t shift_digits = shift / PyLong_SHIFT; + digit rem; + /* x = a >> shift */ + assert(a_size >= shift_digits); + x = _PyLong_New(a_size - shift_digits); + if (x == NULL) + goto error; + rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + a_size - shift_digits, shift % PyLong_SHIFT); + /* set inexact if any of the bits shifted out is nonzero */ + if (rem) + inexact = 1; + while (!inexact && shift_digits > 0) + if (a->ob_digit[--shift_digits]) + inexact = 1; + } + long_normalize(x); + x_size = Py_SIZE(x); + + /* x //= b. If the remainder is nonzero, set inexact. We own the only + reference to x, so it's safe to modify it in-place. */ + if (b_size == 1) { + digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, + b->ob_digit[0]); + long_normalize(x); + if (rem) + inexact = 1; + } + else { + PyLongObject *div, *rem; + div = x_divrem(x, b, &rem); + Py_DECREF(x); + x = div; + if (x == NULL) + goto error; + if (Py_SIZE(rem)) + inexact = 1; + Py_DECREF(rem); + } + x_size = ABS(Py_SIZE(x)); + assert(x_size > 0); /* result of division is never zero */ + x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); + + /* The number of extra bits that have to be rounded away. */ + extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + assert(extra_bits == 2 || extra_bits == 3); + + /* Round by directly modifying the low digit of x. */ + mask = (digit)1 << (extra_bits - 1); + low = x->ob_digit[0] | inexact; + if (low & mask && low & (3*mask-1)) + low += mask; + x->ob_digit[0] = low & ~(mask-1U); + + /* Convert x to a double dx; the conversion is exact. */ + dx = x->ob_digit[--x_size]; + while (x_size > 0) + dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + Py_DECREF(x); + + /* Check whether ldexp result will overflow a double. */ + if (shift + x_bits >= DBL_MAX_EXP && + (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits))) + goto overflow; + result = ldexp(dx, (int)shift); success: - return PyFloat_FromDouble(negate ? -result : result); + return PyFloat_FromDouble(negate ? -result : result); underflow_or_zero: - return PyFloat_FromDouble(negate ? -0.0 : 0.0); + return PyFloat_FromDouble(negate ? -0.0 : 0.0); overflow: - PyErr_SetString(PyExc_OverflowError, - "integer division result too large for a float"); + PyErr_SetString(PyExc_OverflowError, + "integer division result too large for a float"); error: - return NULL; + return NULL; } static PyObject * long_mod(PyObject *a, PyObject *b) { - PyLongObject *mod; - - CHECK_BINOP(a, b); + PyLongObject *mod; + + CHECK_BINOP(a, b); - if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) - mod = NULL; - return (PyObject *)mod; + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) + mod = NULL; + return (PyObject *)mod; } static PyObject * long_divmod(PyObject *a, PyObject *b) { - PyLongObject *div, *mod; - PyObject *z; - - CHECK_BINOP(a, b); - - if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, &mod) < 0) { - return NULL; - } - z = PyTuple_New(2); - if (z != NULL) { - PyTuple_SetItem(z, 0, (PyObject *) div); - PyTuple_SetItem(z, 1, (PyObject *) mod); - } - else { - Py_DECREF(div); - Py_DECREF(mod); - } - return z; + PyLongObject *div, *mod; + PyObject *z; + + CHECK_BINOP(a, b); + + if (l_divmod((PyLongObject*)a, (PyLongObject*)b, &div, &mod) < 0) { + return NULL; + } + z = PyTuple_New(2); + if (z != NULL) { + PyTuple_SetItem(z, 0, (PyObject *) div); + PyTuple_SetItem(z, 1, (PyObject *) mod); + } + else { + Py_DECREF(div); + Py_DECREF(mod); + } + return z; } /* pow(v, w, x) */ static PyObject * long_pow(PyObject *v, PyObject *w, PyObject *x) { - PyLongObject *a, *b, *c; /* a,b,c = v,w,x */ - int negativeOutput = 0; /* if x<0 return negative output */ - - PyLongObject *z = NULL; /* accumulated result */ - Py_ssize_t i, j, k; /* counters */ - PyLongObject *temp = NULL; - - /* 5-ary values. If the exponent is large enough, table is - * precomputed so that table[i] == a**i % c for i in range(32). - */ - PyLongObject *table[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,0,0,0,0,0}; - - /* a, b, c = v, w, x */ - CHECK_BINOP(v, w); - a = (PyLongObject*)v; Py_INCREF(a); - b = (PyLongObject*)w; Py_INCREF(b); - if (PyLong_Check(x)) { - c = (PyLongObject *)x; - Py_INCREF(x); - } - else if (x == Py_None) - c = NULL; - else { - Py_DECREF(a); - Py_DECREF(b); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (Py_SIZE(b) < 0) { /* if exponent is negative */ - if (c) { - PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " - "cannot be negative when 3rd argument specified"); - goto Error; - } - else { - /* else return a float. This works because we know - that this calls float_pow() which converts its - arguments to double. */ - Py_DECREF(a); - Py_DECREF(b); - return PyFloat_Type.tp_as_number->nb_power(v, w, x); - } - } - - if (c) { - /* if modulus == 0: - raise ValueError() */ - if (Py_SIZE(c) == 0) { - PyErr_SetString(PyExc_ValueError, - "pow() 3rd argument cannot be 0"); - goto Error; - } - - /* if modulus < 0: - negativeOutput = True - modulus = -modulus */ - if (Py_SIZE(c) < 0) { - negativeOutput = 1; - temp = (PyLongObject *)_PyLong_Copy(c); - if (temp == NULL) - goto Error; - Py_DECREF(c); - c = temp; - temp = NULL; - NEGATE(c); - } - - /* if modulus == 1: - return 0 */ - if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { - z = (PyLongObject *)PyLong_FromLong(0L); - goto Done; - } - - /* if base < 0: - base = base % modulus - Having the base positive just makes things easier. */ - if (Py_SIZE(a) < 0) { - if (l_divmod(a, c, NULL, &temp) < 0) - goto Error; - Py_DECREF(a); - a = temp; - temp = NULL; - } - } - - /* At this point a, b, and c are guaranteed non-negative UNLESS - c is NULL, in which case a may be negative. */ - - z = (PyLongObject *)PyLong_FromLong(1L); - if (z == NULL) - goto Error; - - /* Perform a modular reduction, X = X % c, but leave X alone if c - * is NULL. - */ -#define REDUCE(X) \ - if (c != NULL) { \ - if (l_divmod(X, c, NULL, &temp) < 0) \ - goto Error; \ - Py_XDECREF(X); \ - X = temp; \ - temp = NULL; \ - } - - /* Multiply two values, then reduce the result: - result = X*Y % c. If c is NULL, skip the mod. */ -#define MULT(X, Y, result) \ -{ \ - temp = (PyLongObject *)long_mul(X, Y); \ - if (temp == NULL) \ - goto Error; \ - Py_XDECREF(result); \ - result = temp; \ - temp = NULL; \ - REDUCE(result) \ + PyLongObject *a, *b, *c; /* a,b,c = v,w,x */ + int negativeOutput = 0; /* if x<0 return negative output */ + + PyLongObject *z = NULL; /* accumulated result */ + Py_ssize_t i, j, k; /* counters */ + PyLongObject *temp = NULL; + + /* 5-ary values. If the exponent is large enough, table is + * precomputed so that table[i] == a**i % c for i in range(32). + */ + PyLongObject *table[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,0,0,0,0,0}; + + /* a, b, c = v, w, x */ + CHECK_BINOP(v, w); + a = (PyLongObject*)v; Py_INCREF(a); + b = (PyLongObject*)w; Py_INCREF(b); + if (PyLong_Check(x)) { + c = (PyLongObject *)x; + Py_INCREF(x); + } + else if (x == Py_None) + c = NULL; + else { + Py_DECREF(a); + Py_DECREF(b); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + if (Py_SIZE(b) < 0) { /* if exponent is negative */ + if (c) { + PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " + "cannot be negative when 3rd argument specified"); + goto Error; + } + else { + /* else return a float. This works because we know + that this calls float_pow() which converts its + arguments to double. */ + Py_DECREF(a); + Py_DECREF(b); + return PyFloat_Type.tp_as_number->nb_power(v, w, x); + } + } + + if (c) { + /* if modulus == 0: + raise ValueError() */ + if (Py_SIZE(c) == 0) { + PyErr_SetString(PyExc_ValueError, + "pow() 3rd argument cannot be 0"); + goto Error; + } + + /* if modulus < 0: + negativeOutput = True + modulus = -modulus */ + if (Py_SIZE(c) < 0) { + negativeOutput = 1; + temp = (PyLongObject *)_PyLong_Copy(c); + if (temp == NULL) + goto Error; + Py_DECREF(c); + c = temp; + temp = NULL; + NEGATE(c); + } + + /* if modulus == 1: + return 0 */ + if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { + z = (PyLongObject *)PyLong_FromLong(0L); + goto Done; + } + + /* if base < 0: + base = base % modulus + Having the base positive just makes things easier. */ + if (Py_SIZE(a) < 0) { + if (l_divmod(a, c, NULL, &temp) < 0) + goto Error; + Py_DECREF(a); + a = temp; + temp = NULL; + } + } + + /* At this point a, b, and c are guaranteed non-negative UNLESS + c is NULL, in which case a may be negative. */ + + z = (PyLongObject *)PyLong_FromLong(1L); + if (z == NULL) + goto Error; + + /* Perform a modular reduction, X = X % c, but leave X alone if c + * is NULL. + */ +#define REDUCE(X) \ + if (c != NULL) { \ + if (l_divmod(X, c, NULL, &temp) < 0) \ + goto Error; \ + Py_XDECREF(X); \ + X = temp; \ + temp = NULL; \ + } + + /* Multiply two values, then reduce the result: + result = X*Y % c. If c is NULL, skip the mod. */ +#define MULT(X, Y, result) \ +{ \ + temp = (PyLongObject *)long_mul(X, Y); \ + if (temp == NULL) \ + goto Error; \ + Py_XDECREF(result); \ + result = temp; \ + temp = NULL; \ + REDUCE(result) \ } - if (Py_SIZE(b) <= FIVEARY_CUTOFF) { - /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ - /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */ - for (i = Py_SIZE(b) - 1; i >= 0; --i) { - digit bi = b->ob_digit[i]; - - for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) { - MULT(z, z, z) - if (bi & j) - MULT(z, a, z) - } - } - } - else { - /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */ - Py_INCREF(z); /* still holds 1L */ - table[0] = z; - for (i = 1; i < 32; ++i) - MULT(table[i-1], a, table[i]) - - for (i = Py_SIZE(b) - 1; i >= 0; --i) { - const digit bi = b->ob_digit[i]; - - for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { - const int index = (bi >> j) & 0x1f; - for (k = 0; k < 5; ++k) - MULT(z, z, z) - if (index) - MULT(z, table[index], z) - } - } - } - - if (negativeOutput && (Py_SIZE(z) != 0)) { - temp = (PyLongObject *)long_sub(z, c); - if (temp == NULL) - goto Error; - Py_DECREF(z); - z = temp; - temp = NULL; - } - goto Done; + if (Py_SIZE(b) <= FIVEARY_CUTOFF) { + /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ + /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */ + for (i = Py_SIZE(b) - 1; i >= 0; --i) { + digit bi = b->ob_digit[i]; + + for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) { + MULT(z, z, z) + if (bi & j) + MULT(z, a, z) + } + } + } + else { + /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */ + Py_INCREF(z); /* still holds 1L */ + table[0] = z; + for (i = 1; i < 32; ++i) + MULT(table[i-1], a, table[i]) + + for (i = Py_SIZE(b) - 1; i >= 0; --i) { + const digit bi = b->ob_digit[i]; + + for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { + const int index = (bi >> j) & 0x1f; + for (k = 0; k < 5; ++k) + MULT(z, z, z) + if (index) + MULT(z, table[index], z) + } + } + } + + if (negativeOutput && (Py_SIZE(z) != 0)) { + temp = (PyLongObject *)long_sub(z, c); + if (temp == NULL) + goto Error; + Py_DECREF(z); + z = temp; + temp = NULL; + } + goto Done; Error: - if (z != NULL) { - Py_DECREF(z); - z = NULL; - } - /* fall through */ + if (z != NULL) { + Py_DECREF(z); + z = NULL; + } + /* fall through */ Done: - if (Py_SIZE(b) > FIVEARY_CUTOFF) { - for (i = 0; i < 32; ++i) - Py_XDECREF(table[i]); - } - Py_DECREF(a); - Py_DECREF(b); - Py_XDECREF(c); - Py_XDECREF(temp); - return (PyObject *)z; + if (Py_SIZE(b) > FIVEARY_CUTOFF) { + for (i = 0; i < 32; ++i) + Py_XDECREF(table[i]); + } + Py_DECREF(a); + Py_DECREF(b); + Py_XDECREF(c); + Py_XDECREF(temp); + return (PyObject *)z; } static PyObject * long_invert(PyLongObject *v) { - /* Implement ~x as -(x+1) */ - PyLongObject *x; - PyLongObject *w; - if (ABS(Py_SIZE(v)) <=1) - return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); - w = (PyLongObject *)PyLong_FromLong(1L); - if (w == NULL) - return NULL; - x = (PyLongObject *) long_add(v, w); - Py_DECREF(w); - if (x == NULL) - return NULL; - Py_SIZE(x) = -(Py_SIZE(x)); - return (PyObject *)maybe_small_long(x); + /* Implement ~x as -(x+1) */ + PyLongObject *x; + PyLongObject *w; + if (ABS(Py_SIZE(v)) <=1) + return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); + w = (PyLongObject *)PyLong_FromLong(1L); + if (w == NULL) + return NULL; + x = (PyLongObject *) long_add(v, w); + Py_DECREF(w); + if (x == NULL) + return NULL; + Py_SIZE(x) = -(Py_SIZE(x)); + return (PyObject *)maybe_small_long(x); } static PyObject * long_neg(PyLongObject *v) { - PyLongObject *z; - if (ABS(Py_SIZE(v)) <= 1) - return PyLong_FromLong(-MEDIUM_VALUE(v)); - z = (PyLongObject *)_PyLong_Copy(v); - if (z != NULL) - Py_SIZE(z) = -(Py_SIZE(v)); - return (PyObject *)z; + PyLongObject *z; + if (ABS(Py_SIZE(v)) <= 1) + return PyLong_FromLong(-MEDIUM_VALUE(v)); + z = (PyLongObject *)_PyLong_Copy(v); + if (z != NULL) + Py_SIZE(z) = -(Py_SIZE(v)); + return (PyObject *)z; } static PyObject * long_abs(PyLongObject *v) { - if (Py_SIZE(v) < 0) - return long_neg(v); - else - return long_long((PyObject *)v); + if (Py_SIZE(v) < 0) + return long_neg(v); + else + return long_long((PyObject *)v); } static int long_bool(PyLongObject *v) { - return Py_SIZE(v) != 0; + return Py_SIZE(v) != 0; } static PyObject * long_rshift(PyLongObject *a, PyLongObject *b) { - PyLongObject *z = NULL; - Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j; - digit lomask, himask; - - CHECK_BINOP(a, b); - - if (Py_SIZE(a) < 0) { - /* Right shifting negative numbers is harder */ - PyLongObject *a1, *a2; - a1 = (PyLongObject *) long_invert(a); - if (a1 == NULL) - goto rshift_error; - a2 = (PyLongObject *) long_rshift(a1, b); - Py_DECREF(a1); - if (a2 == NULL) - goto rshift_error; - z = (PyLongObject *) long_invert(a2); - Py_DECREF(a2); - } - else { - shiftby = PyLong_AsSsize_t((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) - goto rshift_error; - if (shiftby < 0) { - PyErr_SetString(PyExc_ValueError, - "negative shift count"); - goto rshift_error; - } - wordshift = shiftby / PyLong_SHIFT; - newsize = ABS(Py_SIZE(a)) - wordshift; - if (newsize <= 0) - return PyLong_FromLong(0); - loshift = shiftby % PyLong_SHIFT; - hishift = PyLong_SHIFT - loshift; - lomask = ((digit)1 << hishift) - 1; - himask = PyLong_MASK ^ lomask; - z = _PyLong_New(newsize); - if (z == NULL) - goto rshift_error; - if (Py_SIZE(a) < 0) - Py_SIZE(z) = -(Py_SIZE(z)); - for (i = 0, j = wordshift; i < newsize; i++, j++) { - z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; - if (i+1 < newsize) - z->ob_digit[i] |= - (a->ob_digit[j+1] << hishift) & himask; - } - z = long_normalize(z); - } + PyLongObject *z = NULL; + Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j; + digit lomask, himask; + + CHECK_BINOP(a, b); + + if (Py_SIZE(a) < 0) { + /* Right shifting negative numbers is harder */ + PyLongObject *a1, *a2; + a1 = (PyLongObject *) long_invert(a); + if (a1 == NULL) + goto rshift_error; + a2 = (PyLongObject *) long_rshift(a1, b); + Py_DECREF(a1); + if (a2 == NULL) + goto rshift_error; + z = (PyLongObject *) long_invert(a2); + Py_DECREF(a2); + } + else { + shiftby = PyLong_AsSsize_t((PyObject *)b); + if (shiftby == -1L && PyErr_Occurred()) + goto rshift_error; + if (shiftby < 0) { + PyErr_SetString(PyExc_ValueError, + "negative shift count"); + goto rshift_error; + } + wordshift = shiftby / PyLong_SHIFT; + newsize = ABS(Py_SIZE(a)) - wordshift; + if (newsize <= 0) + return PyLong_FromLong(0); + loshift = shiftby % PyLong_SHIFT; + hishift = PyLong_SHIFT - loshift; + lomask = ((digit)1 << hishift) - 1; + himask = PyLong_MASK ^ lomask; + z = _PyLong_New(newsize); + if (z == NULL) + goto rshift_error; + if (Py_SIZE(a) < 0) + Py_SIZE(z) = -(Py_SIZE(z)); + for (i = 0, j = wordshift; i < newsize; i++, j++) { + z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; + if (i+1 < newsize) + z->ob_digit[i] |= + (a->ob_digit[j+1] << hishift) & himask; + } + z = long_normalize(z); + } rshift_error: - return (PyObject *) maybe_small_long(z); + return (PyObject *) maybe_small_long(z); } static PyObject * long_lshift(PyObject *v, PyObject *w) { - /* This version due to Tim Peters */ - PyLongObject *a = (PyLongObject*)v; - PyLongObject *b = (PyLongObject*)w; - PyLongObject *z = NULL; - Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j; - twodigits accum; - - CHECK_BINOP(a, b); - - shiftby = PyLong_AsSsize_t((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) - goto lshift_error; - if (shiftby < 0) { - PyErr_SetString(PyExc_ValueError, "negative shift count"); - goto lshift_error; - } - /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ - wordshift = shiftby / PyLong_SHIFT; - remshift = shiftby - wordshift * PyLong_SHIFT; - - oldsize = ABS(Py_SIZE(a)); - newsize = oldsize + wordshift; - if (remshift) - ++newsize; - z = _PyLong_New(newsize); - if (z == NULL) - goto lshift_error; - if (Py_SIZE(a) < 0) - NEGATE(z); - for (i = 0; i < wordshift; i++) - z->ob_digit[i] = 0; - accum = 0; - for (i = wordshift, j = 0; j < oldsize; i++, j++) { - accum |= (twodigits)a->ob_digit[j] << remshift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); - accum >>= PyLong_SHIFT; - } - if (remshift) - z->ob_digit[newsize-1] = (digit)accum; - else - assert(!accum); - z = long_normalize(z); + /* This version due to Tim Peters */ + PyLongObject *a = (PyLongObject*)v; + PyLongObject *b = (PyLongObject*)w; + PyLongObject *z = NULL; + Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j; + twodigits accum; + + CHECK_BINOP(a, b); + + shiftby = PyLong_AsSsize_t((PyObject *)b); + if (shiftby == -1L && PyErr_Occurred()) + goto lshift_error; + if (shiftby < 0) { + PyErr_SetString(PyExc_ValueError, "negative shift count"); + goto lshift_error; + } + /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby - wordshift * PyLong_SHIFT; + + oldsize = ABS(Py_SIZE(a)); + newsize = oldsize + wordshift; + if (remshift) + ++newsize; + z = _PyLong_New(newsize); + if (z == NULL) + goto lshift_error; + if (Py_SIZE(a) < 0) + NEGATE(z); + for (i = 0; i < wordshift; i++) + z->ob_digit[i] = 0; + accum = 0; + for (i = wordshift, j = 0; j < oldsize; i++, j++) { + accum |= (twodigits)a->ob_digit[j] << remshift; + z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum >>= PyLong_SHIFT; + } + if (remshift) + z->ob_digit[newsize-1] = (digit)accum; + else + assert(!accum); + z = long_normalize(z); lshift_error: - return (PyObject *) maybe_small_long(z); + return (PyObject *) maybe_small_long(z); } /* Compute two's complement of digit vector a[0:m], writing result to @@ -3885,186 +3885,186 @@ lshift_error: static void v_complement(digit *z, digit *a, Py_ssize_t m) { - Py_ssize_t i; - digit carry = 1; - for (i = 0; i < m; ++i) { - carry += a[i] ^ PyLong_MASK; - z[i] = carry & PyLong_MASK; - carry >>= PyLong_SHIFT; - } - assert(carry == 0); + Py_ssize_t i; + digit carry = 1; + for (i = 0; i < m; ++i) { + carry += a[i] ^ PyLong_MASK; + z[i] = carry & PyLong_MASK; + carry >>= PyLong_SHIFT; + } + assert(carry == 0); } /* Bitwise and/xor/or operations */ static PyObject * long_bitwise(PyLongObject *a, - int op, /* '&', '|', '^' */ - PyLongObject *b) + int op, /* '&', '|', '^' */ + PyLongObject *b) { - int nega, negb, negz; - Py_ssize_t size_a, size_b, size_z, i; - PyLongObject *z; - - /* Bitwise operations for negative numbers operate as though - on a two's complement representation. So convert arguments - from sign-magnitude to two's complement, and convert the - result back to sign-magnitude at the end. */ - - /* If a is negative, replace it by its two's complement. */ - size_a = ABS(Py_SIZE(a)); - nega = Py_SIZE(a) < 0; - if (nega) { - z = _PyLong_New(size_a); - if (z == NULL) - return NULL; - v_complement(z->ob_digit, a->ob_digit, size_a); - a = z; - } - else - /* Keep reference count consistent. */ - Py_INCREF(a); - - /* Same for b. */ - size_b = ABS(Py_SIZE(b)); - negb = Py_SIZE(b) < 0; - if (negb) { - z = _PyLong_New(size_b); - if (z == NULL) { - Py_DECREF(a); - return NULL; - } - v_complement(z->ob_digit, b->ob_digit, size_b); - b = z; - } - else - Py_INCREF(b); - - /* Swap a and b if necessary to ensure size_a >= size_b. */ - if (size_a < size_b) { - z = a; a = b; b = z; - size_z = size_a; size_a = size_b; size_b = size_z; - negz = nega; nega = negb; negb = negz; - } - - /* JRH: The original logic here was to allocate the result value (z) - as the longer of the two operands. However, there are some cases - where the result is guaranteed to be shorter than that: AND of two - positives, OR of two negatives: use the shorter number. AND with - mixed signs: use the positive number. OR with mixed signs: use the - negative number. - */ - switch (op) { - case '^': - negz = nega ^ negb; - size_z = size_a; - break; - case '&': - negz = nega & negb; - size_z = negb ? size_a : size_b; - break; - case '|': - negz = nega | negb; - size_z = negb ? size_b : size_a; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - /* We allow an extra digit if z is negative, to make sure that - the final two's complement of z doesn't overflow. */ - z = _PyLong_New(size_z + negz); - if (z == NULL) { - Py_DECREF(a); - Py_DECREF(b); - return NULL; - } - - /* Compute digits for overlap of a and b. */ - switch(op) { - case '&': - for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; - break; - case '|': - for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; - break; - case '^': - for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - /* Copy any remaining digits of a, inverting if necessary. */ - if (op == '^' && negb) - for (; i < size_z; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; - else if (i < size_z) - memcpy(&z->ob_digit[i], &a->ob_digit[i], - (size_z-i)*sizeof(digit)); - - /* Complement result if negative. */ - if (negz) { - Py_SIZE(z) = -(Py_SIZE(z)); - z->ob_digit[size_z] = PyLong_MASK; - v_complement(z->ob_digit, z->ob_digit, size_z+1); - } - - Py_DECREF(a); - Py_DECREF(b); - return (PyObject *)maybe_small_long(long_normalize(z)); + int nega, negb, negz; + Py_ssize_t size_a, size_b, size_z, i; + PyLongObject *z; + + /* Bitwise operations for negative numbers operate as though + on a two's complement representation. So convert arguments + from sign-magnitude to two's complement, and convert the + result back to sign-magnitude at the end. */ + + /* If a is negative, replace it by its two's complement. */ + size_a = ABS(Py_SIZE(a)); + nega = Py_SIZE(a) < 0; + if (nega) { + z = _PyLong_New(size_a); + if (z == NULL) + return NULL; + v_complement(z->ob_digit, a->ob_digit, size_a); + a = z; + } + else + /* Keep reference count consistent. */ + Py_INCREF(a); + + /* Same for b. */ + size_b = ABS(Py_SIZE(b)); + negb = Py_SIZE(b) < 0; + if (negb) { + z = _PyLong_New(size_b); + if (z == NULL) { + Py_DECREF(a); + return NULL; + } + v_complement(z->ob_digit, b->ob_digit, size_b); + b = z; + } + else + Py_INCREF(b); + + /* Swap a and b if necessary to ensure size_a >= size_b. */ + if (size_a < size_b) { + z = a; a = b; b = z; + size_z = size_a; size_a = size_b; size_b = size_z; + negz = nega; nega = negb; negb = negz; + } + + /* JRH: The original logic here was to allocate the result value (z) + as the longer of the two operands. However, there are some cases + where the result is guaranteed to be shorter than that: AND of two + positives, OR of two negatives: use the shorter number. AND with + mixed signs: use the positive number. OR with mixed signs: use the + negative number. + */ + switch (op) { + case '^': + negz = nega ^ negb; + size_z = size_a; + break; + case '&': + negz = nega & negb; + size_z = negb ? size_a : size_b; + break; + case '|': + negz = nega | negb; + size_z = negb ? size_b : size_a; + break; + default: + PyErr_BadArgument(); + return NULL; + } + + /* We allow an extra digit if z is negative, to make sure that + the final two's complement of z doesn't overflow. */ + z = _PyLong_New(size_z + negz); + if (z == NULL) { + Py_DECREF(a); + Py_DECREF(b); + return NULL; + } + + /* Compute digits for overlap of a and b. */ + switch(op) { + case '&': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + break; + case '|': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + break; + case '^': + for (i = 0; i < size_b; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + break; + default: + PyErr_BadArgument(); + return NULL; + } + + /* Copy any remaining digits of a, inverting if necessary. */ + if (op == '^' && negb) + for (; i < size_z; ++i) + z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + else if (i < size_z) + memcpy(&z->ob_digit[i], &a->ob_digit[i], + (size_z-i)*sizeof(digit)); + + /* Complement result if negative. */ + if (negz) { + Py_SIZE(z) = -(Py_SIZE(z)); + z->ob_digit[size_z] = PyLong_MASK; + v_complement(z->ob_digit, z->ob_digit, size_z+1); + } + + Py_DECREF(a); + Py_DECREF(b); + return (PyObject *)maybe_small_long(long_normalize(z)); } static PyObject * long_and(PyObject *a, PyObject *b) { - PyObject *c; - CHECK_BINOP(a, b); - c = long_bitwise((PyLongObject*)a, '&', (PyLongObject*)b); - return c; + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '&', (PyLongObject*)b); + return c; } static PyObject * long_xor(PyObject *a, PyObject *b) { - PyObject *c; - CHECK_BINOP(a, b); - c = long_bitwise((PyLongObject*)a, '^', (PyLongObject*)b); - return c; + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '^', (PyLongObject*)b); + return c; } static PyObject * long_or(PyObject *a, PyObject *b) { - PyObject *c; - CHECK_BINOP(a, b); - c = long_bitwise((PyLongObject*)a, '|', (PyLongObject*)b); - return c; + PyObject *c; + CHECK_BINOP(a, b); + c = long_bitwise((PyLongObject*)a, '|', (PyLongObject*)b); + return c; } static PyObject * long_long(PyObject *v) { - if (PyLong_CheckExact(v)) - Py_INCREF(v); - else - v = _PyLong_Copy((PyLongObject *)v); - return v; + if (PyLong_CheckExact(v)) + Py_INCREF(v); + else + v = _PyLong_Copy((PyLongObject *)v); + return v; } static PyObject * long_float(PyObject *v) { - double result; - result = PyLong_AsDouble(v); - if (result == -1.0 && PyErr_Occurred()) - return NULL; - return PyFloat_FromDouble(result); + double result; + result = PyLong_AsDouble(v); + if (result == -1.0 && PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble(result); } static PyObject * @@ -4073,47 +4073,47 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *x = NULL; - int base = -909; /* unlikely! */ - static char *kwlist[] = {"x", "base", 0}; - - if (type != &PyLong_Type) - return long_subtype_new(type, args, kwds); /* Wimp out */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, - &x, &base)) - return NULL; - if (x == NULL) - return PyLong_FromLong(0L); - if (base == -909) - return PyNumber_Long(x); - else if (PyUnicode_Check(x)) - return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), - PyUnicode_GET_SIZE(x), - base); - else if (PyByteArray_Check(x) || PyBytes_Check(x)) { - /* Since PyLong_FromString doesn't have a length parameter, - * check here for possible NULs in the string. */ - char *string; - Py_ssize_t size = Py_SIZE(x); - if (PyByteArray_Check(x)) - string = PyByteArray_AS_STRING(x); - else - string = PyBytes_AS_STRING(x); - if (strlen(string) != (size_t)size) { - /* We only see this if there's a null byte in x, - x is a bytes or buffer, *and* a base is given. */ - PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", - base, x); - return NULL; - } - return PyLong_FromString(string, NULL, base); - } - else { - PyErr_SetString(PyExc_TypeError, - "int() can't convert non-string with explicit base"); - return NULL; - } + PyObject *x = NULL; + int base = -909; /* unlikely! */ + static char *kwlist[] = {"x", "base", 0}; + + if (type != &PyLong_Type) + return long_subtype_new(type, args, kwds); /* Wimp out */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, + &x, &base)) + return NULL; + if (x == NULL) + return PyLong_FromLong(0L); + if (base == -909) + return PyNumber_Long(x); + else if (PyUnicode_Check(x)) + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), + PyUnicode_GET_SIZE(x), + base); + else if (PyByteArray_Check(x) || PyBytes_Check(x)) { + /* Since PyLong_FromString doesn't have a length parameter, + * check here for possible NULs in the string. */ + char *string; + Py_ssize_t size = Py_SIZE(x); + if (PyByteArray_Check(x)) + string = PyByteArray_AS_STRING(x); + else + string = PyBytes_AS_STRING(x); + if (strlen(string) != (size_t)size) { + /* We only see this if there's a null byte in x, + x is a bytes or buffer, *and* a base is given. */ + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %R", + base, x); + return NULL; + } + return PyLong_FromString(string, NULL, base); + } + else { + 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 long: @@ -4124,256 +4124,256 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyLongObject *tmp, *newobj; - Py_ssize_t i, n; - - assert(PyType_IsSubtype(type, &PyLong_Type)); - tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); - if (tmp == NULL) - return NULL; - assert(PyLong_CheckExact(tmp)); - n = Py_SIZE(tmp); - if (n < 0) - n = -n; - newobj = (PyLongObject *)type->tp_alloc(type, n); - if (newobj == NULL) { - Py_DECREF(tmp); - return NULL; - } - assert(PyLong_Check(newobj)); - Py_SIZE(newobj) = Py_SIZE(tmp); - for (i = 0; i < n; i++) - newobj->ob_digit[i] = tmp->ob_digit[i]; - Py_DECREF(tmp); - return (PyObject *)newobj; + PyLongObject *tmp, *newobj; + Py_ssize_t i, n; + + assert(PyType_IsSubtype(type, &PyLong_Type)); + tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); + if (tmp == NULL) + return NULL; + assert(PyLong_CheckExact(tmp)); + n = Py_SIZE(tmp); + if (n < 0) + n = -n; + newobj = (PyLongObject *)type->tp_alloc(type, n); + if (newobj == NULL) { + Py_DECREF(tmp); + return NULL; + } + assert(PyLong_Check(newobj)); + Py_SIZE(newobj) = Py_SIZE(tmp); + for (i = 0; i < n; i++) + newobj->ob_digit[i] = tmp->ob_digit[i]; + Py_DECREF(tmp); + return (PyObject *)newobj; } static PyObject * long_getnewargs(PyLongObject *v) { - return Py_BuildValue("(N)", _PyLong_Copy(v)); + return Py_BuildValue("(N)", _PyLong_Copy(v)); } static PyObject * long_get0(PyLongObject *v, void *context) { - return PyLong_FromLong(0L); + return PyLong_FromLong(0L); } static PyObject * long_get1(PyLongObject *v, void *context) { - return PyLong_FromLong(1L); + return PyLong_FromLong(1L); } static PyObject * long__format__(PyObject *self, PyObject *args) { - PyObject *format_spec; + PyObject *format_spec; - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - return _PyLong_FormatAdvanced(self, - PyUnicode_AS_UNICODE(format_spec), - PyUnicode_GET_SIZE(format_spec)); + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + return _PyLong_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); } static PyObject * long_round(PyObject *self, PyObject *args) { - PyObject *o_ndigits=NULL, *temp; - PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one; - int errcode; - digit q_mod_4; - - /* Notes on the algorithm: to round to the nearest 10**n (n positive), - the straightforward method is: - - (1) divide by 10**n - (2) round to nearest integer (round to even in case of tie) - (3) multiply result by 10**n. - - But the rounding step involves examining the fractional part of the - quotient to see whether it's greater than 0.5 or not. Since we - want to do the whole calculation in integer arithmetic, it's - simpler to do: - - (1) divide by (10**n)/2 - (2) round to nearest multiple of 2 (multiple of 4 in case of tie) - (3) multiply result by (10**n)/2. - - Then all we need to know about the fractional part of the quotient - arising in step (2) is whether it's zero or not. - - Doing both a multiplication and division is wasteful, and is easily - avoided if we just figure out how much to adjust the original input - by to do the rounding. - - Here's the whole algorithm expressed in Python. - - def round(self, ndigits = None): - """round(int, int) -> int""" - if ndigits is None or ndigits >= 0: - return self - pow = 10**-ndigits >> 1 - q, r = divmod(self, pow) - self -= r - if (q & 1 != 0): - if (q & 2 == r == 0): - self -= pow - else: - self += pow - return self - - */ - if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) - return NULL; - if (o_ndigits == NULL) - return long_long(self); - - ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); - if (ndigits == NULL) - return NULL; - - if (Py_SIZE(ndigits) >= 0) { - Py_DECREF(ndigits); - return long_long(self); - } - - Py_INCREF(self); /* to keep refcounting simple */ - /* we now own references to self, ndigits */ - - /* pow = 10 ** -ndigits >> 1 */ - pow = (PyLongObject *)PyLong_FromLong(10L); - if (pow == NULL) - goto error; - temp = long_neg(ndigits); - Py_DECREF(ndigits); - ndigits = (PyLongObject *)temp; - if (ndigits == NULL) - goto error; - temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - assert(PyLong_Check(pow)); /* check long_pow returned a long */ - one = (PyLongObject *)PyLong_FromLong(1L); - if (one == NULL) - goto error; - temp = long_rshift(pow, one); - Py_DECREF(one); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - - /* q, r = divmod(self, pow) */ - errcode = l_divmod((PyLongObject *)self, pow, &q, &r); - if (errcode == -1) - goto error; - - /* self -= r */ - temp = long_sub((PyLongObject *)self, r); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; - - /* get value of quotient modulo 4 */ - if (Py_SIZE(q) == 0) - q_mod_4 = 0; - else if (Py_SIZE(q) > 0) - q_mod_4 = q->ob_digit[0] & 3; - else - q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3; - - if ((q_mod_4 & 1) == 1) { - /* q is odd; round self up or down by adding or subtracting pow */ - if (q_mod_4 == 1 && Py_SIZE(r) == 0) - temp = (PyObject *)long_sub((PyLongObject *)self, pow); - else - temp = (PyObject *)long_add((PyLongObject *)self, pow); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; - } - Py_DECREF(q); - Py_DECREF(r); - Py_DECREF(pow); - Py_DECREF(ndigits); - return self; + PyObject *o_ndigits=NULL, *temp; + PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one; + int errcode; + digit q_mod_4; + + /* Notes on the algorithm: to round to the nearest 10**n (n positive), + the straightforward method is: + + (1) divide by 10**n + (2) round to nearest integer (round to even in case of tie) + (3) multiply result by 10**n. + + But the rounding step involves examining the fractional part of the + quotient to see whether it's greater than 0.5 or not. Since we + want to do the whole calculation in integer arithmetic, it's + simpler to do: + + (1) divide by (10**n)/2 + (2) round to nearest multiple of 2 (multiple of 4 in case of tie) + (3) multiply result by (10**n)/2. + + Then all we need to know about the fractional part of the quotient + arising in step (2) is whether it's zero or not. + + Doing both a multiplication and division is wasteful, and is easily + avoided if we just figure out how much to adjust the original input + by to do the rounding. + + Here's the whole algorithm expressed in Python. + + def round(self, ndigits = None): + """round(int, int) -> int""" + if ndigits is None or ndigits >= 0: + return self + pow = 10**-ndigits >> 1 + q, r = divmod(self, pow) + self -= r + if (q & 1 != 0): + if (q & 2 == r == 0): + self -= pow + else: + self += pow + return self + + */ + if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) + return NULL; + if (o_ndigits == NULL) + return long_long(self); + + ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); + if (ndigits == NULL) + return NULL; + + if (Py_SIZE(ndigits) >= 0) { + Py_DECREF(ndigits); + return long_long(self); + } + + Py_INCREF(self); /* to keep refcounting simple */ + /* we now own references to self, ndigits */ + + /* pow = 10 ** -ndigits >> 1 */ + pow = (PyLongObject *)PyLong_FromLong(10L); + if (pow == NULL) + goto error; + temp = long_neg(ndigits); + Py_DECREF(ndigits); + ndigits = (PyLongObject *)temp; + if (ndigits == NULL) + goto error; + temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None); + Py_DECREF(pow); + pow = (PyLongObject *)temp; + if (pow == NULL) + goto error; + assert(PyLong_Check(pow)); /* check long_pow returned a long */ + one = (PyLongObject *)PyLong_FromLong(1L); + if (one == NULL) + goto error; + temp = long_rshift(pow, one); + Py_DECREF(one); + Py_DECREF(pow); + pow = (PyLongObject *)temp; + if (pow == NULL) + goto error; + + /* q, r = divmod(self, pow) */ + errcode = l_divmod((PyLongObject *)self, pow, &q, &r); + if (errcode == -1) + goto error; + + /* self -= r */ + temp = long_sub((PyLongObject *)self, r); + Py_DECREF(self); + self = temp; + if (self == NULL) + goto error; + + /* get value of quotient modulo 4 */ + if (Py_SIZE(q) == 0) + q_mod_4 = 0; + else if (Py_SIZE(q) > 0) + q_mod_4 = q->ob_digit[0] & 3; + else + q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3; + + if ((q_mod_4 & 1) == 1) { + /* q is odd; round self up or down by adding or subtracting pow */ + if (q_mod_4 == 1 && Py_SIZE(r) == 0) + temp = (PyObject *)long_sub((PyLongObject *)self, pow); + else + temp = (PyObject *)long_add((PyLongObject *)self, pow); + Py_DECREF(self); + self = temp; + if (self == NULL) + goto error; + } + Py_DECREF(q); + Py_DECREF(r); + Py_DECREF(pow); + Py_DECREF(ndigits); + return self; error: - Py_XDECREF(q); - Py_XDECREF(r); - Py_XDECREF(pow); - Py_XDECREF(self); - Py_XDECREF(ndigits); - return NULL; + Py_XDECREF(q); + Py_XDECREF(r); + Py_XDECREF(pow); + Py_XDECREF(self); + Py_XDECREF(ndigits); + return NULL; } static PyObject * long_sizeof(PyLongObject *v) { - Py_ssize_t res; + Py_ssize_t res; - res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit); - return PyLong_FromSsize_t(res); + res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit); + return PyLong_FromSsize_t(res); } static PyObject * long_bit_length(PyLongObject *v) { - PyLongObject *result, *x, *y; - Py_ssize_t ndigits, msd_bits = 0; - digit msd; - - assert(v != NULL); - assert(PyLong_Check(v)); - - ndigits = ABS(Py_SIZE(v)); - if (ndigits == 0) - return PyLong_FromLong(0); - - msd = v->ob_digit[ndigits-1]; - while (msd >= 32) { - msd_bits += 6; - msd >>= 6; - } - msd_bits += (long)(BitLengthTable[msd]); - - if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) - return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); - - /* expression above may overflow; use Python integers instead */ - result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1); - if (result == NULL) - return NULL; - x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT); - if (x == NULL) - goto error; - y = (PyLongObject *)long_mul(result, x); - Py_DECREF(x); - if (y == NULL) - goto error; - Py_DECREF(result); - result = y; - - x = (PyLongObject *)PyLong_FromLong((long)msd_bits); - if (x == NULL) - goto error; - y = (PyLongObject *)long_add(result, x); - Py_DECREF(x); - if (y == NULL) - goto error; - Py_DECREF(result); - result = y; - - return (PyObject *)result; + PyLongObject *result, *x, *y; + Py_ssize_t ndigits, msd_bits = 0; + digit msd; + + assert(v != NULL); + assert(PyLong_Check(v)); + + ndigits = ABS(Py_SIZE(v)); + if (ndigits == 0) + return PyLong_FromLong(0); + + msd = v->ob_digit[ndigits-1]; + while (msd >= 32) { + msd_bits += 6; + msd >>= 6; + } + msd_bits += (long)(BitLengthTable[msd]); + + if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) + return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); + + /* expression above may overflow; use Python integers instead */ + result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1); + if (result == NULL) + return NULL; + x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT); + if (x == NULL) + goto error; + y = (PyLongObject *)long_mul(result, x); + Py_DECREF(x); + if (y == NULL) + goto error; + Py_DECREF(result); + result = y; + + x = (PyLongObject *)PyLong_FromLong((long)msd_bits); + if (x == NULL) + goto error; + y = (PyLongObject *)long_add(result, x); + Py_DECREF(x); + if (y == NULL) + goto error; + Py_DECREF(result); + result = y; + + return (PyObject *)result; error: - Py_DECREF(result); - return NULL; + Py_DECREF(result); + return NULL; } PyDoc_STRVAR(long_bit_length_doc, @@ -4389,7 +4389,7 @@ Number of bits necessary to represent self in binary.\n\ static PyObject * long_is_finite(PyObject *v) { - Py_RETURN_TRUE; + Py_RETURN_TRUE; } #endif @@ -4397,64 +4397,64 @@ long_is_finite(PyObject *v) static PyObject * long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) { - PyObject *byteorder_str; - PyObject *is_signed_obj = NULL; - Py_ssize_t length; - int little_endian; - int is_signed; - PyObject *bytes; - static char *kwlist[] = {"length", "byteorder", "signed", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist, - &length, &byteorder_str, - &is_signed_obj)) - return NULL; - - if (args != NULL && Py_SIZE(args) > 2) { - PyErr_SetString(PyExc_TypeError, - "'signed' is a keyword-only argument"); - return NULL; - } - - if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) - little_endian = 1; - else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) - little_endian = 0; - else { - PyErr_SetString(PyExc_ValueError, - "byteorder must be either 'little' or 'big'"); - return NULL; - } - - if (is_signed_obj != NULL) { - int cmp = PyObject_IsTrue(is_signed_obj); - if (cmp < 0) - return NULL; - is_signed = cmp ? 1 : 0; - } - else { - /* If the signed argument was omitted, use False as the - default. */ - is_signed = 0; - } - - if (length < 0) { - PyErr_SetString(PyExc_ValueError, - "length argument must be non-negative"); - return NULL; - } - - bytes = PyBytes_FromStringAndSize(NULL, length); - if (bytes == NULL) - return NULL; - - if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes), - length, little_endian, is_signed) < 0) { - Py_DECREF(bytes); - return NULL; - } - - return bytes; + PyObject *byteorder_str; + PyObject *is_signed_obj = NULL; + Py_ssize_t length; + int little_endian; + int is_signed; + PyObject *bytes; + static char *kwlist[] = {"length", "byteorder", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist, + &length, &byteorder_str, + &is_signed_obj)) + return NULL; + + if (args != NULL && Py_SIZE(args) > 2) { + PyErr_SetString(PyExc_TypeError, + "'signed' is a keyword-only argument"); + return NULL; + } + + if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) + little_endian = 1; + else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + if (is_signed_obj != NULL) { + int cmp = PyObject_IsTrue(is_signed_obj); + if (cmp < 0) + return NULL; + is_signed = cmp ? 1 : 0; + } + else { + /* If the signed argument was omitted, use False as the + default. */ + is_signed = 0; + } + + if (length < 0) { + PyErr_SetString(PyExc_ValueError, + "length argument must be non-negative"); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, length); + if (bytes == NULL) + return NULL; + + if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes), + length, little_endian, is_signed) < 0) { + Py_DECREF(bytes); + return NULL; + } + + return bytes; } PyDoc_STRVAR(long_to_bytes_doc, @@ -4462,7 +4462,7 @@ PyDoc_STRVAR(long_to_bytes_doc, \n\ Return an array of bytes representing an integer.\n\ \n\ -The integer is represented using length bytes. An OverflowError is\n\ +The integer is represented using length bytes. An OverflowError is\n\ raised if the integer is not representable with the given number of\n\ bytes.\n\ \n\ @@ -4473,87 +4473,87 @@ significant byte is at the end of the byte array. To request the native\n\ byte order of the host system, use `sys.byteorder' as the byte order value.\n\ \n\ The signed keyword-only argument determines whether two's complement is\n\ -used to represent the integer. If signed is False and a negative integer\n\ +used to represent the integer. If signed is False and a negative integer\n\ is given, an OverflowError is raised."); static PyObject * long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *byteorder_str; - PyObject *is_signed_obj = NULL; - int little_endian; - int is_signed; - PyObject *obj; - PyObject *bytes; - PyObject *long_obj; - static char *kwlist[] = {"bytes", "byteorder", "signed", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist, - &obj, &byteorder_str, - &is_signed_obj)) - return NULL; - - if (args != NULL && Py_SIZE(args) > 2) { - PyErr_SetString(PyExc_TypeError, - "'signed' is a keyword-only argument"); - return NULL; - } - - if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) - little_endian = 1; - else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) - little_endian = 0; - else { - PyErr_SetString(PyExc_ValueError, - "byteorder must be either 'little' or 'big'"); - return NULL; - } - - if (is_signed_obj != NULL) { - int cmp = PyObject_IsTrue(is_signed_obj); - if (cmp < 0) - return NULL; - is_signed = cmp ? 1 : 0; - } - else { - /* If the signed argument was omitted, use False as the - default. */ - is_signed = 0; - } - - bytes = PyObject_Bytes(obj); - if (bytes == NULL) - return NULL; - - long_obj = _PyLong_FromByteArray( - (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), - little_endian, is_signed); - Py_DECREF(bytes); - - /* If from_bytes() was used on subclass, allocate new subclass - * instance, initialize it with decoded long value and return it. - */ - if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { - PyLongObject *newobj; - int i; - Py_ssize_t n = ABS(Py_SIZE(long_obj)); - - newobj = (PyLongObject *)type->tp_alloc(type, n); - if (newobj == NULL) { - Py_DECREF(long_obj); - return NULL; - } - assert(PyLong_Check(newobj)); - Py_SIZE(newobj) = Py_SIZE(long_obj); - for (i = 0; i < n; i++) { - newobj->ob_digit[i] = - ((PyLongObject *)long_obj)->ob_digit[i]; - } - Py_DECREF(long_obj); - return (PyObject *)newobj; - } - - return long_obj; + PyObject *byteorder_str; + PyObject *is_signed_obj = NULL; + int little_endian; + int is_signed; + PyObject *obj; + PyObject *bytes; + PyObject *long_obj; + static char *kwlist[] = {"bytes", "byteorder", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist, + &obj, &byteorder_str, + &is_signed_obj)) + return NULL; + + if (args != NULL && Py_SIZE(args) > 2) { + PyErr_SetString(PyExc_TypeError, + "'signed' is a keyword-only argument"); + return NULL; + } + + if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little")) + little_endian = 1; + else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big")) + little_endian = 0; + else { + PyErr_SetString(PyExc_ValueError, + "byteorder must be either 'little' or 'big'"); + return NULL; + } + + if (is_signed_obj != NULL) { + int cmp = PyObject_IsTrue(is_signed_obj); + if (cmp < 0) + return NULL; + is_signed = cmp ? 1 : 0; + } + else { + /* If the signed argument was omitted, use False as the + default. */ + is_signed = 0; + } + + bytes = PyObject_Bytes(obj); + if (bytes == NULL) + return NULL; + + long_obj = _PyLong_FromByteArray( + (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), + little_endian, is_signed); + Py_DECREF(bytes); + + /* If from_bytes() was used on subclass, allocate new subclass + * instance, initialize it with decoded long value and return it. + */ + if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { + PyLongObject *newobj; + int i; + Py_ssize_t n = ABS(Py_SIZE(long_obj)); + + newobj = (PyLongObject *)type->tp_alloc(type, n); + if (newobj == NULL) { + Py_DECREF(long_obj); + return NULL; + } + assert(PyLong_Check(newobj)); + Py_SIZE(newobj) = Py_SIZE(long_obj); + for (i = 0; i < n; i++) { + newobj->ob_digit[i] = + ((PyLongObject *)long_obj)->ob_digit[i]; + } + Py_DECREF(long_obj); + return (PyObject *)newobj; + } + + return long_obj; } PyDoc_STRVAR(long_from_bytes_doc, @@ -4575,32 +4575,32 @@ The signed keyword-only argument indicates whether two's complement is\n\ used to represent the integer."); static PyMethodDef long_methods[] = { - {"conjugate", (PyCFunction)long_long, METH_NOARGS, - "Returns self, the complex conjugate of any int."}, - {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS, - long_bit_length_doc}, + {"conjugate", (PyCFunction)long_long, METH_NOARGS, + "Returns self, the complex conjugate of any int."}, + {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS, + long_bit_length_doc}, #if 0 - {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, - "Returns always True."}, + {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, + "Returns always True."}, #endif - {"to_bytes", (PyCFunction)long_to_bytes, - METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc}, - {"from_bytes", (PyCFunction)long_from_bytes, - METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc}, - {"__trunc__", (PyCFunction)long_long, METH_NOARGS, - "Truncating an Integral returns itself."}, - {"__floor__", (PyCFunction)long_long, METH_NOARGS, - "Flooring an Integral returns itself."}, - {"__ceil__", (PyCFunction)long_long, METH_NOARGS, - "Ceiling of an Integral returns itself."}, - {"__round__", (PyCFunction)long_round, METH_VARARGS, - "Rounding an Integral returns itself.\n" - "Rounding with an ndigits argument also returns an integer."}, - {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS}, - {"__format__", (PyCFunction)long__format__, METH_VARARGS}, - {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS, - "Returns size in memory, in bytes"}, - {NULL, NULL} /* sentinel */ + {"to_bytes", (PyCFunction)long_to_bytes, + METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc}, + {"from_bytes", (PyCFunction)long_from_bytes, + METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc}, + {"__trunc__", (PyCFunction)long_long, METH_NOARGS, + "Truncating an Integral returns itself."}, + {"__floor__", (PyCFunction)long_long, METH_NOARGS, + "Flooring an Integral returns itself."}, + {"__ceil__", (PyCFunction)long_long, METH_NOARGS, + "Ceiling of an Integral returns itself."}, + {"__round__", (PyCFunction)long_round, METH_VARARGS, + "Rounding an Integral returns itself.\n" + "Rounding with an ndigits argument also returns an integer."}, + {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS}, + {"__format__", (PyCFunction)long__format__, METH_VARARGS}, + {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS, + "Returns size in memory, in bytes"}, + {NULL, NULL} /* sentinel */ }; static PyGetSetDef long_getset[] = { @@ -4633,83 +4633,83 @@ string, use the optional base. It is an error to supply a base when\n\ converting a non-string."); static PyNumberMethods long_as_number = { - (binaryfunc) long_add, /*nb_add*/ - (binaryfunc) long_sub, /*nb_subtract*/ - (binaryfunc) long_mul, /*nb_multiply*/ - long_mod, /*nb_remainder*/ - long_divmod, /*nb_divmod*/ - long_pow, /*nb_power*/ - (unaryfunc) long_neg, /*nb_negative*/ - (unaryfunc) long_long, /*tp_positive*/ - (unaryfunc) long_abs, /*tp_absolute*/ - (inquiry) long_bool, /*tp_bool*/ - (unaryfunc) long_invert, /*nb_invert*/ - long_lshift, /*nb_lshift*/ - (binaryfunc) long_rshift, /*nb_rshift*/ - long_and, /*nb_and*/ - long_xor, /*nb_xor*/ - long_or, /*nb_or*/ - long_long, /*nb_int*/ - 0, /*nb_reserved*/ - long_float, /*nb_float*/ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 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 */ - long_div, /* nb_floor_divide */ - long_true_divide, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - long_long, /* nb_index */ + (binaryfunc) long_add, /*nb_add*/ + (binaryfunc) long_sub, /*nb_subtract*/ + (binaryfunc) long_mul, /*nb_multiply*/ + long_mod, /*nb_remainder*/ + long_divmod, /*nb_divmod*/ + long_pow, /*nb_power*/ + (unaryfunc) long_neg, /*nb_negative*/ + (unaryfunc) long_long, /*tp_positive*/ + (unaryfunc) long_abs, /*tp_absolute*/ + (inquiry) long_bool, /*tp_bool*/ + (unaryfunc) long_invert, /*nb_invert*/ + long_lshift, /*nb_lshift*/ + (binaryfunc) long_rshift, /*nb_rshift*/ + long_and, /*nb_and*/ + long_xor, /*nb_xor*/ + long_or, /*nb_or*/ + long_long, /*nb_int*/ + 0, /*nb_reserved*/ + long_float, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 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 */ + long_div, /* nb_floor_divide */ + long_true_divide, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + long_long, /* nb_index */ }; PyTypeObject PyLong_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "int", /* tp_name */ - offsetof(PyLongObject, ob_digit), /* tp_basicsize */ - sizeof(digit), /* tp_itemsize */ - long_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - long_to_decimal_string, /* tp_repr */ - &long_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)long_hash, /* tp_hash */ - 0, /* tp_call */ - long_to_decimal_string, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ - long_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - long_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - long_methods, /* tp_methods */ - 0, /* tp_members */ - long_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 */ - long_new, /* tp_new */ - PyObject_Del, /* tp_free */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "int", /* tp_name */ + offsetof(PyLongObject, ob_digit), /* tp_basicsize */ + sizeof(digit), /* tp_itemsize */ + long_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + long_to_decimal_string, /* tp_repr */ + &long_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)long_hash, /* tp_hash */ + 0, /* tp_call */ + long_to_decimal_string, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ + long_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + long_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + long_methods, /* tp_methods */ + 0, /* tp_members */ + long_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 */ + long_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; static PyTypeObject Int_InfoType; @@ -4721,89 +4721,89 @@ A struct sequence that holds information about Python's\n\ internal representation of integers. The attributes are read only."); static PyStructSequence_Field int_info_fields[] = { - {"bits_per_digit", "size of a digit in bits"}, - {"sizeof_digit", "size in bytes of the C type used to " - "represent a digit"}, - {NULL, NULL} + {"bits_per_digit", "size of a digit in bits"}, + {"sizeof_digit", "size in bytes of the C type used to " + "represent a digit"}, + {NULL, NULL} }; static PyStructSequence_Desc int_info_desc = { - "sys.int_info", /* name */ - int_info__doc__, /* doc */ - int_info_fields, /* fields */ - 2 /* number of fields */ + "sys.int_info", /* name */ + int_info__doc__, /* doc */ + int_info_fields, /* fields */ + 2 /* number of fields */ }; PyObject * PyLong_GetInfo(void) { - PyObject* int_info; - int field = 0; - int_info = PyStructSequence_New(&Int_InfoType); - if (int_info == NULL) - return NULL; - PyStructSequence_SET_ITEM(int_info, field++, - PyLong_FromLong(PyLong_SHIFT)); - PyStructSequence_SET_ITEM(int_info, field++, - PyLong_FromLong(sizeof(digit))); - if (PyErr_Occurred()) { - Py_CLEAR(int_info); - return NULL; - } - return int_info; + PyObject* int_info; + int field = 0; + int_info = PyStructSequence_New(&Int_InfoType); + if (int_info == NULL) + return NULL; + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(PyLong_SHIFT)); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(sizeof(digit))); + if (PyErr_Occurred()) { + Py_CLEAR(int_info); + return NULL; + } + return int_info; } int _PyLong_Init(void) { #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int ival, size; - PyLongObject *v = small_ints; - - for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { - size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); - if (Py_TYPE(v) == &PyLong_Type) { - /* The element is already initialized, most likely - * the Python interpreter was initialized before. - */ - Py_ssize_t refcnt; - PyObject* op = (PyObject*)v; - - refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op); - _Py_NewReference(op); - /* _Py_NewReference sets the ref count to 1 but - * the ref count might be larger. Set the refcnt - * to the original refcnt + 1 */ - Py_REFCNT(op) = refcnt + 1; - assert(Py_SIZE(op) == size); - assert(v->ob_digit[0] == abs(ival)); - } - else { - PyObject_INIT(v, &PyLong_Type); - } - Py_SIZE(v) = size; - v->ob_digit[0] = abs(ival); - } + int ival, size; + PyLongObject *v = small_ints; + + for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { + size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + if (Py_TYPE(v) == &PyLong_Type) { + /* The element is already initialized, most likely + * the Python interpreter was initialized before. + */ + Py_ssize_t refcnt; + PyObject* op = (PyObject*)v; + + refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op); + _Py_NewReference(op); + /* _Py_NewReference sets the ref count to 1 but + * the ref count might be larger. Set the refcnt + * to the original refcnt + 1 */ + Py_REFCNT(op) = refcnt + 1; + assert(Py_SIZE(op) == size); + assert(v->ob_digit[0] == abs(ival)); + } + else { + PyObject_INIT(v, &PyLong_Type); + } + Py_SIZE(v) = size; + v->ob_digit[0] = abs(ival); + } #endif - /* initialize int_info */ - if (Int_InfoType.tp_name == 0) - PyStructSequence_InitType(&Int_InfoType, &int_info_desc); + /* initialize int_info */ + if (Int_InfoType.tp_name == 0) + PyStructSequence_InitType(&Int_InfoType, &int_info_desc); - return 1; + return 1; } void PyLong_Fini(void) { - /* Integers are currently statically allocated. Py_DECREF is not - needed, but Python must forget about the reference or multiple - reinitializations will fail. */ + /* Integers are currently statically allocated. Py_DECREF is not + needed, but Python must forget about the reference or multiple + reinitializations will fail. */ #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int i; - PyLongObject *v = small_ints; - for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { - _Py_DEC_REFTOTAL; - _Py_ForgetReference((PyObject*)v); - } + int i; + PyLongObject *v = small_ints; + for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { + _Py_DEC_REFTOTAL; + _Py_ForgetReference((PyObject*)v); + } #endif } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index b734b0fe5d..356d161842 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -16,104 +16,104 @@ static int numfree = 0; 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; + 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; + 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; + 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; + 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: - 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; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags in " - "PyCFunction_Call. METH_OLDARGS is no " - "longer supported!"); - - return NULL; - } - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - f->m_ml->ml_name); - return NULL; + 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: + 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; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags in " + "PyCFunction_Call. METH_OLDARGS is no " + "longer supported!"); + + 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) */ @@ -121,163 +121,163 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) 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); - } + _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; + const char *doc = m->m_ml->ml_doc; - if (doc != NULL) - return PyUnicode_FromString(doc); - Py_INCREF(Py_None); - return Py_None; + if (doc != NULL) + return PyUnicode_FromString(doc); + Py_INCREF(Py_None); + return Py_None; } static PyObject * meth_get__name__(PyCFunctionObject *m, void *closure) { - return PyUnicode_FromString(m->m_ml->ml_name); + return PyUnicode_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; + Py_VISIT(m->m_self); + Py_VISIT(m->m_module); + return 0; } static PyObject * meth_get__self__(PyCFunctionObject *m, void *closure) { - PyObject *self; + PyObject *self; - self = m->m_self; - if (self == NULL) - self = Py_None; - Py_INCREF(self); - return self; + 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} + {"__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} + {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED}, + {NULL} }; static PyObject * meth_repr(PyCFunctionObject *m) { - if (m->m_self == NULL || PyModule_Check(m->m_self)) - return PyUnicode_FromFormat("", - m->m_ml->ml_name); - return PyUnicode_FromFormat("", - m->m_ml->ml_name, - m->m_self->ob_type->tp_name, - m->m_self); + if (m->m_self == NULL || PyModule_Check(m->m_self)) + return PyUnicode_FromFormat("", + m->m_ml->ml_name); + return PyUnicode_FromFormat("", + m->m_ml->ml_name, + m->m_self->ob_type->tp_name, + m->m_self); } static PyObject * meth_richcompare(PyObject *self, PyObject *other, int op) { - PyCFunctionObject *a, *b; - PyObject *res; - int eq; - - if ((op != Py_EQ && op != Py_NE) || - !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; + PyCFunctionObject *a, *b; + PyObject *res; + int eq; + + if ((op != Py_EQ && op != Py_NE) || + !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; + 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 */ - 0, /* tp_reserved */ - (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 */ + 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 */ + 0, /* tp_reserved */ + (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 */ }; /* Clear out the free list */ @@ -285,22 +285,22 @@ PyTypeObject PyCFunction_Type = { 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; + 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(); + (void)PyCFunction_ClearFreeList(); } /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(), @@ -314,5 +314,5 @@ PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *); PyObject * PyCFunction_New(PyMethodDef *ml, PyObject *self) { - return PyCFunction_NewEx(ml, self, NULL); + return PyCFunction_NewEx(ml, self, NULL); } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index feac861b5c..9ef7339c14 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -7,53 +7,53 @@ static Py_ssize_t max_module_number; typedef struct { - PyObject_HEAD - PyObject *md_dict; - struct PyModuleDef *md_def; - void *md_state; + PyObject_HEAD + PyObject *md_dict; + struct PyModuleDef *md_def; + void *md_state; } PyModuleObject; static PyMemberDef module_members[] = { - {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, - {0} + {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, + {0} }; static PyTypeObject moduledef_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "moduledef", /* tp_name */ - sizeof(struct PyModuleDef), /* tp_size */ - 0, /* tp_itemsize */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "moduledef", /* tp_name */ + sizeof(struct PyModuleDef), /* tp_size */ + 0, /* tp_itemsize */ }; PyObject * PyModule_New(const char *name) { - PyModuleObject *m; - PyObject *nameobj; - m = PyObject_GC_New(PyModuleObject, &PyModule_Type); - if (m == NULL) - return NULL; - m->md_def = NULL; - m->md_state = NULL; - nameobj = PyUnicode_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; + PyModuleObject *m; + PyObject *nameobj; + m = PyObject_GC_New(PyModuleObject, &PyModule_Type); + if (m == NULL) + return NULL; + m->md_def = NULL; + m->md_state = NULL; + nameobj = PyUnicode_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; + Py_XDECREF(nameobj); + Py_DECREF(m); + return NULL; } static char api_version_warning[] = @@ -63,231 +63,231 @@ static char api_version_warning[] = PyObject * PyModule_Create2(struct PyModuleDef* module, int module_api_version) { - PyObject *d, *v, *n; - PyMethodDef *ml; - const char* name; - PyModuleObject *m; - if (!Py_IsInitialized()) - Py_FatalError("Interpreter not initialized (version mismatch?)"); - if (PyType_Ready(&moduledef_type) < 0) - return NULL; - if (module->m_base.m_index == 0) { - max_module_number++; - Py_REFCNT(module) = 1; - Py_TYPE(module) = &moduledef_type; - module->m_base.m_index = max_module_number; - } - name = module->m_name; - if (module_api_version != PYTHON_API_VERSION) { - char message[512]; - PyOS_snprintf(message, sizeof(message), - api_version_warning, name, - PYTHON_API_VERSION, name, - module_api_version); - if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) - return NULL; - } - /* Make sure name is fully qualified. - - This is a bit of a hack: when the shared library is loaded, - the module name is "package.module", but the module calls - PyModule_Create*() with just "module" for the name. The shared - library loader squirrels away the true name of the module in - _Py_PackageContext, and PyModule_Create*() will substitute this - (if the name actually matches). - */ - if (_Py_PackageContext != NULL) { - char *p = strrchr(_Py_PackageContext, '.'); - if (p != NULL && strcmp(module->m_name, p+1) == 0) { - name = _Py_PackageContext; - _Py_PackageContext = NULL; - } - } - if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) - return NULL; - - if (module->m_size > 0) { - m->md_state = PyMem_MALLOC(module->m_size); - if (!m->md_state) { - PyErr_NoMemory(); - Py_DECREF(m); - return NULL; - } - memset(m->md_state, 0, module->m_size); - } - - d = PyModule_GetDict((PyObject*)m); - if (module->m_methods != NULL) { - n = PyUnicode_FromString(name); - if (n == NULL) - return NULL; - for (ml = module->m_methods; ml->ml_name != NULL; ml++) { - if ((ml->ml_flags & METH_CLASS) || - (ml->ml_flags & METH_STATIC)) { - PyErr_SetString(PyExc_ValueError, - "module functions cannot set" - " METH_CLASS or METH_STATIC"); - Py_DECREF(n); - return NULL; - } - v = PyCFunction_NewEx(ml, (PyObject*)m, n); - if (v == NULL) { - Py_DECREF(n); - return NULL; - } - if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { - Py_DECREF(v); - Py_DECREF(n); - return NULL; - } - Py_DECREF(v); - } - Py_DECREF(n); - } - if (module->m_doc != NULL) { - v = PyUnicode_FromString(module->m_doc); - if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { - Py_XDECREF(v); - return NULL; - } - Py_DECREF(v); - } - m->md_def = module; - return (PyObject*)m; + PyObject *d, *v, *n; + PyMethodDef *ml; + const char* name; + PyModuleObject *m; + if (!Py_IsInitialized()) + Py_FatalError("Interpreter not initialized (version mismatch?)"); + if (PyType_Ready(&moduledef_type) < 0) + return NULL; + if (module->m_base.m_index == 0) { + max_module_number++; + Py_REFCNT(module) = 1; + Py_TYPE(module) = &moduledef_type; + module->m_base.m_index = max_module_number; + } + name = module->m_name; + if (module_api_version != PYTHON_API_VERSION) { + char message[512]; + PyOS_snprintf(message, sizeof(message), + api_version_warning, name, + PYTHON_API_VERSION, name, + module_api_version); + if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) + return NULL; + } + /* Make sure name is fully qualified. + + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + PyModule_Create*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _Py_PackageContext, and PyModule_Create*() will substitute this + (if the name actually matches). + */ + if (_Py_PackageContext != NULL) { + char *p = strrchr(_Py_PackageContext, '.'); + if (p != NULL && strcmp(module->m_name, p+1) == 0) { + name = _Py_PackageContext; + _Py_PackageContext = NULL; + } + } + if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) + return NULL; + + if (module->m_size > 0) { + m->md_state = PyMem_MALLOC(module->m_size); + if (!m->md_state) { + PyErr_NoMemory(); + Py_DECREF(m); + return NULL; + } + memset(m->md_state, 0, module->m_size); + } + + d = PyModule_GetDict((PyObject*)m); + if (module->m_methods != NULL) { + n = PyUnicode_FromString(name); + if (n == NULL) + return NULL; + for (ml = module->m_methods; ml->ml_name != NULL; ml++) { + if ((ml->ml_flags & METH_CLASS) || + (ml->ml_flags & METH_STATIC)) { + PyErr_SetString(PyExc_ValueError, + "module functions cannot set" + " METH_CLASS or METH_STATIC"); + Py_DECREF(n); + return NULL; + } + v = PyCFunction_NewEx(ml, (PyObject*)m, n); + if (v == NULL) { + Py_DECREF(n); + return NULL; + } + if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { + Py_DECREF(v); + Py_DECREF(n); + return NULL; + } + Py_DECREF(v); + } + Py_DECREF(n); + } + if (module->m_doc != NULL) { + v = PyUnicode_FromString(module->m_doc); + if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { + Py_XDECREF(v); + return NULL; + } + Py_DECREF(v); + } + m->md_def = module; + return (PyObject*)m; } 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; + 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; } const 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 || - !PyUnicode_Check(nameobj)) - { - PyErr_SetString(PyExc_SystemError, "nameless module"); - return NULL; - } - return _PyUnicode_AsString(nameobj); + 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 || + !PyUnicode_Check(nameobj)) + { + PyErr_SetString(PyExc_SystemError, "nameless module"); + return NULL; + } + return _PyUnicode_AsString(nameobj); } static PyObject* module_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 || - !PyUnicode_Check(fileobj)) - { - PyErr_SetString(PyExc_SystemError, "module filename missing"); - return NULL; - } - return fileobj; + 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 || + !PyUnicode_Check(fileobj)) + { + PyErr_SetString(PyExc_SystemError, "module filename missing"); + return NULL; + } + return fileobj; } const char * PyModule_GetFilename(PyObject *m) { - PyObject *fileobj; - fileobj = module_getfilename(m); - if (fileobj == NULL) - return NULL; - return _PyUnicode_AsString(fileobj); + PyObject *fileobj; + fileobj = module_getfilename(m); + if (fileobj == NULL) + return NULL; + return _PyUnicode_AsString(fileobj); } PyModuleDef* PyModule_GetDef(PyObject* m) { - if (!PyModule_Check(m)) { - PyErr_BadArgument(); - return NULL; - } - return ((PyModuleObject *)m)->md_def; + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + return ((PyModuleObject *)m)->md_def; } void* PyModule_GetState(PyObject* m) { - if (!PyModule_Check(m)) { - PyErr_BadArgument(); - return NULL; - } - return ((PyModuleObject *)m)->md_state; + if (!PyModule_Check(m)) { + PyErr_BadArgument(); + return NULL; + } + return ((PyModuleObject *)m)->md_state; } 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 && PyUnicode_Check(key)) { - const char *s = _PyUnicode_AsString(key); - if (s[0] == '_' && s[1] != '_') { - if (Py_VerboseFlag > 1) - PySys_WriteStderr("# clear[1] %s\n", s); - PyDict_SetItem(d, key, Py_None); - } - } - } - - /* Next, clear all names except for __builtins__ */ - pos = 0; - while (PyDict_Next(d, &pos, &key, &value)) { - if (value != Py_None && PyUnicode_Check(key)) { - const char *s = _PyUnicode_AsString(key); - if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { - if (Py_VerboseFlag > 1) - PySys_WriteStderr("# clear[2] %s\n", s); - PyDict_SetItem(d, key, Py_None); - } - } - } - - /* Note: we leave __builtins__ in place, so that destructors - of non-global objects defined in this module can still use - builtins, in particularly 'None'. */ + /* 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 && PyUnicode_Check(key)) { + const char *s = _PyUnicode_AsString(key); + if (s[0] == '_' && s[1] != '_') { + if (Py_VerboseFlag > 1) + PySys_WriteStderr("# clear[1] %s\n", s); + PyDict_SetItem(d, key, Py_None); + } + } + } + + /* Next, clear all names except for __builtins__ */ + pos = 0; + while (PyDict_Next(d, &pos, &key, &value)) { + if (value != Py_None && PyUnicode_Check(key)) { + const char *s = _PyUnicode_AsString(key); + if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { + if (Py_VerboseFlag > 1) + PySys_WriteStderr("# clear[2] %s\n", s); + PyDict_SetItem(d, key, Py_None); + } + } + } + + /* Note: we leave __builtins__ in place, so that destructors + of non-global objects defined in this module can still use + builtins, in particularly 'None'. */ } @@ -296,86 +296,86 @@ _PyModule_Clear(PyObject *m) 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, "U|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 char *kwlist[] = {"name", "doc", NULL}; + PyObject *dict, *name = Py_None, *doc = Py_None; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|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_def && m->md_def->m_free) - m->md_def->m_free(m); - if (m->md_dict != NULL) { - /* If we are the only ones holding a reference, we can clear - the dictionary. */ - if (Py_REFCNT(m->md_dict) == 1) - _PyModule_Clear((PyObject *)m); - Py_DECREF(m->md_dict); - } - if (m->md_state != NULL) - PyMem_FREE(m->md_state); - Py_TYPE(m)->tp_free((PyObject *)m); + PyObject_GC_UnTrack(m); + if (m->md_def && m->md_def->m_free) + m->md_def->m_free(m); + if (m->md_dict != NULL) { + /* If we are the only ones holding a reference, we can clear + the dictionary. */ + if (Py_REFCNT(m->md_dict) == 1) + _PyModule_Clear((PyObject *)m); + Py_DECREF(m->md_dict); + } + if (m->md_state != NULL) + PyMem_FREE(m->md_state); + Py_TYPE(m)->tp_free((PyObject *)m); } static PyObject * module_repr(PyModuleObject *m) { - const char *name; - PyObject *filename; - - name = PyModule_GetName((PyObject *)m); - if (name == NULL) { - PyErr_Clear(); - name = "?"; - } - filename = module_getfilename((PyObject *)m); - if (filename == NULL) { - PyErr_Clear(); - return PyUnicode_FromFormat("", name); - } - return PyUnicode_FromFormat("", name, filename); + const char *name; + PyObject *filename; + + name = PyModule_GetName((PyObject *)m); + if (name == NULL) { + PyErr_Clear(); + name = "?"; + } + filename = module_getfilename((PyObject *)m); + if (filename == NULL) { + PyErr_Clear(); + return PyUnicode_FromFormat("", name); + } + return PyUnicode_FromFormat("", name, filename); } static int module_traverse(PyModuleObject *m, visitproc visit, void *arg) { - if (m->md_def && m->md_def->m_traverse) { - int res = m->md_def->m_traverse((PyObject*)m, visit, arg); - if (res) - return res; - } - Py_VISIT(m->md_dict); - return 0; + if (m->md_def && m->md_def->m_traverse) { + int res = m->md_def->m_traverse((PyObject*)m, visit, arg); + if (res) + return res; + } + Py_VISIT(m->md_dict); + return 0; } static int module_clear(PyModuleObject *m) { - if (m->md_def && m->md_def->m_clear) { - int res = m->md_def->m_clear((PyObject*)m); - if (res) - return res; - } - Py_CLEAR(m->md_dict); - return 0; + if (m->md_def && m->md_def->m_clear) { + int res = m->md_def->m_clear((PyObject*)m); + if (res) + return res; + } + Py_CLEAR(m->md_dict); + return 0; } - + PyDoc_STRVAR(module_doc, "module(name[, doc])\n\ @@ -384,44 +384,44 @@ 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_reserved */ - (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 */ - (inquiry)module_clear, /* 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 */ + 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_reserved */ + (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 */ + (inquiry)module_clear, /* 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/Objects/object.c b/Objects/object.c index 4d3d6590cc..8ddc7ec78c 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -15,18 +15,18 @@ 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; + 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 */ @@ -58,21 +58,21 @@ 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)); - } + 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; - } + 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 */ +#endif /* Py_TRACE_REFS */ #ifdef COUNT_ALLOCS static PyTypeObject *type_list; @@ -89,99 +89,99 @@ 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); + 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; + 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; + 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); + /* 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; + } + 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); - } + 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 @@ -191,13 +191,13 @@ void dec_count(PyTypeObject *tp) void _Py_NegativeRefcount(const char *fname, int lineno, PyObject *op) { - char buf[300]; + 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); + 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 */ @@ -217,123 +217,123 @@ Py_DecRef(PyObject *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; + 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; + 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); + 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); + 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); } /* 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; + 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; - } + 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, ""); - 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, "", - (long)op->ob_refcnt, op); - Py_END_ALLOW_THREADS - else { - PyObject *s; - if (flags & Py_PRINT_RAW) - s = PyObject_Str(op); - else - s = PyObject_Repr(op); - if (s == NULL) - ret = -1; - else if (PyBytes_Check(s)) { - fwrite(PyBytes_AS_STRING(s), 1, - PyBytes_GET_SIZE(s), fp); - } - else if (PyUnicode_Check(s)) { - PyObject *t; - t = _PyUnicode_AsDefaultEncodedString(s, NULL); - if (t == NULL) - ret = 0; - else { - fwrite(PyBytes_AS_STRING(t), 1, - PyBytes_GET_SIZE(t), fp); - } - } - else { - PyErr_Format(PyExc_TypeError, - "str() or repr() returned '%.100s'", - s->ob_type->tp_name); - ret = -1; - } - Py_XDECREF(s); - } - } - if (ret == 0) { - if (ferror(fp)) { - PyErr_SetFromErrno(PyExc_IOError); - clearerr(fp); - ret = -1; - } - } - return ret; + clearerr(fp); /* Clear any previous error condition */ + if (op == NULL) { + Py_BEGIN_ALLOW_THREADS + fprintf(fp, ""); + 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, "", + (long)op->ob_refcnt, op); + Py_END_ALLOW_THREADS + else { + PyObject *s; + if (flags & Py_PRINT_RAW) + s = PyObject_Str(op); + else + s = PyObject_Repr(op); + if (s == NULL) + ret = -1; + else if (PyBytes_Check(s)) { + fwrite(PyBytes_AS_STRING(s), 1, + PyBytes_GET_SIZE(s), fp); + } + else if (PyUnicode_Check(s)) { + PyObject *t; + t = _PyUnicode_AsDefaultEncodedString(s, NULL); + if (t == NULL) + ret = 0; + else { + fwrite(PyBytes_AS_STRING(t), 1, + PyBytes_GET_SIZE(t), fp); + } + } + else { + PyErr_Format(PyExc_TypeError, + "str() or repr() returned '%.100s'", + s->ob_type->tp_name); + ret = -1; + } + Py_XDECREF(s); + } + } + 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); + return internal_print(op, fp, flags, 0); } /* For debugging convenience. Set a breakpoint here and call it from your DLL */ @@ -347,159 +347,159 @@ _Py_BreakPoint(void) void _PyObject_Dump(PyObject* op) { - if (op == NULL) - fprintf(stderr, "NULL\n"); - else { + if (op == NULL) + fprintf(stderr, "NULL\n"); + else { #ifdef WITH_THREAD - PyGILState_STATE gil; + PyGILState_STATE gil; #endif - fprintf(stderr, "object : "); + fprintf(stderr, "object : "); #ifdef WITH_THREAD - gil = PyGILState_Ensure(); + gil = PyGILState_Ensure(); #endif - (void)PyObject_Print(op, stderr, 0); + (void)PyObject_Print(op, stderr, 0); #ifdef WITH_THREAD - PyGILState_Release(gil); + 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); - } + /* 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) { - PyObject *res; - if (PyErr_CheckSignals()) - return NULL; + PyObject *res; + if (PyErr_CheckSignals()) + return NULL; #ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } + if (PyOS_CheckStack()) { + PyErr_SetString(PyExc_MemoryError, "stack overflow"); + return NULL; + } #endif - if (v == NULL) - return PyUnicode_FromString(""); - if (Py_TYPE(v)->tp_repr == NULL) - return PyUnicode_FromFormat("<%s object at %p>", - v->ob_type->tp_name, v); - res = (*v->ob_type->tp_repr)(v); - if (res != NULL && !PyUnicode_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__repr__ returned non-string (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; + if (v == NULL) + return PyUnicode_FromString(""); + if (Py_TYPE(v)->tp_repr == NULL) + return PyUnicode_FromFormat("<%s object at %p>", + v->ob_type->tp_name, v); + res = (*v->ob_type->tp_repr)(v); + if (res != NULL && !PyUnicode_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__repr__ returned non-string (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } PyObject * PyObject_Str(PyObject *v) { - PyObject *res; - if (PyErr_CheckSignals()) - return NULL; + PyObject *res; + if (PyErr_CheckSignals()) + return NULL; #ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } + if (PyOS_CheckStack()) { + PyErr_SetString(PyExc_MemoryError, "stack overflow"); + return NULL; + } #endif - if (v == NULL) - return PyUnicode_FromString(""); - if (PyUnicode_CheckExact(v)) { - Py_INCREF(v); - return v; - } - 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; - if (!PyUnicode_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__str__ returned non-string (type %.200s)", - Py_TYPE(res)->tp_name); - Py_DECREF(res); - return NULL; - } - return res; + if (v == NULL) + return PyUnicode_FromString(""); + if (PyUnicode_CheckExact(v)) { + Py_INCREF(v); + return v; + } + 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; + if (!PyUnicode_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__str__ returned non-string (type %.200s)", + Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } PyObject * PyObject_ASCII(PyObject *v) { - PyObject *repr, *ascii, *res; - - repr = PyObject_Repr(v); - if (repr == NULL) - return NULL; + PyObject *repr, *ascii, *res; + + repr = PyObject_Repr(v); + if (repr == NULL) + return NULL; - /* repr is guaranteed to be a PyUnicode object by PyObject_Repr */ - ascii = PyUnicode_EncodeASCII( - PyUnicode_AS_UNICODE(repr), - PyUnicode_GET_SIZE(repr), - "backslashreplace"); + /* repr is guaranteed to be a PyUnicode object by PyObject_Repr */ + ascii = PyUnicode_EncodeASCII( + PyUnicode_AS_UNICODE(repr), + PyUnicode_GET_SIZE(repr), + "backslashreplace"); - Py_DECREF(repr); - if (ascii == NULL) - return NULL; + Py_DECREF(repr); + if (ascii == NULL) + return NULL; - res = PyUnicode_DecodeASCII( - PyBytes_AS_STRING(ascii), - PyBytes_GET_SIZE(ascii), - NULL); + res = PyUnicode_DecodeASCII( + PyBytes_AS_STRING(ascii), + PyBytes_GET_SIZE(ascii), + NULL); - Py_DECREF(ascii); - return res; + Py_DECREF(ascii); + return res; } PyObject * PyObject_Bytes(PyObject *v) { - PyObject *result, *func; - static PyObject *bytesstring = NULL; - - if (v == NULL) - return PyBytes_FromString(""); - - if (PyBytes_CheckExact(v)) { - Py_INCREF(v); - return v; - } - - func = _PyObject_LookupSpecial(v, "__bytes__", &bytesstring); - if (func != NULL) { - result = PyObject_CallFunctionObjArgs(func, NULL); - Py_DECREF(func); - if (result == NULL) - return NULL; - if (!PyBytes_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__bytes__ returned non-bytes (type %.200s)", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; - } - return result; - } - else if (PyErr_Occurred()) - return NULL; - return PyBytes_FromObject(v); + PyObject *result, *func; + static PyObject *bytesstring = NULL; + + if (v == NULL) + return PyBytes_FromString(""); + + if (PyBytes_CheckExact(v)) { + Py_INCREF(v); + return v; + } + + func = _PyObject_LookupSpecial(v, "__bytes__", &bytesstring); + if (func != NULL) { + result = PyObject_CallFunctionObjArgs(func, NULL); + Py_DECREF(func); + if (result == NULL) + return NULL; + if (!PyBytes_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + return result; + } + else if (PyErr_Occurred()) + return NULL; + return PyBytes_FromObject(v); } /* For Python 3.0.1 and later, the old three-way comparison has been @@ -542,51 +542,51 @@ static char *opstrings[] = {"<", "<=", "==", "!=", ">", ">="}; static PyObject * do_richcompare(PyObject *v, PyObject *w, int op) { - richcmpfunc f; - PyObject *res; - int checked_reverse_op = 0; - - if (v->ob_type != w->ob_type && - PyType_IsSubtype(w->ob_type, v->ob_type) && - (f = w->ob_type->tp_richcompare) != NULL) { - checked_reverse_op = 1; - res = (*f)(w, v, _Py_SwappedOp[op]); - if (res != Py_NotImplemented) - return res; - Py_DECREF(res); - } - if ((f = v->ob_type->tp_richcompare) != NULL) { - res = (*f)(v, w, op); - if (res != Py_NotImplemented) - return res; - Py_DECREF(res); - } - if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { - res = (*f)(w, v, _Py_SwappedOp[op]); - if (res != Py_NotImplemented) - return res; - Py_DECREF(res); - } - /* If neither object implements it, provide a sensible default - for == and !=, but raise an exception for ordering. */ - switch (op) { - case Py_EQ: - res = (v == w) ? Py_True : Py_False; - break; - case Py_NE: - res = (v != w) ? Py_True : Py_False; - break; - default: - /* XXX Special-case None so it doesn't show as NoneType() */ - PyErr_Format(PyExc_TypeError, - "unorderable types: %.100s() %s %.100s()", - v->ob_type->tp_name, - opstrings[op], - w->ob_type->tp_name); - return NULL; - } - Py_INCREF(res); - return res; + richcmpfunc f; + PyObject *res; + int checked_reverse_op = 0; + + if (v->ob_type != w->ob_type && + PyType_IsSubtype(w->ob_type, v->ob_type) && + (f = w->ob_type->tp_richcompare) != NULL) { + checked_reverse_op = 1; + res = (*f)(w, v, _Py_SwappedOp[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + if ((f = v->ob_type->tp_richcompare) != NULL) { + res = (*f)(v, w, op); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { + res = (*f)(w, v, _Py_SwappedOp[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } + /* If neither object implements it, provide a sensible default + for == and !=, but raise an exception for ordering. */ + switch (op) { + case Py_EQ: + res = (v == w) ? Py_True : Py_False; + break; + case Py_NE: + res = (v != w) ? Py_True : Py_False; + break; + default: + /* XXX Special-case None so it doesn't show as NoneType() */ + PyErr_Format(PyExc_TypeError, + "unorderable types: %.100s() %s %.100s()", + v->ob_type->tp_name, + opstrings[op], + w->ob_type->tp_name); + return NULL; + } + Py_INCREF(res); + return res; } /* Perform a rich comparison with object result. This wraps do_richcompare() @@ -595,19 +595,19 @@ do_richcompare(PyObject *v, PyObject *w, int op) PyObject * PyObject_RichCompare(PyObject *v, PyObject *w, int op) { - PyObject *res; + PyObject *res; - assert(Py_LT <= op && op <= Py_GE); - if (v == NULL || w == NULL) { - if (!PyErr_Occurred()) - PyErr_BadInternalCall(); - return NULL; - } - if (Py_EnterRecursiveCall(" in comparison")) - return NULL; - res = do_richcompare(v, w, op); - Py_LeaveRecursiveCall(); - return res; + assert(Py_LT <= op && op <= Py_GE); + if (v == NULL || w == NULL) { + if (!PyErr_Occurred()) + PyErr_BadInternalCall(); + return NULL; + } + if (Py_EnterRecursiveCall(" in comparison")) + return NULL; + res = do_richcompare(v, w, op); + Py_LeaveRecursiveCall(); + return res; } /* Perform a rich comparison with integer result. This wraps @@ -615,31 +615,31 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op) 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; + 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) + if a==b then hash(a)==hash(b) All the utility functions (_Py_Hash*()) return "-1" to signify an error. */ @@ -647,230 +647,230 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op) 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; + 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 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 *v) { - PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", - Py_TYPE(v)->tp_name); - return -1; + PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", + Py_TYPE(v)->tp_name); + return -1; } long PyObject_Hash(PyObject *v) { - PyTypeObject *tp = Py_TYPE(v); - 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); - } - /* Otherwise, the object can't be hashed */ - return PyObject_HashNotImplemented(v); + PyTypeObject *tp = Py_TYPE(v); + 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); + } + /* Otherwise, the object can't be hashed */ + return PyObject_HashNotImplemented(v); } PyObject * PyObject_GetAttrString(PyObject *v, const char *name) { - PyObject *w, *res; + PyObject *w, *res; - if (Py_TYPE(v)->tp_getattr != NULL) - return (*Py_TYPE(v)->tp_getattr)(v, (char*)name); - w = PyUnicode_InternFromString(name); - if (w == NULL) - return NULL; - res = PyObject_GetAttr(v, w); - Py_XDECREF(w); - return res; + if (Py_TYPE(v)->tp_getattr != NULL) + return (*Py_TYPE(v)->tp_getattr)(v, (char*)name); + w = PyUnicode_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; + 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; + PyObject *s; + int res; - if (Py_TYPE(v)->tp_setattr != NULL) - return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w); - s = PyUnicode_InternFromString(name); - if (s == NULL) - return -1; - res = PyObject_SetAttr(v, s, w); - Py_XDECREF(s); - return res; + if (Py_TYPE(v)->tp_setattr != NULL) + return (*Py_TYPE(v)->tp_setattr)(v, (char*)name, w); + s = PyUnicode_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 (!PyUnicode_Check(name)) { - PyErr_Format(PyExc_TypeError, - "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); - return NULL; - } - if (tp->tp_getattro != NULL) - return (*tp->tp_getattro)(v, name); - if (tp->tp_getattr != NULL) { - char *name_str = _PyUnicode_AsString(name); - if (name_str == NULL) - return NULL; - return (*tp->tp_getattr)(v, name_str); - } - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); - return NULL; + PyTypeObject *tp = Py_TYPE(v); + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return NULL; + } + if (tp->tp_getattro != NULL) + return (*tp->tp_getattro)(v, name); + if (tp->tp_getattr != NULL) { + char *name_str = _PyUnicode_AsString(name); + if (name_str == NULL) + return NULL; + return (*tp->tp_getattr)(v, name_str); + } + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, 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; + 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 (!PyUnicode_Check(name)) { - PyErr_Format(PyExc_TypeError, - "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); - return -1; - } - Py_INCREF(name); - - PyUnicode_InternInPlace(&name); - if (tp->tp_setattro != NULL) { - err = (*tp->tp_setattro)(v, name, value); - Py_DECREF(name); - return err; - } - if (tp->tp_setattr != NULL) { - char *name_str = _PyUnicode_AsString(name); - if (name_str == NULL) - return -1; - err = (*tp->tp_setattr)(v, name_str, value); - Py_DECREF(name); - return err; - } - Py_DECREF(name); - assert(name->ob_refcnt >= 1); - if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) - PyErr_Format(PyExc_TypeError, - "'%.100s' object has no attributes " - "(%s .%U)", - tp->tp_name, - value==NULL ? "del" : "assign to", - name); - else - PyErr_Format(PyExc_TypeError, - "'%.100s' object has only read-only attributes " - "(%s .%U)", - tp->tp_name, - value==NULL ? "del" : "assign to", - name); - return -1; + PyTypeObject *tp = Py_TYPE(v); + int err; + + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return -1; + } + Py_INCREF(name); + + PyUnicode_InternInPlace(&name); + if (tp->tp_setattro != NULL) { + err = (*tp->tp_setattro)(v, name, value); + Py_DECREF(name); + return err; + } + if (tp->tp_setattr != NULL) { + char *name_str = _PyUnicode_AsString(name); + if (name_str == NULL) + return -1; + err = (*tp->tp_setattr)(v, name_str, value); + Py_DECREF(name); + return err; + } + Py_DECREF(name); + assert(name->ob_refcnt >= 1); + if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) + PyErr_Format(PyExc_TypeError, + "'%.100s' object has no attributes " + "(%s .%U)", + tp->tp_name, + value==NULL ? "del" : "assign to", + name); + else + PyErr_Format(PyExc_TypeError, + "'%.100s' object has only read-only attributes " + "(%s .%U)", + tp->tp_name, + value==NULL ? "del" : "assign to", + name); + return -1; } /* Helper to get a pointer to an object's __dict__ slot, if any */ @@ -878,33 +878,33 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) PyObject ** _PyObject_GetDictPtr(PyObject *obj) { - Py_ssize_t dictoffset; - PyTypeObject *tp = Py_TYPE(obj); + Py_ssize_t dictoffset; + PyTypeObject *tp = Py_TYPE(obj); - dictoffset = tp->tp_dictoffset; - if (dictoffset == 0) - return NULL; - if (dictoffset < 0) { - Py_ssize_t tsize; - size_t size; + 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); + 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); + 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; + Py_INCREF(obj); + return obj; } /* Helper used when the __next__ method is removed from a type: @@ -915,10 +915,10 @@ PyObject_SelfIter(PyObject *obj) PyObject * _PyObject_NextNotImplemented(PyObject *self) { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not iterable", - Py_TYPE(self)->tp_name); - return NULL; + 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 */ @@ -926,189 +926,189 @@ _PyObject_NextNotImplemented(PyObject *self) PyObject * PyObject_GenericGetAttr(PyObject *obj, PyObject *name) { - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr = NULL; - PyObject *res = NULL; - descrgetfunc f; - Py_ssize_t dictoffset; - PyObject **dictptr; - - if (!PyUnicode_Check(name)){ - PyErr_Format(PyExc_TypeError, - "attribute name must be string, not '%.200s'", - name->ob_type->tp_name); - return NULL; - } - else - Py_INCREF(name); - - if (tp->tp_dict == NULL) { - if (PyType_Ready(tp) < 0) - goto done; - } + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr = NULL; + PyObject *res = NULL; + descrgetfunc f; + Py_ssize_t dictoffset; + PyObject **dictptr; + + if (!PyUnicode_Check(name)){ + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->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); - assert(PyType_Check(base)); - dict = ((PyTypeObject *)base)->tp_dict; - assert(dict && PyDict_Check(dict)); - descr = PyDict_GetItem(dict, name); - if (descr != NULL) - break; - } - } + /* 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); + 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); + descr = _PyType_Lookup(tp, name); #endif - Py_XINCREF(descr); - - f = NULL; - if (descr != NULL) { - 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; - } - } - - /* Inline _PyObject_GetDictPtr */ - dictoffset = tp->tp_dictoffset; - if (dictoffset != 0) { - PyObject *dict; - 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 '%U'", - tp->tp_name, name); + Py_XINCREF(descr); + + f = NULL; + if (descr != NULL) { + 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; + } + } + + /* Inline _PyObject_GetDictPtr */ + dictoffset = tp->tp_dictoffset; + if (dictoffset != 0) { + PyObject *dict; + 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 '%U'", + tp->tp_name, name); done: - Py_DECREF(name); - return res; + Py_DECREF(name); + return res; } int PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) { - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrsetfunc f; - PyObject **dictptr; - int res = -1; - - if (!PyUnicode_Check(name)){ - PyErr_Format(PyExc_TypeError, - "attribute name must be string, not '%.200s'", - name->ob_type->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) { - f = descr->ob_type->tp_descr_set; - if (f != NULL && PyDescr_IsData(descr)) { - res = f(descr, obj, value); - goto done; - } - } - - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL) { - PyObject *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 '%U'", - tp->tp_name, name); - goto done; - } - - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrsetfunc f; + PyObject **dictptr; + int res = -1; + + if (!PyUnicode_Check(name)){ + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->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) { + f = descr->ob_type->tp_descr_set; + if (f != NULL && PyDescr_IsData(descr)) { + res = f(descr, obj, value); + goto done; + } + } + + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL) { + PyObject *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 '%U'", + tp->tp_name, name); + goto done; + } + + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + tp->tp_name, name); done: - Py_DECREF(name); - return res; + Py_DECREF(name); + return res; } /* Test a value used as condition, e.g., in a for or if statement. @@ -1117,26 +1117,26 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) 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_bool != NULL) - res = (*v->ob_type->tp_as_number->nb_bool)(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); + 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_bool != NULL) + res = (*v->ob_type->tp_as_number->nb_bool)(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' @@ -1145,11 +1145,11 @@ PyObject_IsTrue(PyObject *v) int PyObject_Not(PyObject *v) { - int res; - res = PyObject_IsTrue(v); - if (res < 0) - return res; - return res == 0; + int res; + res = PyObject_IsTrue(v); + if (res < 0) + return res; + return res == 0; } /* Test whether an object can be called */ @@ -1157,9 +1157,9 @@ PyObject_Not(PyObject *v) int PyCallable_Check(PyObject *x) { - if (x == NULL) - return 0; - return x->ob_type->tp_call != NULL; + if (x == NULL) + return 0; + return x->ob_type->tp_call != NULL; } /* ------------------------- PyObject_Dir() helpers ------------------------- */ @@ -1175,78 +1175,78 @@ PyCallable_Check(PyObject *x) 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; + 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 without arguments: returns the local scope. */ static PyObject * _dir_locals(void) { - PyObject *names; - PyObject *locals = PyEval_GetLocals(); + PyObject *names; + PyObject *locals = PyEval_GetLocals(); - if (locals == NULL) { - PyErr_SetString(PyExc_SystemError, "frame does not exist"); - return NULL; - } + 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; + 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__. @@ -1256,37 +1256,37 @@ _dir_locals(void) static PyObject * _specialized_dir_type(PyObject *obj) { - PyObject *result = NULL; - PyObject *dict = PyDict_New(); + PyObject *result = NULL; + PyObject *dict = PyDict_New(); - if (dict != NULL && merge_class_dict(dict, obj) == 0) - result = PyDict_Keys(dict); + if (dict != NULL && merge_class_dict(dict, obj) == 0) + result = PyDict_Keys(dict); - Py_XDECREF(dict); - return result; + 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 { - const char *name = PyModule_GetName(obj); - if (name) - PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ is not a dictionary", - name); - } - } + PyObject *result = NULL; + PyObject *dict = PyObject_GetAttrString(obj, "__dict__"); + + if (dict != NULL) { + if (PyDict_Check(dict)) + result = PyDict_Keys(dict); + else { + const char *name = PyModule_GetName(obj); + if (name) + PyErr_Format(PyExc_TypeError, + "%.200s.__dict__ is not a dictionary", + name); + } + } - Py_XDECREF(dict); - return result; + Py_XDECREF(dict); + return result; } /* Helper for PyObject_Dir of generic objects: returns __dict__, __class__, @@ -1295,47 +1295,47 @@ _specialized_dir_module(PyObject *obj) 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 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 */ + 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 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; + Py_XDECREF(itsclass); + Py_XDECREF(dict); + return result; } /* Helper for PyObject_Dir: object introspection. @@ -1344,40 +1344,40 @@ error: static PyObject * _dir_object(PyObject *obj) { - PyObject * result = NULL; - PyObject * dirfunc = PyObject_GetAttrString((PyObject*)obj->ob_type, - "__dir__"); - - assert(obj); - if (dirfunc == NULL) { - /* use default implementation */ - PyErr_Clear(); - if (PyModule_Check(obj)) - result = _specialized_dir_module(obj); - else if (PyType_Check(obj)) - result = _specialized_dir_type(obj); - else - result = _generic_dir(obj); - } - else { - /* use __dir__ */ - result = PyObject_CallFunctionObjArgs(dirfunc, obj, 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; + PyObject * result = NULL; + PyObject * dirfunc = PyObject_GetAttrString((PyObject*)obj->ob_type, + "__dir__"); + + assert(obj); + if (dirfunc == NULL) { + /* use default implementation */ + PyErr_Clear(); + if (PyModule_Check(obj)) + result = _specialized_dir_module(obj); + else if (PyType_Check(obj)) + result = _specialized_dir_type(obj); + else + result = _generic_dir(obj); + } + else { + /* use __dir__ */ + result = PyObject_CallFunctionObjArgs(dirfunc, obj, 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 @@ -1387,24 +1387,24 @@ _dir_object(PyObject *obj) PyObject * PyObject_Dir(PyObject *obj) { - PyObject * result; + PyObject * result; - if (obj == NULL) - /* no object -- introspect the locals */ - result = _dir_locals(); - else - /* object -- introspect the object */ - result = _dir_object(obj); + 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)); + assert(result == NULL || PyList_Check(result)); - if (result != NULL && PyList_Sort(result) != 0) { - /* sorting the list failed */ - Py_DECREF(result); - result = NULL; - } + if (result != NULL && PyList_Sort(result) != 0) { + /* sorting the list failed */ + Py_DECREF(result); + result = NULL; + } - return result; + return result; } /* @@ -1418,35 +1418,35 @@ so there is exactly one (which is indestructible, by the way). static PyObject * none_repr(PyObject *op) { - return PyUnicode_FromString("None"); + return PyUnicode_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"); + /* 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_reserved*/ - none_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + 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_reserved*/ + none_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ }; PyObject _Py_NoneStruct = { @@ -1460,165 +1460,165 @@ PyObject _Py_NoneStruct = { static PyObject * NotImplemented_repr(PyObject *op) { - return PyUnicode_FromString("NotImplemented"); + return PyUnicode_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_reserved*/ - NotImplemented_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + 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_reserved*/ + 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 + _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(&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_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_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(&_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(&PyBool_Type) < 0) + Py_FatalError("Can't initialize bool type"); - if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray type"); + if (PyType_Ready(&PyByteArray_Type) < 0) + Py_FatalError("Can't initialize bytearray type"); - if (PyType_Ready(&PyBytes_Type) < 0) - Py_FatalError("Can't initialize 'str'"); + if (PyType_Ready(&PyBytes_Type) < 0) + Py_FatalError("Can't initialize 'str'"); - if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list 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(&PyNone_Type) < 0) + Py_FatalError("Can't initialize None type"); - if (PyType_Ready(Py_Ellipsis->ob_type) < 0) - Py_FatalError("Can't initialize type(Ellipsis)"); + if (PyType_Ready(Py_Ellipsis->ob_type) < 0) + Py_FatalError("Can't initialize type(Ellipsis)"); - if (PyType_Ready(&PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize NotImplemented 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(&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(&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(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); - if (PyType_Ready(&PyRange_Type) < 0) - Py_FatalError("Can't initialize range type"); + if (PyType_Ready(&PyRange_Type) < 0) + Py_FatalError("Can't initialize range type"); - if (PyType_Ready(&PyDict_Type) < 0) - Py_FatalError("Can't initialize dict 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"); + if (PyType_Ready(&PySet_Type) < 0) + Py_FatalError("Can't initialize set type"); - if (PyType_Ready(&PyUnicode_Type) < 0) - Py_FatalError("Can't initialize str type"); + if (PyType_Ready(&PyUnicode_Type) < 0) + Py_FatalError("Can't initialize str type"); - if (PyType_Ready(&PySlice_Type) < 0) - Py_FatalError("Can't initialize slice type"); + 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"); + if (PyType_Ready(&PyStaticMethod_Type) < 0) + Py_FatalError("Can't initialize static method type"); - if (PyType_Ready(&PyComplex_Type) < 0) - Py_FatalError("Can't initialize complex type"); + if (PyType_Ready(&PyComplex_Type) < 0) + Py_FatalError("Can't initialize complex type"); - if (PyType_Ready(&PyFloat_Type) < 0) - Py_FatalError("Can't initialize float type"); + if (PyType_Ready(&PyFloat_Type) < 0) + Py_FatalError("Can't initialize float type"); - if (PyType_Ready(&PyLong_Type) < 0) - Py_FatalError("Can't initialize int type"); + if (PyType_Ready(&PyLong_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(&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(&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(&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(&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(&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(&PyReversed_Type) < 0) + Py_FatalError("Can't initialize reversed type"); - if (PyType_Ready(&PyStdPrinter_Type) < 0) - Py_FatalError("Can't initialize StdPrinter"); + if (PyType_Ready(&PyStdPrinter_Type) < 0) + Py_FatalError("Can't initialize StdPrinter"); - if (PyType_Ready(&PyCode_Type) < 0) - Py_FatalError("Can't initialize code 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(&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(&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(&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(&PyFunction_Type) < 0) + Py_FatalError("Can't initialize function type"); - if (PyType_Ready(&PyDictProxy_Type) < 0) - Py_FatalError("Can't initialize dict proxy 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(&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(&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(&PyWrapperDescr_Type) < 0) + Py_FatalError("Can't initialize wrapper type"); - if (PyType_Ready(&PyEllipsis_Type) < 0) - Py_FatalError("Can't initialize ellipsis 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(&PyMemberDescr_Type) < 0) + Py_FatalError("Can't initialize member descriptor type"); - if (PyType_Ready(&PyFilter_Type) < 0) - Py_FatalError("Can't initialize filter type"); + if (PyType_Ready(&PyFilter_Type) < 0) + Py_FatalError("Can't initialize filter type"); - if (PyType_Ready(&PyMap_Type) < 0) - Py_FatalError("Can't initialize map type"); + if (PyType_Ready(&PyMap_Type) < 0) + Py_FatalError("Can't initialize map type"); - if (PyType_Ready(&PyZip_Type) < 0) - Py_FatalError("Can't initialize zip type"); + if (PyType_Ready(&PyZip_Type) < 0) + Py_FatalError("Can't initialize zip type"); } @@ -1627,50 +1627,50 @@ _Py_ReadyTypes(void) void _Py_NewReference(PyObject *op) { - _Py_INC_REFTOTAL; - op->ob_refcnt = 1; - _Py_AddToAllObjects(op, 1); - _Py_INC_TPALLOCS(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; + 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) { - fprintf(stderr, "* ob\n"); - _PyObject_Dump(op); - fprintf(stderr, "* op->_ob_prev->_ob_next\n"); - _PyObject_Dump(op->_ob_prev->_ob_next); - fprintf(stderr, "* op->_ob_next->_ob_prev\n"); - _PyObject_Dump(op->_ob_next->_ob_prev); - Py_FatalError("UNREF invalid object"); - } + 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) { + fprintf(stderr, "* ob\n"); + _PyObject_Dump(op); + fprintf(stderr, "* op->_ob_prev->_ob_next\n"); + _PyObject_Dump(op->_ob_prev->_ob_next); + fprintf(stderr, "* op->_ob_next->_ob_prev\n"); + _PyObject_Dump(op->_ob_next->_ob_prev); + 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"); + 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); + 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); + destructor dealloc = Py_TYPE(op)->tp_dealloc; + _Py_ForgetReference(op); + (*dealloc)(op); } /* Print all live objects. Because PyObject_Print is called, the @@ -1679,14 +1679,14 @@ _Py_Dealloc(PyObject *op) 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); - } + 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 @@ -1695,40 +1695,40 @@ _Py_PrintReferences(FILE *fp) 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 *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; + 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 @@ -1747,19 +1747,19 @@ Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size; void * PyMem_Malloc(size_t nbytes) { - return PyMem_MALLOC(nbytes); + return PyMem_MALLOC(nbytes); } void * PyMem_Realloc(void *p, size_t nbytes) { - return PyMem_REALLOC(p, nbytes); + return PyMem_REALLOC(p, nbytes); } void PyMem_Free(void *p) { - PyMem_FREE(p); + PyMem_FREE(p); } @@ -1780,52 +1780,52 @@ PyMem_Free(void *p) 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; + 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; - } - } + 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. */ @@ -1845,11 +1845,11 @@ PyObject *_PyTrash_delete_later = NULL; 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; + 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; } /* Dealloccate all the objects in the _PyTrash_delete_later list. Called when @@ -1858,24 +1858,24 @@ _PyTrash_deposit_object(PyObject *op) 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; - } + 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; + } } #ifdef __cplusplus diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index fa985da987..274f720d3f 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -27,7 +27,7 @@ static int running_on_valgrind = -1; the cyclic garbage collector operates selectively on container objects. - Object-specific allocators + Object-specific allocators _____ ______ ______ ________ [ int ] [ dict ] [ list ] ... [ string ] Python core | +3 | <----- Object-specific memory -----> | <-- Non-object memory --> | @@ -67,7 +67,7 @@ static int running_on_valgrind = -1; * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. */ -/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ +/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ /*==========================================================================*/ @@ -95,22 +95,22 @@ static int running_on_valgrind = -1; * * For small requests we have the following table: * - * Request in bytes Size of allocated block Size class idx + * 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 - * ... ... ... - * 241-248 248 30 - * 249-256 256 31 + * 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 + * ... ... ... + * 241-248 248 30 + * 249-256 256 31 * - * 0, 257 and up: routed to the underlying allocator. + * 0, 257 and up: routed to the underlying allocator. */ /*==========================================================================*/ @@ -127,9 +127,9 @@ static int running_on_valgrind = -1; * * 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) +#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) @@ -140,14 +140,14 @@ static int running_on_valgrind = -1; * 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 + * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 256 + * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT * * 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 256 -#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) +#define SMALL_REQUEST_THRESHOLD 256 +#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) /* * The system's VMM page size can be obtained on most unices with a @@ -159,15 +159,15 @@ static int running_on_valgrind = -1; * 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) +#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? */ +#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ #endif #endif @@ -184,18 +184,18 @@ static int running_on_valgrind = -1; * some address space wastage, but this is the most portable way to request * memory from the system across various platforms. */ -#define ARENA_SIZE (256 << 10) /* 256KB */ +#define ARENA_SIZE (256 << 10) /* 256KB */ #ifdef WITH_MEMORY_LIMITS -#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) +#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 +#define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */ +#define POOL_SIZE_MASK SYSTEM_PAGE_SIZE_MASK /* * -- End of tunable settings section -- @@ -221,92 +221,92 @@ static int running_on_valgrind = -1; /* * 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 */ +#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 or elsewhere. Axiom. */ #undef uchar -#define uchar unsigned char /* assuming == 8 bits */ +#define uchar unsigned char /* assuming == 8 bits */ #undef uint -#define uint unsigned int /* assuming >= 16 bits */ +#define uint unsigned int /* assuming >= 16 bits */ #undef ulong -#define ulong unsigned long /* assuming >= 32 bits */ +#define ulong unsigned long /* assuming >= 32 bits */ #undef uptr -#define uptr Py_uintptr_t +#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 */ + 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; + /* 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 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 */ +#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)) @@ -320,10 +320,10 @@ struct arena_object { * 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) +#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. @@ -403,9 +403,9 @@ 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; + 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 @@ -421,25 +421,25 @@ 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) +#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) + 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) + , 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) + , 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) + , 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) + , 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) + , 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) + , 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) + , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63) #endif /* NB_SMALL_SIZE_CLASSES > 56 */ #endif /* NB_SMALL_SIZE_CLASSES > 48 */ #endif /* NB_SMALL_SIZE_CLASSES > 40 */ @@ -523,90 +523,90 @@ static size_t narenas_highwater = 0; static struct arena_object* new_arena(void) { - struct arena_object* arenaobj; - uint excess; /* number of bytes above pool alignment */ + struct arena_object* arenaobj; + uint excess; /* number of bytes above pool alignment */ #ifdef PYMALLOC_DEBUG - if (Py_GETENV("PYTHONMALLOCSTATS")) - _PyObject_DebugMallocStats(); + 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 (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 */ + 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); - arenaobj->address = (uptr)malloc(ARENA_SIZE); - if (arenaobj->address == 0) { - /* The allocation failed: return NULL after putting the - * arenaobj back. - */ - arenaobj->nextarena = unused_arena_objects; - unused_arena_objects = arenaobj; - return NULL; - } - - ++narenas_currently_allocated; + 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); + arenaobj->address = (uptr)malloc(ARENA_SIZE); + if (arenaobj->address == 0) { + /* The allocation failed: return NULL after putting the + * arenaobj back. + */ + arenaobj->nextarena = unused_arena_objects; + unused_arena_objects = arenaobj; + return NULL; + } + + ++narenas_currently_allocated; #ifdef PYMALLOC_DEBUG - ++ntimes_arena_allocated; - if (narenas_currently_allocated > narenas_highwater) - narenas_highwater = narenas_currently_allocated; + ++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; + 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; } /* @@ -622,11 +622,11 @@ 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 + B <= P < B + ARENA_SIZE Subtracting B throughout, this is true iff - 0 <= P-B < ARENA_SIZE + 0 <= P-B < ARENA_SIZE By using unsigned arithmetic, the "0 <=" half of the test can be skipped. @@ -660,7 +660,7 @@ 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 + 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 @@ -683,10 +683,10 @@ 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. */ -#define Py_ADDRESS_IN_RANGE(P, POOL) \ - ((POOL)->arenaindex < maxarenas && \ - (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \ - arenas[(POOL)->arenaindex].address != 0) +#define Py_ADDRESS_IN_RANGE(P, POOL) \ + ((POOL)->arenaindex < maxarenas && \ + (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \ + arenas[(POOL)->arenaindex].address != 0) /* This is only useful when running memory debuggers such as @@ -709,7 +709,7 @@ extremely desirable that it be this fast. #undef Py_ADDRESS_IN_RANGE #if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \ - (__GNUC__ >= 4)) + (__GNUC__ >= 4)) #define Py_NO_INLINE __attribute__((__noinline__)) #else #define Py_NO_INLINE @@ -738,201 +738,201 @@ int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE; void * PyObject_Malloc(size_t nbytes) { - block *bp; - poolp pool; - poolp next; - uint size; + 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; + 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. */ + /* + * 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; - } + 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. */ + 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); + /* 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 */ @@ -941,218 +941,218 @@ redirect: void PyObject_Free(void *p) { - poolp pool; - block *lastfree; - poolp next, prev; - uint size; + poolp pool; + block *lastfree; + poolp next, prev; + uint size; - if (p == NULL) /* free(NULL) has no effect */ - return; + if (p == NULL) /* free(NULL) has no effect */ + return; #ifdef WITH_VALGRIND - if (UNLIKELY(running_on_valgrind > 0)) - goto redirect; + 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. */ - free((void *)ao->address); - 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; - } + 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. */ + free((void *)ao->address); + 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); + /* We didn't allocate this address. */ + free(p); } /* realloc. If p is NULL, this acts like malloc(nbytes). Else if nbytes==0, @@ -1164,81 +1164,81 @@ redirect: void * PyObject_Realloc(void *p, size_t nbytes) { - void *bp; - poolp pool; - size_t size; - - 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; + void *bp; + poolp pool; + size_t size; + + 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; + /* 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; - } + 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; + /* 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 */ +#else /* ! WITH_PYMALLOC */ /*==========================================================================*/ /* pymalloc not enabled: Redirect the entry points to malloc. These will @@ -1247,19 +1247,19 @@ PyObject_Realloc(void *p, size_t nbytes) void * PyObject_Malloc(size_t n) { - return PyMem_MALLOC(n); + return PyMem_MALLOC(n); } void * PyObject_Realloc(void *p, size_t n) { - return PyMem_REALLOC(p, n); + return PyMem_REALLOC(p, n); } void PyObject_Free(void *p) { - PyMem_FREE(p); + PyMem_FREE(p); } #endif /* WITH_PYMALLOC */ @@ -1284,7 +1284,7 @@ PyObject_Free(void *p) #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 */ +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. @@ -1292,7 +1292,7 @@ static size_t serialno = 0; /* incremented on each debug {m,re}alloc */ static void bumpserialno(void) { - ++serialno; + ++serialno; } #define SST SIZEOF_SIZE_T @@ -1301,13 +1301,13 @@ bumpserialno(void) static size_t read_size_t(const void *p) { - const uchar *q = (const uchar *)p; - size_t result = *q++; - int i; + const uchar *q = (const uchar *)p; + size_t result = *q++; + int i; - for (i = SST; --i > 0; ++q) - result = (result << 8) | *q; - return result; + 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 @@ -1316,13 +1316,13 @@ read_size_t(const void *p) static void write_size_t(void *p, size_t n) { - uchar *q = (uchar *)p + SST - 1; - int i; + uchar *q = (uchar *)p + SST - 1; + int i; - for (i = SST; --i >= 0; --q) { - *q = (uchar)(n & 0xff); - n >>= 8; - } + for (i = SST; --i >= 0; --q) { + *q = (uchar)(n & 0xff); + n >>= 8; + } } #ifdef Py_DEBUG @@ -1333,22 +1333,22 @@ write_size_t(void *p, size_t n) 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; + 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 */ +#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: @@ -1378,39 +1378,39 @@ p[2*S+n+S: 2*S+n+2*S] void * _PyMem_DebugMalloc(size_t nbytes) { - return _PyObject_DebugMallocApi(_PYMALLOC_MEM_ID, nbytes); + return _PyObject_DebugMallocApi(_PYMALLOC_MEM_ID, nbytes); } void * _PyMem_DebugRealloc(void *p, size_t nbytes) { - return _PyObject_DebugReallocApi(_PYMALLOC_MEM_ID, p, nbytes); + return _PyObject_DebugReallocApi(_PYMALLOC_MEM_ID, p, nbytes); } void _PyMem_DebugFree(void *p) { - _PyObject_DebugFreeApi(_PYMALLOC_MEM_ID, 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); + return _PyObject_DebugMallocApi(_PYMALLOC_OBJ_ID, nbytes); } void * _PyObject_DebugRealloc(void *p, size_t nbytes) { - return _PyObject_DebugReallocApi(_PYMALLOC_OBJ_ID, p, nbytes); + return _PyObject_DebugReallocApi(_PYMALLOC_OBJ_ID, p, nbytes); } void _PyObject_DebugFree(void *p) { - _PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p); + _PyObject_DebugFreeApi(_PYMALLOC_OBJ_ID, p); } void _PyObject_DebugCheckAddress(const void *p) { - _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p); + _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p); } @@ -1418,34 +1418,34 @@ _PyObject_DebugCheckAddress(const void *p) 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; + 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 @@ -1456,68 +1456,68 @@ _PyObject_DebugMallocApi(char id, size_t nbytes) 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); + 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; + 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. @@ -1528,192 +1528,192 @@ _PyObject_DebugReallocApi(char api, void *p, size_t nbytes) 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; + 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); + _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); - } + 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; - uint digit = (uint)(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; + 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; + uint digit = (uint)(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. @@ -1723,142 +1723,142 @@ printone(const char* msg, size_t value) 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 poolsinarena; - uint j; - uptr base = arenas[i].address; - - /* Skip arenas which are not allocated. */ - if (arenas[i].address == (uptr)NULL) - continue; - narenas += 1; - - poolsinarena = arenas[i].ntotalpools; - 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; + 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 poolsinarena; + uint j; + uptr base = arenas[i].address; + + /* Skip arenas which are not allocated. */ + if (arenas[i].address == (uptr)NULL) + continue; + narenas += 1; + + poolsinarena = arenas[i].ntotalpools; + 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])); + 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); + } + } + 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 */ +#endif /* PYMALLOC_DEBUG */ #ifdef Py_USING_MEMORY_DEBUGGER /* Make this function last so gcc won't inline it since the definition is @@ -1867,8 +1867,8 @@ _PyObject_DebugMallocStats(void) int Py_ADDRESS_IN_RANGE(void *P, poolp pool) { - return pool->arenaindex < maxarenas && - (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE && - arenas[pool->arenaindex].address != 0; + return pool->arenaindex < maxarenas && + (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE && + arenas[pool->arenaindex].address != 0; } #endif diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index cd148c6667..e36469cd01 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -17,7 +17,7 @@ typedef struct { } rangeobject; /* Helper function for validating step. Always returns a new reference or - NULL on error. + NULL on error. */ static PyObject * validate_step(PyObject *step) @@ -269,7 +269,7 @@ range_repr(rangeobject *r) static PyObject * range_reduce(rangeobject *r, PyObject *args) { - return Py_BuildValue("(O(OOO))", Py_TYPE(r), + return Py_BuildValue("(O(OOO))", Py_TYPE(r), r->start, r->stop, r->step); } @@ -328,11 +328,11 @@ range_contains(rangeobject *r, PyObject *ob) { } static PySequenceMethods range_as_sequence = { - (lenfunc)range_length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ + (lenfunc)range_length, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ (ssizeargfunc)range_item, /* sq_item */ - 0, /* sq_slice */ + 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ (objobjproc)range_contains, /* sq_contains */ @@ -345,51 +345,51 @@ 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 */ + {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, + reverse_doc}, + {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyRange_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "range", /* Name of this type */ - sizeof(rangeobject), /* Basic object size */ - 0, /* Item size for varobject */ - (destructor)range_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "range", /* Name of this type */ + sizeof(rangeobject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)range_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ }; /*********************** range Iterator **************************/ @@ -400,18 +400,18 @@ PyTypeObject PyRange_Type = { */ typedef struct { - PyObject_HEAD - long index; - long start; - long step; - long len; + PyObject_HEAD + long index; + long start; + long step; + long len; } rangeiterobject; static PyObject * rangeiter_next(rangeiterobject *r) { if (r->index < r->len) - /* cast to unsigned to avoid possible signed overflow + /* cast to unsigned to avoid possible signed overflow in intermediate calculations. */ return PyLong_FromLong((long)(r->start + (unsigned long)(r->index++) * r->step)); @@ -445,50 +445,50 @@ PyDoc_STRVAR(length_hint_doc, static PyMethodDef rangeiter_methods[] = { {"__length_hint__", (PyCFunction)rangeiter_len, METH_NOARGS, - length_hint_doc}, - {NULL, NULL} /* sentinel */ + length_hint_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyRangeIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "range_iterator", /* 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_reserved */ - 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, /* 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 */ - rangeiter_new, /* tp_new */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "range_iterator", /* 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_reserved */ + 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, /* 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 */ + rangeiter_new, /* tp_new */ }; /* Return number of items in range (lo, hi, step). step != 0 @@ -560,8 +560,8 @@ rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) static PyMethodDef longrangeiter_methods[] = { {"__length_hint__", (PyCFunction)longrangeiter_len, METH_NOARGS, - length_hint_doc}, - {NULL, NULL} /* sentinel */ + length_hint_doc}, + {NULL, NULL} /* sentinel */ }; static void @@ -610,36 +610,36 @@ longrangeiter_next(longrangeiterobject *r) } PyTypeObject PyLongRangeIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "longrange_iterator", /* tp_name */ - sizeof(longrangeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)longrangeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 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)longrangeiter_next, /* tp_iternext */ - longrangeiter_methods, /* tp_methods */ - 0, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "longrange_iterator", /* tp_name */ + sizeof(longrangeiterobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)longrangeiter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 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)longrangeiter_next, /* tp_iternext */ + longrangeiter_methods, /* tp_methods */ + 0, }; static PyObject * diff --git a/Objects/setobject.c b/Objects/setobject.c index aaa483878e..b35fef5ed6 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1,5 +1,5 @@ -/* set object implementation +/* set object implementation Written and maintained by Raymond D. Hettinger Derived from Lib/sets.py and Objects/dictobject.c. @@ -17,12 +17,12 @@ 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); + 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. */ @@ -35,20 +35,20 @@ static PyObject *dummy = NULL; /* Initialized by first call to make_new_set() */ PyObject * _PySet_Dummy(void) { - return dummy; + return dummy; } #endif -#define INIT_NONZERO_SET_SLOTS(so) do { \ - (so)->table = (so)->smalltable; \ - (so)->mask = PySet_MINSIZE - 1; \ - (so)->hash = -1; \ +#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); \ +#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 */ @@ -77,78 +77,78 @@ 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; + 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; } /* @@ -159,50 +159,50 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash) static setentry * set_lookkey_unicode(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-unicode 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 (!PyUnicode_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 && unicode_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 - && unicode_eq(entry->key, key))) - return entry; - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - } - assert(0); /* NOT REACHED */ - return 0; + 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-unicode 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 (!PyUnicode_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 && unicode_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 + && unicode_eq(entry->key, key))) + return entry; + if (entry->key == dummy && freeslot == NULL) + freeslot = entry; + } + assert(0); /* NOT REACHED */ + return 0; } /* @@ -213,30 +213,30 @@ Eats a reference to key. static int set_insert_key(register PySetObject *so, PyObject *key, long hash) { - register setentry *entry; - typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long); - - 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; + register setentry *entry; + typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long); + + 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; } /* @@ -250,22 +250,22 @@ 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; + 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++; + 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++; } /* @@ -276,86 +276,86 @@ 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; + 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 */ @@ -363,42 +363,42 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) static int set_add_entry(register PySetObject *so, setentry *entry) { - register Py_ssize_t n_used; + register Py_ssize_t n_used; - assert(so->fill <= so->mask); /* at least one empty slot */ - n_used = so->used; - Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, entry->hash) == -1) { - Py_DECREF(entry->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); + assert(so->fill <= so->mask); /* at least one empty slot */ + n_used = so->used; + Py_INCREF(entry->key); + if (set_insert_key(so, entry->key, entry->hash) == -1) { + Py_DECREF(entry->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 (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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); + register long hash; + register Py_ssize_t n_used; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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 @@ -406,112 +406,112 @@ set_add_key(register PySetObject *so, PyObject *key) 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; +{ 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 (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + register long hash; + register setentry *entry; + PyObject *old_key; + + assert (PyAnySet_Check(so)); + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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]; + 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)); + Py_ssize_t i, n; + assert (PyAnySet_Check(so)); - n = so->mask + 1; - i = 0; + 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) { + 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; + assert(i < n); + ++i; #endif - if (entry->key) { - --fill; - Py_DECREF(entry->key); - } + if (entry->key) { + --fill; + Py_DECREF(entry->key); + } #ifdef Py_DEBUG - else - assert(entry->key == NULL); + else + assert(entry->key == NULL); #endif - } + } - if (table_is_malloced) - PyMem_DEL(table); - return 0; + if (table_is_malloced) + PyMem_DEL(table); + return 0; } /* @@ -525,223 +525,223 @@ set_clear_internal(PySetObject *so) * } * * CAUTION: In general, it isn't safe to use set_next in a loop that - * mutates the table. + * 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; + 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) + 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 PyObject * set_repr(PySetObject *so) { - PyObject *keys, *result=NULL; - Py_UNICODE *u; - int status = Py_ReprEnter((PyObject*)so); - PyObject *listrepr; - Py_ssize_t newsize; - - if (status != 0) { - if (status < 0) - return NULL; - return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name); - } - - /* shortcut for the empty set */ - if (!so->used) { - Py_ReprLeave((PyObject*)so); - return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name); - } - - keys = PySequence_List((PyObject *)so); - if (keys == NULL) - goto done; - - listrepr = PyObject_Repr(keys); - Py_DECREF(keys); - if (listrepr == NULL) - goto done; - newsize = PyUnicode_GET_SIZE(listrepr); - result = PyUnicode_FromUnicode(NULL, newsize); - if (result) { - u = PyUnicode_AS_UNICODE(result); - *u++ = '{'; - /* Omit the brackets from the listrepr */ - Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1, - PyUnicode_GET_SIZE(listrepr)-2); - u += newsize-2; - *u++ = '}'; - } - Py_DECREF(listrepr); - if (Py_TYPE(so) != &PySet_Type) { - PyObject *tmp = PyUnicode_FromFormat("%s(%U)", - Py_TYPE(so)->tp_name, - result); - Py_DECREF(result); - result = tmp; - } + PyObject *keys, *result=NULL; + Py_UNICODE *u; + int status = Py_ReprEnter((PyObject*)so); + PyObject *listrepr; + Py_ssize_t newsize; + + if (status != 0) { + if (status < 0) + return NULL; + return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name); + } + + /* shortcut for the empty set */ + if (!so->used) { + Py_ReprLeave((PyObject*)so); + return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name); + } + + keys = PySequence_List((PyObject *)so); + if (keys == NULL) + goto done; + + listrepr = PyObject_Repr(keys); + Py_DECREF(keys); + if (listrepr == NULL) + goto done; + newsize = PyUnicode_GET_SIZE(listrepr); + result = PyUnicode_FromUnicode(NULL, newsize); + if (result) { + u = PyUnicode_AS_UNICODE(result); + *u++ = '{'; + /* Omit the brackets from the listrepr */ + Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1, + PyUnicode_GET_SIZE(listrepr)-2); + u += newsize-2; + *u++ = '}'; + } + Py_DECREF(listrepr); + if (Py_TYPE(so) != &PySet_Type) { + PyObject *tmp = PyUnicode_FromFormat("%s(%U)", + Py_TYPE(so)->tp_name, + result); + Py_DECREF(result); + result = tmp; + } done: - Py_ReprLeave((PyObject*)so); - return result; + Py_ReprLeave((PyObject*)so); + return result; } static Py_ssize_t set_len(PyObject *so) { - return ((PySetObject *)so)->used; + return ((PySetObject *)so)->used; } static int set_merge(PySetObject *so, PyObject *otherset) { - PySetObject *other; - 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]; - if (entry->key != NULL && - entry->key != dummy) { - Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, entry->hash) == -1) { - Py_DECREF(entry->key); - return -1; - } - } - } - return 0; + PySetObject *other; + 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]; + if (entry->key != NULL && + entry->key != dummy) { + Py_INCREF(entry->key); + if (set_insert_key(so, entry->key, entry->hash) == -1) { + Py_DECREF(entry->key); + return -1; + } + } + } + return 0; } static int set_contains_key(PySetObject *so, PyObject *key) { - long hash; - setentry *entry; + long hash; + setentry *entry; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyUnicodeObject *) key)->hash) == -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; + if (!PyUnicode_CheckExact(key) || + (hash = ((PyUnicodeObject *) key)->hash) == -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; + 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; + 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; + 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\ @@ -750,289 +750,289 @@ Raises KeyError if the set is empty."); static int set_traverse(PySetObject *so, visitproc visit, void *arg) { - Py_ssize_t pos = 0; - setentry *entry; + Py_ssize_t pos = 0; + setentry *entry; - while (set_next(so, &pos, &entry)) - Py_VISIT(entry->key); - return 0; + 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; + 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; + 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); + 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; + 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 PyLong_FromLong(len); + Py_ssize_t len = 0; + if (si->si_set != NULL && si->si_used == si->si_set->used) + len = si->len; + return PyLong_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 */ + {"__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; + 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; + Py_DECREF(so); + si->si_set = NULL; + return NULL; } PyTypeObject PySetIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "set_iterator", /* 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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "set_iterator", /* 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_reserved */ + 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; + 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; + 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; + Py_ssize_t i; - for (i=0 ; i"); - 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_unicode; - so->weakreflist = NULL; - - if (iterable != NULL) { - if (set_update_internal(so, iterable) == -1) { - Py_DECREF(so); - return NULL; - } - } - - return (PyObject *)so; + register PySetObject *so = NULL; + + if (dummy == NULL) { /* Auto-initialize dummy */ + dummy = PyUnicode_FromString(""); + 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_unicode; + so->weakreflist = NULL; + + if (iterable != NULL) { + if (set_update_internal(so, iterable) == -1) { + Py_DECREF(so); + return NULL; + } + } + + return (PyObject *)so; } static PyObject * make_new_set_basetype(PyTypeObject *type, PyObject *iterable) { - if (type != &PySet_Type && type != &PyFrozenSet_Type) { - if (PyType_IsSubtype(type, &PySet_Type)) - type = &PySet_Type; - else - type = &PyFrozenSet_Type; - } - return make_new_set(type, iterable); + if (type != &PySet_Type && type != &PyFrozenSet_Type) { + if (PyType_IsSubtype(type, &PySet_Type)) + type = &PySet_Type; + else + type = &PyFrozenSet_Type; + } + return make_new_set(type, iterable); } /* The empty frozenset is a singleton */ @@ -1041,56 +1041,56 @@ static PyObject *emptyfrozenset = NULL; static PyObject * frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *iterable = NULL, *result; + PyObject *iterable = NULL, *result; - if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds)) - return NULL; + if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds)) + return NULL; - if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) - 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 (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; + 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; + PySetObject *so; - while (numfree) { - numfree--; - so = free_list[numfree]; - PyObject_GC_Del(so); - } - Py_CLEAR(dummy); - Py_CLEAR(emptyfrozenset); + 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); + 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 @@ -1100,64 +1100,64 @@ set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 + 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 + 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; - } + 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_basetype(Py_TYPE(so), (PyObject *)so); + return make_new_set_basetype(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); + 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."); @@ -1165,8 +1165,8 @@ PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set."); static PyObject * set_clear(PySetObject *so) { - set_clear_internal(so); - Py_RETURN_NONE; + set_clear_internal(so); + Py_RETURN_NONE; } PyDoc_STRVAR(clear_doc, "Remove all elements from this set."); @@ -1174,24 +1174,24 @@ 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; + PySetObject *result; + PyObject *other; + Py_ssize_t i; - result = (PySetObject *)set_copy(so); - if (result == NULL) - return NULL; + result = (PySetObject *)set_copy(so); + if (result == NULL) + return NULL; - for (i=0 ; i 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; + PySetObject *result; + PyObject *key, *it, *tmp; + + if ((PyObject *)so == other) + return set_copy(so); + + result = (PySetObject *)make_new_set_basetype(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; + Py_ssize_t i; + PyObject *result = (PyObject *)so; - if (PyTuple_GET_SIZE(args) == 0) - return set_copy(so); + if (PyTuple_GET_SIZE(args) == 0) + return set_copy(so); - Py_INCREF(so); - for (i=0 ; i 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; + 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, @@ -1471,51 +1471,51 @@ PyDoc_STRVAR(isdisjoint_doc, 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); + 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; + Py_ssize_t i; - for (i=0 ; ihash; - 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; + 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_basetype(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; + Py_ssize_t i; + PyObject *result, *other; - if (PyTuple_GET_SIZE(args) == 0) - return set_copy(so); + 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; + other = PyTuple_GET_ITEM(args, 0); + result = set_difference(so, other); + if (result == NULL) + return NULL; - for (i=1 ; i 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; + 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."); @@ -1765,17 +1765,17 @@ PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set."); static PyObject * set_issuperset(PySetObject *so, PyObject *other) { - PyObject *tmp, *result; + 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); + 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."); @@ -1783,54 +1783,54 @@ 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; + 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 PyObject * set_add(PySetObject *so, PyObject *key) { - if (set_add_key(so, key) == -1) - return NULL; - Py_RETURN_NONE; + if (set_add_key(so, key) == -1) + return NULL; + Py_RETURN_NONE; } -PyDoc_STRVAR(add_doc, +PyDoc_STRVAR(add_doc, "Add an element to a set.\n\ \n\ This has no effect if the element is already present."); @@ -1838,34 +1838,34 @@ 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, NULL); - if (tmpkey == NULL) - return -1; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - rv = set_contains(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - Py_DECREF(tmpkey); - } - return rv; + 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, NULL); + if (tmpkey == NULL) + return -1; + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + rv = set_contains(so, tmpkey); + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + Py_DECREF(tmpkey); + } + return rv; } static PyObject * set_direct_contains(PySetObject *so, PyObject *key) { - long result; + long result; - result = set_contains(so, key); - if (result == -1) - return NULL; - return PyBool_FromLong(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."); @@ -1873,30 +1873,30 @@ 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, NULL); - if (tmpkey == NULL) - return NULL; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - rv = set_discard_key(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - Py_DECREF(tmpkey); - if (rv == -1) - return NULL; - } - - if (rv == DISCARD_NOTFOUND) { - set_key_error(key); - return NULL; - } - Py_RETURN_NONE; + 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, NULL); + if (tmpkey == NULL) + return NULL; + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + rv = set_discard_key(so, tmpkey); + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + 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, @@ -1907,54 +1907,54 @@ If the element is not a member, raise a KeyError."); static PyObject * set_discard(PySetObject *so, PyObject *key) { - PyObject *tmpkey, *result; - 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, NULL); - if (tmpkey == NULL) - return NULL; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - result = set_discard(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); - Py_DECREF(tmpkey); - return result; - } - Py_RETURN_NONE; + PyObject *tmpkey, *result; + 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, NULL); + if (tmpkey == NULL) + return NULL; + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + result = set_discard(so, tmpkey); + set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); + Py_DECREF(tmpkey); + return result; + } + 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."); +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); + 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; + Py_XDECREF(args); + Py_XDECREF(keys); + Py_XDECREF(dict); + return result; } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -1962,42 +1962,42 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyObject * set_sizeof(PySetObject *so) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PySetObject); - if (so->table != so->smalltable) - res = res + (so->mask + 1) * sizeof(setentry); - return PyLong_FromSsize_t(res); + res = sizeof(PySetObject); + if (so->table != so->smalltable) + res = res + (so->mask + 1) * sizeof(setentry); + return PyLong_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; + 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); + 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_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 ********************************************************/ @@ -2010,83 +2010,83 @@ 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}, + {"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}, + {"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 */ + {"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_remainder*/ - 0, /*nb_divmod*/ - 0, /*nb_power*/ - 0, /*nb_negative*/ - 0, /*nb_positive*/ - 0, /*nb_absolute*/ - 0, /*nb_bool*/ - 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_int*/ - 0, /*nb_reserved*/ - 0, /*nb_float*/ - 0, /*nb_inplace_add*/ - (binaryfunc)set_isub, /*nb_inplace_subtract*/ - 0, /*nb_inplace_multiply*/ - 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*/ + 0, /*nb_add*/ + (binaryfunc)set_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 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_int*/ + 0, /*nb_reserved*/ + 0, /*nb_float*/ + 0, /*nb_inplace_add*/ + (binaryfunc)set_isub, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 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, @@ -2096,95 +2096,95 @@ set(iterable) -> new set object\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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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_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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "set", /* tp_name */ + sizeof(PySetObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)set_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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_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 */ + {"__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_remainder*/ - 0, /*nb_divmod*/ - 0, /*nb_power*/ - 0, /*nb_negative*/ - 0, /*nb_positive*/ - 0, /*nb_absolute*/ - 0, /*nb_bool*/ - 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_add*/ + (binaryfunc)set_sub, /*nb_subtract*/ + 0, /*nb_multiply*/ + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_bool*/ + 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, @@ -2194,47 +2194,47 @@ frozenset(iterable) -> frozenset object\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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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_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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "frozenset", /* tp_name */ + sizeof(PySetObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)set_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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_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 */ }; @@ -2243,238 +2243,238 @@ PyTypeObject PyFrozenSet_Type = { PyObject * PySet_New(PyObject *iterable) { - return make_new_set(&PySet_Type, iterable); + return make_new_set(&PySet_Type, iterable); } PyObject * PyFrozenSet_New(PyObject *iterable) { - return make_new_set(&PyFrozenSet_Type, 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); + 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); + 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); + 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); + 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); + if (!PySet_Check(anyset) && + (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) { + PyErr_BadInternalCall(); + return -1; + } + return set_add_key((PySetObject *)anyset, key); } int _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash) { - setentry *entry; + 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; + 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); + 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); + 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. +/* 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) +#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; - long hash; - PyObject *str; - - /* Verify preconditions */ - assert(PyAnySet_Check(ob)); - assert(PyAnySet_CheckExact(ob)); - assert(!PyFrozenSet_CheckExact(ob)); - - /* so.clear(); so |= set("abc"); */ - str = PyUnicode_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_NextEntry((PyObject *)dup, &i, &x, &hash)) { - s = _PyUnicode_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; + Py_ssize_t count; + char *s; + Py_ssize_t i; + PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x; + PyObject *ob = (PyObject *)so; + long hash; + PyObject *str; + + /* Verify preconditions */ + assert(PyAnySet_Check(ob)); + assert(PyAnySet_CheckExact(ob)); + assert(!PyFrozenSet_CheckExact(ob)); + + /* so.clear(); so |= set("abc"); */ + str = PyUnicode_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_NextEntry((PyObject *)dup, &i, &x, &hash)) { + s = _PyUnicode_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 diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 9acd7f7763..ee89006688 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -7,7 +7,7 @@ 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. @@ -19,35 +19,35 @@ this type and there is exactly one in existence. static PyObject * ellipsis_repr(PyObject *op) { - return PyUnicode_FromString("Ellipsis"); + return PyUnicode_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_reserved */ - 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 */ + 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_reserved */ + 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 + _PyObject_EXTRA_INIT + 1, &PyEllipsis_Type }; @@ -60,154 +60,154 @@ PyObject _Py_EllipsisObject = { PyObject * PySlice_New(PyObject *start, PyObject *stop, PyObject *step) { - PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type); + PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type); - if (obj == NULL) - return NULL; + 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); + 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; + obj->step = step; + obj->start = start; + obj->stop = stop; - return (PyObject *) obj; + return (PyObject *) obj; } PyObject * _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop) { - PyObject *start, *end, *slice; - start = PyLong_FromSsize_t(istart); - if (!start) - return NULL; - end = PyLong_FromSsize_t(istop); - if (!end) { - Py_DECREF(start); - return NULL; - } - - slice = PySlice_New(start, end, NULL); - Py_DECREF(start); - Py_DECREF(end); - return slice; + PyObject *start, *end, *slice; + start = PyLong_FromSsize_t(istart); + if (!start) + return NULL; + end = PyLong_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 (!PyLong_Check(r->step)) return -1; - *step = PyLong_AsSsize_t(r->step); - } - if (r->start == Py_None) { - *start = *step < 0 ? length-1 : 0; - } else { - if (!PyLong_Check(r->start)) return -1; - *start = PyLong_AsSsize_t(r->start); - if (*start < 0) *start += length; - } - if (r->stop == Py_None) { - *stop = *step < 0 ? -1 : length; - } else { - if (!PyLong_Check(r->stop)) return -1; - *stop = PyLong_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; + /* XXX support long ints */ + if (r->step == Py_None) { + *step = 1; + } else { + if (!PyLong_Check(r->step)) return -1; + *step = PyLong_AsSsize_t(r->step); + } + if (r->start == Py_None) { + *start = *step < 0 ? length-1 : 0; + } else { + if (!PyLong_Check(r->start)) return -1; + *start = PyLong_AsSsize_t(r->start); + if (*start < 0) *start += length; + } + if (r->stop == Py_None) { + *stop = *step < 0 ? -1 : length; + } else { + if (!PyLong_Check(r->stop)) return -1; + *stop = PyLong_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) + 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; + /* 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; + PyObject *start, *stop, *step; - start = stop = step = NULL; + start = stop = step = NULL; - if (!_PyArg_NoKeywords("slice()", kw)) - return NULL; + if (!_PyArg_NoKeywords("slice()", kw)) + return NULL; - if (!PyArg_UnpackTuple(args, "slice", 1, 3, &start, &stop, &step)) - 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); + /* 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, @@ -218,42 +218,42 @@ 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); + Py_DECREF(r->step); + Py_DECREF(r->start); + Py_DECREF(r->stop); + PyObject_Del(r); } static PyObject * slice_repr(PySliceObject *r) { - return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step); + return PyUnicode_FromFormat("slice(%R, %R, %R)", r->start, r->stop, r->step); } 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} + {"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; + Py_ssize_t ilen, start, stop, step, slicelength; - ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); + ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); - if (ilen == -1 && PyErr_Occurred()) { - return NULL; - } + if (ilen == -1 && PyErr_Occurred()) { + return NULL; + } - if (PySlice_GetIndicesEx(self, ilen, &start, &stop, - &step, &slicelength) < 0) { - return NULL; - } + if (PySlice_GetIndicesEx(self, ilen, &start, &stop, + &step, &slicelength) < 0) { + return NULL; + } - return Py_BuildValue("(nnn)", start, stop, step); + return Py_BuildValue("(nnn)", start, stop, step); } PyDoc_STRVAR(slice_indices_doc, @@ -267,119 +267,119 @@ handling of normal slices."); static PyObject * slice_reduce(PySliceObject* self) { - return Py_BuildValue("O(OOO)", Py_TYPE(self), self->start, self->stop, self->step); + 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} + {"indices", (PyCFunction)slice_indices, + METH_O, slice_indices_doc}, + {"__reduce__", (PyCFunction)slice_reduce, + METH_NOARGS, reduce_doc}, + {NULL, NULL} }; static PyObject * slice_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *t1; - PyObject *t2; - PyObject *res; - - if (!PySlice_Check(v) || !PySlice_Check(w)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (v == w) { - /* XXX Do we really need this shortcut? - There's a unit test for it, but is that fair? */ - switch (op) { - case Py_EQ: - case Py_LE: - case Py_GE: - res = Py_True; - break; - default: - res = Py_False; - break; - } - Py_INCREF(res); - return res; - } - - t1 = PyTuple_New(3); - t2 = PyTuple_New(3); - if (t1 == NULL || t2 == NULL) - return NULL; - - PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start); - PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop); - PyTuple_SET_ITEM(t1, 2, ((PySliceObject *)v)->step); - PyTuple_SET_ITEM(t2, 0, ((PySliceObject *)w)->start); - PyTuple_SET_ITEM(t2, 1, ((PySliceObject *)w)->stop); - PyTuple_SET_ITEM(t2, 2, ((PySliceObject *)w)->step); - - res = PyObject_RichCompare(t1, t2, op); - - PyTuple_SET_ITEM(t1, 0, NULL); - PyTuple_SET_ITEM(t1, 1, NULL); - PyTuple_SET_ITEM(t1, 2, NULL); - PyTuple_SET_ITEM(t2, 0, NULL); - PyTuple_SET_ITEM(t2, 1, NULL); - PyTuple_SET_ITEM(t2, 2, NULL); - - Py_DECREF(t1); - Py_DECREF(t2); - - return res; + PyObject *t1; + PyObject *t2; + PyObject *res; + + if (!PySlice_Check(v) || !PySlice_Check(w)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + if (v == w) { + /* XXX Do we really need this shortcut? + There's a unit test for it, but is that fair? */ + switch (op) { + case Py_EQ: + case Py_LE: + case Py_GE: + res = Py_True; + break; + default: + res = Py_False; + break; + } + Py_INCREF(res); + return res; + } + + t1 = PyTuple_New(3); + t2 = PyTuple_New(3); + if (t1 == NULL || t2 == NULL) + return NULL; + + PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start); + PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop); + PyTuple_SET_ITEM(t1, 2, ((PySliceObject *)v)->step); + PyTuple_SET_ITEM(t2, 0, ((PySliceObject *)w)->start); + PyTuple_SET_ITEM(t2, 1, ((PySliceObject *)w)->stop); + PyTuple_SET_ITEM(t2, 2, ((PySliceObject *)w)->step); + + res = PyObject_RichCompare(t1, t2, op); + + PyTuple_SET_ITEM(t1, 0, NULL); + PyTuple_SET_ITEM(t1, 1, NULL); + PyTuple_SET_ITEM(t1, 2, NULL); + PyTuple_SET_ITEM(t2, 0, NULL); + PyTuple_SET_ITEM(t2, 1, NULL); + PyTuple_SET_ITEM(t2, 2, NULL); + + Py_DECREF(t1); + Py_DECREF(t2); + + return res; } static long slice_hash(PySliceObject *v) { - PyErr_SetString(PyExc_TypeError, "unhashable type"); - return -1L; + 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 */ - 0, /* tp_reserved */ - (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 */ - slice_richcompare, /* 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 */ + 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 */ + 0, /* tp_reserved */ + (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 */ + slice_richcompare, /* 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/Objects/stringlib/eq.h b/Objects/stringlib/eq.h index 4e989dce6d..3e7f5e86c6 100644 --- a/Objects/stringlib/eq.h +++ b/Objects/stringlib/eq.h @@ -6,16 +6,16 @@ Py_LOCAL_INLINE(int) unicode_eq(PyObject *aa, PyObject *bb) { - register PyUnicodeObject *a = (PyUnicodeObject *)aa; - register PyUnicodeObject *b = (PyUnicodeObject *)bb; + register PyUnicodeObject *a = (PyUnicodeObject *)aa; + register PyUnicodeObject *b = (PyUnicodeObject *)bb; - if (a->length != b->length) - return 0; - if (a->length == 0) - return 1; - if (a->str[0] != b->str[0]) - return 0; - if (a->length == 1) - return 1; - return memcmp(a->str, b->str, a->length * sizeof(Py_UNICODE)) == 0; + if (a->length != b->length) + return 0; + if (a->length == 0) + return 1; + if (a->str[0] != b->str[0]) + return 0; + if (a->length == 1) + return 1; + return memcmp(a->str, b->str, a->length * sizeof(Py_UNICODE)) == 0; } diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 539feaee18..ecb00a9a1e 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -563,36 +563,36 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output) 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; + format_spec->ptr : NULL; Py_ssize_t format_spec_len = format_spec->ptr ? - format_spec->end - format_spec->ptr : 0; + 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 (PyUnicode_CheckExact(fieldobj)) - formatter = _PyUnicode_FormatAdvanced; + formatter = _PyUnicode_FormatAdvanced; else if (PyLong_CheckExact(fieldobj)) - formatter =_PyLong_FormatAdvanced; + formatter =_PyLong_FormatAdvanced; else if (PyFloat_CheckExact(fieldobj)) - formatter = _PyFloat_FormatAdvanced; + formatter = _PyFloat_FormatAdvanced; /* XXX: for 2.6, convert format_spec to the appropriate type (unicode, str) */ 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); + /* 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); + /* 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; @@ -605,11 +605,11 @@ render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output) /* 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; + PyObject *tmp = STRINGLIB_TOSTR(result); + if (tmp == NULL) + goto done; + Py_DECREF(result); + result = tmp; } #endif @@ -844,17 +844,17 @@ do_conversion(PyObject *obj, STRINGLIB_CHAR conversion) return STRINGLIB_TOASCII(obj); #endif 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, + 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); + } else + PyErr_Format(PyExc_ValueError, + "Unknown conversion specifier \\x%x", + (unsigned int)conversion); return NULL; } } @@ -1119,7 +1119,7 @@ formatteriter_next(formatteriterobject *it) Py_INCREF(conversion_str); } else - conversion_str = STRINGLIB_NEW(&conversion, 1); + conversion_str = STRINGLIB_NEW(&conversion, 1); if (conversion_str == NULL) goto done; @@ -1135,39 +1135,39 @@ formatteriter_next(formatteriterobject *it) } static PyMethodDef formatteriter_methods[] = { - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; static PyTypeObject PyFormatterIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "formatteriterator", /* tp_name */ - sizeof(formatteriterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ + "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_reserved */ - 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 */ + (destructor)formatteriter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 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, }; @@ -1268,39 +1268,39 @@ fieldnameiter_next(fieldnameiterobject *it) } static PyMethodDef fieldnameiter_methods[] = { - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; static PyTypeObject PyFieldNameIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "fieldnameiterator", /* tp_name */ - sizeof(fieldnameiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ + "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_reserved */ - 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 */ + (destructor)fieldnameiter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 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 diff --git a/Objects/structseq.c b/Objects/structseq.c index 54c8deb57f..7031225cb0 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -9,7 +9,7 @@ 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. +/* 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"; @@ -29,511 +29,511 @@ char *PyStructSequence_UnnamedField = "unnamed field"; PyObject * PyStructSequence_New(PyTypeObject *type) { - PyStructSequence *obj; + PyStructSequence *obj; - obj = PyObject_New(PyStructSequence, type); - if (obj == NULL) - return NULL; - Py_SIZE(obj) = VISIBLE_SIZE_TP(type); + obj = PyObject_New(PyStructSequence, type); + if (obj == NULL) + return NULL; + Py_SIZE(obj) = VISIBLE_SIZE_TP(type); - return (PyObject*) obj; + return (PyObject*) obj; } static void structseq_dealloc(PyStructSequence *obj) { - Py_ssize_t i, size; + Py_ssize_t i, size; - size = REAL_SIZE(obj); - for (i = 0; i < size; ++i) { - Py_XDECREF(obj->ob_item[i]); - } - PyObject_Del(obj); + 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); + 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]; + 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; + 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; - } + 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) { - 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; + 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) { + 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)); + return structseq_slice(obj, 0, VISIBLE_SIZE(obj)); } static PyObject * structseq_repr(PyStructSequence *obj) { - /* buffer and type size were chosen well considered. */ + /* 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 = _PyUnicode_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 PyUnicode_FromString(buf); + 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 = _PyUnicode_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 PyUnicode_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; + 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; + 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; + 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; + 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; + 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; + 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 */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)structseq_contains, /* sq_contains */ + (lenfunc)structseq_length, + (binaryfunc)structseq_concat, /* sq_concat */ + (ssizeargfunc)structseq_repeat, /* sq_repeat */ + (ssizeargfunc)structseq_item, /* sq_item */ + 0, /* 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, + (lenfunc)structseq_length, + (binaryfunc)structseq_subscript, }; static PyMethodDef structseq_methods[] = { - {"__reduce__", (PyCFunction)structseq_reduce, - METH_NOARGS, NULL}, - {NULL, NULL} + {"__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_reserved */ - (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 */ + 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_reserved */ + (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; + 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_base.ob_base._ob_next) { - _Py_ForgetReference((PyObject*)type); - } + /* if the type object was chained, unchain it first + before overwriting its storage */ + if (type->ob_base.ob_base._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 = PyLong_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); + 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 = PyLong_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/Objects/tupleobject.c b/Objects/tupleobject.c index 9145b58806..aa3be821bb 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -5,9 +5,9 @@ /* Speed optimization to avoid frequent malloc/free of small tuples */ #ifndef PyTuple_MAXSAVESIZE -#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */ +#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */ #endif -#ifndef PyTuple_MAXFREELIST +#ifndef PyTuple_MAXFREELIST #define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */ #endif @@ -35,12 +35,12 @@ 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))); + 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 @@ -48,161 +48,161 @@ show_track(void) PyObject * PyTuple_New(register Py_ssize_t size) { - register PyTupleObject *op; - Py_ssize_t i; - if (size < 0) { - PyErr_BadInternalCall(); - return NULL; - } + 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); + if (size == 0 && free_list[0]) { + op = free_list[0]; + Py_INCREF(op); #ifdef COUNT_ALLOCS - tuple_zero_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]--; + 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++; + fast_tuple_allocs++; #endif - /* Inline PyObject_InitVar */ + /* Inline PyObject_InitVar */ #ifdef Py_TRACE_REFS - Py_SIZE(op) = size; - Py_TYPE(op) = &PyTuple_Type; + Py_SIZE(op) = size; + Py_TYPE(op) = &PyTuple_Type; #endif - _Py_NewReference((PyObject *)op); - } - else + _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(); - } - nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); - - op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); - if (op == NULL) - return NULL; - } - for (i=0; i < size; i++) - op->ob_item[i] = NULL; + { + 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(); + } + nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); + + 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 */ - } + 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++; + count_tracked++; #endif - _PyObject_GC_TRACK(op); - return (PyObject *) op; + _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); + 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]; + 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; + 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; - } + 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++; + count_tracked--; + count_untracked++; #endif - _PyObject_GC_UNTRACK(op); + _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) - 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; + Py_ssize_t i; + PyObject *o; + PyObject *result; + PyObject **items; + va_list vargs; + + va_start(vargs, n); + result = PyTuple_New(n); + if (result == NULL) + 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; } @@ -211,405 +211,405 @@ PyTuple_Pack(Py_ssize_t n, ...) 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]); + 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 */ - } + 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); + } + Py_TYPE(op)->tp_free((PyObject *)op); done: - Py_TRASHCAN_SAFE_END(op) + Py_TRASHCAN_SAFE_END(op) } 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 PyUnicode_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 ? PyUnicode_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 = PyUnicode_FromString("("); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyTuple_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyUnicode_FromString(n == 1 ? ",)" : ")"); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, n-1); - PyUnicode_AppendAndDel(&temp, s); - PyTuple_SET_ITEM(pieces, n-1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); + Py_ssize_t i, n; + PyObject *s, *temp; + PyObject *pieces, *result = NULL; + + n = Py_SIZE(v); + if (n == 0) + return PyUnicode_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 ? PyUnicode_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 = PyUnicode_FromString("("); + if (s == NULL) + goto Done; + temp = PyTuple_GET_ITEM(pieces, 0); + PyUnicode_AppendAndDel(&s, temp); + PyTuple_SET_ITEM(pieces, 0, s); + if (s == NULL) + goto Done; + + s = PyUnicode_FromString(n == 1 ? ",)" : ")"); + if (s == NULL) + goto Done; + temp = PyTuple_GET_ITEM(pieces, n-1); + PyUnicode_AppendAndDel(&temp, s); + PyTuple_SET_ITEM(pieces, n-1, temp); + if (temp == NULL) + goto Done; + + /* Paste them all together with ", " between. */ + s = PyUnicode_FromString(", "); + if (s == NULL) + goto Done; + result = PyUnicode_Join(s, pieces); + Py_DECREF(s); Done: - Py_DECREF(pieces); - Py_ReprLeave((PyObject *)v); - return result; + 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 +/* 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, + 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; + 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); + return Py_SIZE(a); } static int tuplecontains(PyTupleObject *a, PyObject *el) { - Py_ssize_t i; - int cmp; + 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; + 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]; + 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) +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; + 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); + 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; - } + 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; + 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; + 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 PyLong_FromSsize_t(i); - else if (cmp < 0) - return NULL; - } - PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple"); - return NULL; + 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 PyLong_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 PyLong_FromSsize_t(count); + 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 PyLong_FromSsize_t(count); } static int tupletraverse(PyTupleObject *o, visitproc visit, void *arg) { - Py_ssize_t i; + Py_ssize_t i; - for (i = Py_SIZE(o); --i >= 0; ) - Py_VISIT(o->ob_item[i]); - return 0; + 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); + 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 * @@ -618,41 +618,41 @@ 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); + 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; + 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, @@ -662,86 +662,86 @@ tuple(iterable) -> tuple initialized from iterable's items\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 */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)tuplecontains, /* sq_contains */ + (lenfunc)tuplelength, /* sq_length */ + (binaryfunc)tupleconcat, /* sq_concat */ + (ssizeargfunc)tuplerepeat, /* sq_repeat */ + (ssizeargfunc)tupleitem, /* sq_item */ + 0, /* 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; - } + 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))); - + return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v))); + } static PyObject * tuple_sizeof(PyTupleObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *); - return PyLong_FromSsize_t(res); + res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *); + return PyLong_FromSsize_t(res); } PyDoc_STRVAR(index_doc, @@ -754,62 +754,62 @@ PyDoc_STRVAR(sizeof_doc, "T.__sizeof__() -- size of T in memory, in bytes"); static PyMethodDef tuple_methods[] = { - {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS}, - {"__sizeof__", (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc}, - {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc}, - {"count", (PyCFunction)tuplecount, METH_O, count_doc}, - {NULL, NULL} /* sentinel */ + {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS}, + {"__sizeof__", (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc}, + {"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 + (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 */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "tuple", + sizeof(PyTupleObject) - sizeof(PyObject *), + sizeof(PyObject *), + (destructor)tupledealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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: @@ -822,207 +822,207 @@ PyTypeObject PyTuple_Type = { 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_XDECREF(v->ob_item[i]); - v->ob_item[i] = NULL; - } - 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; + 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_XDECREF(v->ob_item[i]); + v->ob_item[i] = NULL; + } + 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; + 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); - } - } + 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; + 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_XDECREF(free_list[0]); - free_list[0] = NULL; + /* empty tuples are used all over the place and applications may + * rely on the fact that an empty tuple is a singleton. */ + Py_XDECREF(free_list[0]); + free_list[0] = NULL; - (void)PyTuple_ClearFreeList(); + (void)PyTuple_ClearFreeList(); #endif #ifdef SHOW_TRACK_COUNT - show_track(); + show_track(); #endif } /*********************** Tuple Iterator **************************/ typedef struct { - PyObject_HEAD - long it_index; - PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ + 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); + _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; + 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; + 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 PyLong_FromSsize_t(len); + Py_ssize_t len = 0; + if (it->it_seq) + len = PyTuple_GET_SIZE(it->it_seq) - it->it_index; + return PyLong_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 */ + {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc}, + {NULL, NULL} /* sentinel */ }; PyTypeObject PyTupleIter_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "tuple_iterator", /* 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_reserved */ - 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, + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "tuple_iterator", /* 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_reserved */ + 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; + 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/Objects/typeobject.c b/Objects/typeobject.c index 7fd4cc85e8..2ec9829231 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -13,22 +13,22 @@ 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_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, \ - ((PyUnicodeObject *)(name))->hash) + MCACHE_HASH((type)->tp_version_tag, \ + ((PyUnicodeObject *)(name))->hash) #define MCACHE_CACHEABLE_NAME(name) \ - PyUnicode_CheckExact(name) && \ - PyUnicode_GET_SIZE(name) <= MCACHE_MAX_ATTR_SIZE + PyUnicode_CheckExact(name) && \ + PyUnicode_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 */ + 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]; @@ -37,325 +37,325 @@ 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; + 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; + /* 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); + /* + 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; + /* 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_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, - {"__itemsize__", T_INT, 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} + {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, + {"__itemsize__", T_INT, 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; + const char *s; - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { - PyHeapTypeObject* et = (PyHeapTypeObject*)type; + 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 PyUnicode_FromString(s); - } + 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 PyUnicode_FromString(s); + } } static int type_set_name(PyTypeObject *type, PyObject *value, void *context) { - PyHeapTypeObject* et; - char *tp_name; - 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 (!PyUnicode_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; - } - - /* Check absence of null characters */ - tmp = PyUnicode_FromStringAndSize("\0", 1); - if (tmp == NULL) - return -1; - if (PyUnicode_Contains(value, tmp) != 0) { - Py_DECREF(tmp); - PyErr_Format(PyExc_ValueError, - "__name__ must not contain null bytes"); - return -1; - } - Py_DECREF(tmp); - - tp_name = _PyUnicode_AsString(value); - if (tp_name == NULL) - return -1; - - et = (PyHeapTypeObject*)type; - - Py_INCREF(value); - - Py_DECREF(et->ht_name); - et->ht_name = value; - - type->tp_name = tp_name; - - return 0; + PyHeapTypeObject* et; + char *tp_name; + 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 (!PyUnicode_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; + } + + /* Check absence of null characters */ + tmp = PyUnicode_FromStringAndSize("\0", 1); + if (tmp == NULL) + return -1; + if (PyUnicode_Contains(value, tmp) != 0) { + Py_DECREF(tmp); + PyErr_Format(PyExc_ValueError, + "__name__ must not contain null bytes"); + return -1; + } + Py_DECREF(tmp); + + tp_name = _PyUnicode_AsString(value); + if (tp_name == NULL) + return -1; + + et = (PyHeapTypeObject*)type; + + Py_INCREF(value); + + Py_DECREF(et->ht_name); + et->ht_name = value; + + type->tp_name = tp_name; + + 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 PyUnicode_FromStringAndSize( - type->tp_name, (Py_ssize_t)(s - type->tp_name)); - return PyUnicode_FromString("builtins"); - } + 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 PyUnicode_FromStringAndSize( + type->tp_name, (Py_ssize_t)(s - type->tp_name)); + return PyUnicode_FromString("builtins"); + } } 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; - } + 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); + PyType_Modified(type); - return PyDict_SetItemString(type->tp_dict, "__module__", value); + return PyDict_SetItemString(type->tp_dict, "__module__", value); } static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { - PyObject *mod = PyDict_GetItemString(type->tp_dict, - "__abstractmethods__"); - if (!mod) { - PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); - return NULL; - } - Py_XINCREF(mod); - return mod; + PyObject *mod = PyDict_GetItemString(type->tp_dict, + "__abstractmethods__"); + if (!mod) { + PyErr_Format(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 res = PyDict_SetItemString(type->tp_dict, - "__abstractmethods__", value); - if (res == 0) { - PyType_Modified(type); - if (value && PyObject_IsTrue(value)) { - type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT; - } - else { - type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT; - } - } - return res; + /* __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 res = PyDict_SetItemString(type->tp_dict, + "__abstractmethods__", value); + if (res == 0) { + PyType_Modified(type); + if (value && PyObject_IsTrue(value)) { + 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; + Py_INCREF(type->tp_bases); + return type->tp_bases; } static PyTypeObject *best_base(PyObject *); @@ -367,357 +367,357 @@ 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); + update_callback callback, void *data); static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, - update_callback callback, void *data); + 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; + 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 (!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; + 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 (!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); - } + 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; + type->tp_bases = old_bases; + type->tp_base = old_base; + type->tp_mro = old_mro; - return -1; + 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); + 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 PyUnicode_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; + PyObject *result; + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) + return PyUnicode_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; - } + 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; - } + 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} + {"__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_repr(PyTypeObject *type) { - PyObject *mod, *name, *rtn; + PyObject *mod, *name, *rtn; - mod = type_module(type, NULL); - if (mod == NULL) - PyErr_Clear(); - else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; - } - name = type_name(type, NULL); - if (name == NULL) - return NULL; + mod = type_module(type, NULL); + if (mod == NULL) + PyErr_Clear(); + else if (!PyUnicode_Check(mod)) { + Py_DECREF(mod); + mod = NULL; + } + name = type_name(type, NULL); + if (name == NULL) + return NULL; - if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins")) - rtn = PyUnicode_FromFormat("", mod, name); - else - rtn = PyUnicode_FromFormat("", type->tp_name); + if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins")) + rtn = PyUnicode_FromFormat("", mod, name); + else + rtn = PyUnicode_FromFormat("", type->tp_name); - Py_XDECREF(mod); - Py_DECREF(name); - return rtn; + 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(Py_TYPE(obj), type)) - return obj; - type = Py_TYPE(obj); - if (type->tp_init != NULL && - type->tp_init(obj, args, kwds) < 0) { - Py_DECREF(obj); - obj = NULL; - } - } - return obj; + 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(Py_TYPE(obj), type)) + return obj; + type = Py_TYPE(obj); + if (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 */ + 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 (PyType_IS_GC(type)) + obj = _PyObject_GC_Malloc(size); + else + obj = (PyObject *)PyObject_MALLOC(size); - if (obj == NULL) - return PyErr_NoMemory(); + if (obj == NULL) + return PyErr_NoMemory(); - memset(obj, '\0', size); + memset(obj, '\0', size); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(type); + 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 (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; + 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); + return type->tp_alloc(type, 0); } /* Helpers for subtyping */ @@ -725,341 +725,341 @@ PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) 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; + 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; + 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); - } - } - } + 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; + 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); - } + /* 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); + } - /* There's no need to clear the instance dict (if any); - the collector will call its tp_clear handler. */ + /* There's no need to clear the instance dict (if any); + the collector will call its tp_clear handler. */ - if (baseclear) - return baseclear(self); - return 0; + if (baseclear) + return baseclear(self); + return 0; } static void subtype_dealloc(PyObject *self) { - PyTypeObject *type, *base; - destructor basedealloc; - - /* 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; - Py_TRASHCAN_SAFE_BEGIN(self); - --_PyTrash_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 ((basedealloc = 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); + PyTypeObject *type, *base; + destructor basedealloc; + + /* 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; + Py_TRASHCAN_SAFE_BEGIN(self); + --_PyTrash_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 ((basedealloc = 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; - Py_TRASHCAN_SAFE_END(self); - --_PyTrash_delete_nesting; + ++_PyTrash_delete_nesting; + Py_TRASHCAN_SAFE_END(self); + --_PyTrash_delete_nesting; - /* Explanation of the weirdness around the trashcan macros: + /* Explanation of the weirdness around the trashcan macros: - Q. What do the trashcan macros do? + 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. + 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? + 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: + 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 + GC untrack + trashcan begin + GC track - Q. Why did the last question say "immediately GC-track again"? - It's nowhere near immediately. + 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 dealloction is - a subtle disaster. + 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 dealloction is + a subtle disaster. - Q. Why the bizarre (net-zero) manipulation of - _PyTrash_delete_nesting around the trashcan macros? + 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: + 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 + - suppose the trashcan level is one below the trashcan limit - - subtype_dealloc() is called + - 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 + - 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__ + - 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 + - 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 + - the trashcan limit is now reached, so the object is put on the + trashcan's to-be-deleted-later list - - basedealloc() returns + - basedealloc() returns - - subtype_dealloc() decrefs the object's type + - subtype_dealloc() decrefs the object's type - - subtype_dealloc() returns + - subtype_dealloc() returns - - later, the trashcan code starts deleting the objects from its - to-be-deleted-later list + - later, the trashcan code starts deleting the objects from its + to-be-deleted-later list - - subtype_dealloc() is called *AGAIN* for the same object + - 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*!!! + - 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. + 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. + 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? + 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. - */ + 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); @@ -1069,36 +1069,36 @@ static PyTypeObject *solid_base(PyTypeObject *type); int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - - 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; - } + PyObject *mro; + + 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, + 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. @@ -1115,75 +1115,75 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) static PyObject * lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj) { - PyObject *res; + PyObject *res; - if (*attrobj == NULL) { - *attrobj = PyUnicode_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; + if (*attrobj == NULL) { + *attrobj = PyUnicode_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 *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) { - return lookup_maybe(self, attrstr, attrobj); + return lookup_maybe(self, attrstr, attrobj); } /* A variation of PyObject_CallMethod that uses lookup_method() - instead of PyObject_GetAttrString(). This uses the same convention + 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); + 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; - } + 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); + if (format && *format) + args = Py_VaBuildValue(format, va); + else + args = PyTuple_New(0); - va_end(va); + va_end(va); - if (args == NULL) - return NULL; + if (args == NULL) + return NULL; - assert(PyTuple_Check(args)); - retval = PyObject_Call(func, args, NULL); + assert(PyTuple_Check(args)); + retval = PyObject_Call(func, args, NULL); - Py_DECREF(args); - Py_DECREF(func); + Py_DECREF(args); + Py_DECREF(func); - return retval; + return retval; } /* Clone of call_method() that returns NotImplemented when the lookup fails. */ @@ -1191,37 +1191,37 @@ call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) static PyObject * call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...) { - va_list va; - PyObject *args, *func = 0, *retval; - va_start(va, 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; - } + 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); + if (format && *format) + args = Py_VaBuildValue(format, va); + else + args = PyTuple_New(0); - va_end(va); + va_end(va); - if (args == NULL) - return NULL; + if (args == NULL) + return NULL; - assert(PyTuple_Check(args)); - retval = PyObject_Call(func, args, NULL); + assert(PyTuple_Check(args)); + retval = PyObject_Call(func, args, NULL); - Py_DECREF(args); - Py_DECREF(func); + Py_DECREF(args); + Py_DECREF(func); - return retval; + return retval; } /* @@ -1254,68 +1254,68 @@ call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...) static int tail_contains(PyObject *list, int whence, PyObject *o) { - Py_ssize_t j, size; - size = PyList_GET_SIZE(list); + 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; + 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 (!PyUnicode_Check(name)) { - Py_DECREF(name); - return NULL; - } - return name; + PyObject *name = PyObject_GetAttrString(cls, "__name__"); + if (name == NULL) { + PyErr_Clear(); + Py_XDECREF(name); + name = PyObject_Repr(cls); + } + if (name == NULL) + return NULL; + if (!PyUnicode_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); - if (o != NULL) { - PyErr_Format(PyExc_TypeError, - "duplicate base class %U", - o); - Py_DECREF(o); - } else { - PyErr_SetString(PyExc_TypeError, - "duplicate base class"); - } - return -1; - } - } - } - return 0; + 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); + if (o != NULL) { + PyErr_Format(PyExc_TypeError, + "duplicate base class %U", + o); + Py_DECREF(o); + } else { + PyErr_SetString(PyExc_TypeError, + "duplicate base class"); + } + 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 + 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. */ @@ -1323,252 +1323,252 @@ check_duplicates(PyObject *list) 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 \ + 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 ? _PyUnicode_AsString(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); + 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 ? _PyUnicode_AsString(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; + 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; + 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; - parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro); - 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; + 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; + parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro); + 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; + PyTypeObject *type = (PyTypeObject *)self; - return mro_implementation(type); + 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 (!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; + 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 (!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; } @@ -1578,90 +1578,90 @@ mro_internal(PyTypeObject *type) 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 (!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; + 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 (!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; + 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 *); + 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; + return t_size != b_size; } static PyTypeObject * solid_base(PyTypeObject *type) { - PyTypeObject *base; + 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; + 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 *); @@ -1677,180 +1677,180 @@ static void fixup_slot_dispatchers(PyTypeObject *); 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; + 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; + static PyObject *dict_str; + PyObject *descr; - if (dict_str == NULL) { - dict_str = PyUnicode_InternFromString("__dict__"); - if (dict_str == NULL) - return NULL; - } - descr = _PyType_Lookup(type, dict_str); - if (descr == NULL || !PyDescr_IsData(descr)) - return NULL; + if (dict_str == NULL) { + dict_str = PyUnicode_InternFromString("__dict__"); + if (dict_str == NULL) + return NULL; + } + descr = _PyType_Lookup(type, dict_str); + if (descr == NULL || !PyDescr_IsData(descr)) + return NULL; - return descr; + return descr; } static void raise_dict_descr_error(PyObject *obj) { - PyErr_Format(PyExc_TypeError, - "this __dict__ descriptor does not support " - "'%.200s' objects", Py_TYPE(obj)->tp_name); + PyErr_Format(PyExc_TypeError, + "this __dict__ descriptor does not support " + "'%.200s' objects", Py_TYPE(obj)->tp_name); } static PyObject * subtype_dict(PyObject *obj, void *context) { - PyObject **dictptr; - PyObject *dict; - PyTypeObject *base; - - base = get_builtin_base_with_dict(Py_TYPE(obj)); - if (base != NULL) { - descrgetfunc func; - PyObject *descr = get_dict_descriptor(base); - if (descr == NULL) { - raise_dict_descr_error(obj); - return NULL; - } - func = Py_TYPE(descr)->tp_descr_get; - if (func == NULL) { - raise_dict_descr_error(obj); - return NULL; - } - return func(descr, obj, (PyObject *)(Py_TYPE(obj))); - } - - 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; + PyObject **dictptr; + PyObject *dict; + PyTypeObject *base; + + base = get_builtin_base_with_dict(Py_TYPE(obj)); + if (base != NULL) { + descrgetfunc func; + PyObject *descr = get_dict_descriptor(base); + if (descr == NULL) { + raise_dict_descr_error(obj); + return NULL; + } + func = Py_TYPE(descr)->tp_descr_get; + if (func == NULL) { + raise_dict_descr_error(obj); + return NULL; + } + return func(descr, obj, (PyObject *)(Py_TYPE(obj))); + } + + 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(Py_TYPE(obj)); - if (base != NULL) { - descrsetfunc func; - PyObject *descr = get_dict_descriptor(base); - if (descr == NULL) { - raise_dict_descr_error(obj); - return -1; - } - func = Py_TYPE(descr)->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; + PyObject **dictptr; + PyObject *dict; + PyTypeObject *base; + + base = get_builtin_base_with_dict(Py_TYPE(obj)); + if (base != NULL) { + descrsetfunc func; + PyObject *descr = get_dict_descriptor(base); + if (descr == NULL) { + raise_dict_descr_error(obj); + return -1; + } + func = Py_TYPE(descr)->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; + 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} + {"__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} + {"__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} + {"__weakref__", subtype_getweakref, NULL, + PyDoc_STR("list of weak references to the object (if defined)")}, + {0} }; static int valid_identifier(PyObject *s) { - if (!PyUnicode_Check(s)) { - PyErr_Format(PyExc_TypeError, - "__slots__ items must be strings, not '%.200s'", - Py_TYPE(s)->tp_name); - return 0; - } - if (!PyUnicode_IsIdentifier(s)) { - PyErr_SetString(PyExc_TypeError, - "__slots__ must be identifiers"); - return 0; - } - return 1; + if (!PyUnicode_Check(s)) { + PyErr_Format(PyExc_TypeError, + "__slots__ items must be strings, not '%.200s'", + Py_TYPE(s)->tp_name); + return 0; + } + if (!PyUnicode_IsIdentifier(s)) { + PyErr_SetString(PyExc_TypeError, + "__slots__ must be identifiers"); + return 0; + } + return 1; } /* Forward */ @@ -1860,435 +1860,435 @@ object_init(PyObject *self, PyObject *args, PyObject *kwds); static int type_init(PyObject *cls, PyObject *args, PyObject *kwds) { - int res; + int res; - assert(args != NULL && PyTuple_Check(args)); - assert(kwds == NULL || PyDict_Check(kwds)); + 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 (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; - } + 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; + /* 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, "UO!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 = Py_TYPE(tmp); - 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 (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; - } - - /* Check for valid slot names and two special cases */ - for (i = 0; i < nslots; i++) { - PyObject *tmp = PyTuple_GET_ITEM(slots, i); - if (!valid_identifier(tmp)) - goto bad_slots; - assert(PyUnicode_Check(tmp)); - if (PyUnicode_CompareWithASCIIString(tmp, "__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 (PyUnicode_CompareWithASCIIString(tmp, "__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++) { - tmp = PyTuple_GET_ITEM(slots, i); - if ((add_dict && - PyUnicode_CompareWithASCIIString(tmp, "__dict__") == 0) || - (add_weak && - PyUnicode_CompareWithASCIIString(tmp, "__weakref__") == 0)) - continue; - tmp =_Py_Mangle(name, tmp); - if (!tmp) - 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 */ - 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; - - /* 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 = _PyUnicode_AsString(name); - if (!type->tp_name) { - Py_DECREF(type); - return NULL; - } - - /* 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 && PyUnicode_Check(doc)) { - Py_ssize_t len; - char *doc_str; - char *tp_doc; - - doc_str = _PyUnicode_AsString(doc); - if (doc_str == NULL) { - Py_DECREF(type); - return NULL; - } - /* Silently truncate the docstring if it contains null bytes. */ - len = strlen(doc_str); - tp_doc = (char *)PyObject_MALLOC(len + 1); - if (tp_doc == NULL) { - Py_DECREF(type); - return NULL; - } - memcpy(tp_doc, doc_str, len + 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 = _PyUnicode_AsString( - 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; + 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, "UO!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 = Py_TYPE(tmp); + 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 (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; + } + + /* Check for valid slot names and two special cases */ + for (i = 0; i < nslots; i++) { + PyObject *tmp = PyTuple_GET_ITEM(slots, i); + if (!valid_identifier(tmp)) + goto bad_slots; + assert(PyUnicode_Check(tmp)); + if (PyUnicode_CompareWithASCIIString(tmp, "__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 (PyUnicode_CompareWithASCIIString(tmp, "__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++) { + tmp = PyTuple_GET_ITEM(slots, i); + if ((add_dict && + PyUnicode_CompareWithASCIIString(tmp, "__dict__") == 0) || + (add_weak && + PyUnicode_CompareWithASCIIString(tmp, "__weakref__") == 0)) + continue; + tmp =_Py_Mangle(name, tmp); + if (!tmp) + 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 */ + 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; + + /* 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 = _PyUnicode_AsString(name); + if (!type->tp_name) { + Py_DECREF(type); + return NULL; + } + + /* 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 && PyUnicode_Check(doc)) { + Py_ssize_t len; + char *doc_str; + char *tp_doc; + + doc_str = _PyUnicode_AsString(doc); + if (doc_str == NULL) { + Py_DECREF(type); + return NULL; + } + /* Silently truncate the docstring if it contains null bytes. */ + len = strlen(doc_str); + tp_doc = (char *)PyObject_MALLOC(len + 1); + if (tp_doc == NULL) { + Py_DECREF(type); + return NULL; + } + memcpy(tp_doc, doc_str, len + 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 = _PyUnicode_AsString( + 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. @@ -2296,50 +2296,50 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) 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); - 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; + 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); + 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(), @@ -2347,166 +2347,166 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) static PyObject * type_getattro(PyTypeObject *type, PyObject *name) { - PyTypeObject *metatype = Py_TYPE(type); - PyObject *meta_attribute, *attribute; - descrgetfunc meta_get; - - /* 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 '%U'", - type->tp_name, name); - return NULL; + PyTypeObject *metatype = Py_TYPE(type); + PyObject *meta_attribute, *attribute; + descrgetfunc meta_get; + + /* 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 '%U'", + type->tp_name, 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); + 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); + 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; + 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 PyObject * type_prepare(PyObject *self, PyObject *args, PyObject *kwds) { - return PyDict_New(); + return PyDict_New(); } 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")}, - {"__prepare__", (PyCFunction)type_prepare, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("__prepare__() -> dict\n" - "used to create the namespace for the class statement")}, - {"__instancecheck__", type___instancecheck__, METH_O, - PyDoc_STR("__instancecheck__() -> check if an object is an instance")}, - {"__subclasscheck__", type___subclasscheck__, METH_O, - PyDoc_STR("__subclasschck__ -> check if an class is a subclass")}, - {0} + {"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")}, + {"__prepare__", (PyCFunction)type_prepare, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("__prepare__() -> dict\n" + "used to create the namespace for the class statement")}, + {"__instancecheck__", type___instancecheck__, METH_O, + PyDoc_STR("__instancecheck__() -> check if an object is an instance")}, + {"__subclasscheck__", type___subclasscheck__, METH_O, + PyDoc_STR("__subclasschck__ -> check if an class is a subclass")}, + {0} }; PyDoc_STRVAR(type_doc, @@ -2516,109 +2516,109 @@ PyDoc_STRVAR(type_doc, 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); + /* 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); + 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. */ + /* 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; + 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); + /* Because of type_is_gc(), the collector only calls this + for heaptypes. */ + assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); - /* 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: + /* 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_dict: - It is a dict, so the collector will call its tp_clear. + tp_dict: + It is a dict, so the collector will call its tp_clear. - tp_cache: - Not used; if it were, it would be a dict. + 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_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. + 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. - */ + slots (in PyHeapTypeObject): + A tuple of strings can't be part of a cycle. + */ - Py_CLEAR(type->tp_mro); + Py_CLEAR(type->tp_mro); - return 0; + return 0; } static int type_is_gc(PyTypeObject *type) { - return type->tp_flags & Py_TPFLAGS_HEAPTYPE; + 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_reserved */ - (reprfunc)type_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* 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 */ - 0, /* 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 */ + 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_reserved */ + (reprfunc)type_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* 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 */ + 0, /* 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 */ }; @@ -2671,318 +2671,318 @@ 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)); + 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; + 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.__new__() takes no parameters", - 1); - } - else if (type->tp_new != object_new || - type->tp_init == object_init) - { - PyErr_SetString(PyExc_TypeError, - "object.__new__() 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; - - /* 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 = PyUnicode_InternFromString(", "); - if (comma == NULL) - goto error; - } - joined = PyObject_CallMethod(comma, "join", - "O", sorted_methods); - if (joined == NULL) - goto error; - - PyErr_Format(PyExc_TypeError, - "Can't instantiate abstract class %s " - "with abstract methods %U", - type->tp_name, - joined); - error: - Py_XDECREF(joined); - Py_XDECREF(sorted_methods); - Py_XDECREF(abstract_methods); - return NULL; - } - return type->tp_alloc(type, 0); + 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.__new__() takes no parameters", + 1); + } + else if (type->tp_new != object_new || + type->tp_init == object_init) + { + PyErr_SetString(PyExc_TypeError, + "object.__new__() 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; + + /* 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 = PyUnicode_InternFromString(", "); + if (comma == NULL) + goto error; + } + joined = PyObject_CallMethod(comma, "join", + "O", sorted_methods); + if (joined == NULL) + goto error; + + PyErr_Format(PyExc_TypeError, + "Can't instantiate abstract class %s " + "with abstract methods %U", + type->tp_name, + joined); + 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); + 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 (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; - } - name = type_name(type, NULL); - if (name == NULL) - return NULL; - if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins")) - rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self); - else - rtn = PyUnicode_FromFormat("<%s object at %p>", - type->tp_name, self); - Py_XDECREF(mod); - Py_DECREF(name); - return rtn; + PyTypeObject *type; + PyObject *mod, *name, *rtn; + + type = Py_TYPE(self); + mod = type_module(type, NULL); + if (mod == NULL) + PyErr_Clear(); + else if (!PyUnicode_Check(mod)) { + Py_DECREF(mod); + mod = NULL; + } + name = type_name(type, NULL); + if (name == NULL) + return NULL; + if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins")) + rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self); + else + rtn = PyUnicode_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; + unaryfunc f; - f = Py_TYPE(self)->tp_repr; - if (f == NULL) - f = object_repr; - return f(self); + f = Py_TYPE(self)->tp_repr; + if (f == NULL) + f = object_repr; + return f(self); } static PyObject * object_richcompare(PyObject *self, PyObject *other, int op) { - PyObject *res; - - switch (op) { - - case Py_EQ: - /* Return NotImplemented instead of False, so if two - objects are compared, both get a chance at the - comparison. See issue #1393. */ - res = (self == other) ? Py_True : Py_NotImplemented; - Py_INCREF(res); - break; - - case Py_NE: - /* By default, != returns the opposite of ==, - unless the latter returns NotImplemented. */ - res = PyObject_RichCompare(self, other, Py_EQ); - if (res != NULL && res != Py_NotImplemented) { - int ok = PyObject_IsTrue(res); - Py_DECREF(res); - if (ok < 0) - res = NULL; - else { - if (ok) - res = Py_False; - else - res = Py_True; - Py_INCREF(res); - } - } - break; - - default: - res = Py_NotImplemented; - Py_INCREF(res); - break; - } - - return res; + PyObject *res; + + switch (op) { + + case Py_EQ: + /* Return NotImplemented instead of False, so if two + objects are compared, both get a chance at the + comparison. See issue #1393. */ + res = (self == other) ? Py_True : Py_NotImplemented; + Py_INCREF(res); + break; + + case Py_NE: + /* By default, != returns the opposite of ==, + unless the latter returns NotImplemented. */ + res = PyObject_RichCompare(self, other, Py_EQ); + if (res != NULL && res != Py_NotImplemented) { + int ok = PyObject_IsTrue(res); + Py_DECREF(res); + if (ok < 0) + res = NULL; + else { + if (ok) + res = Py_False; + else + res = Py_True; + Py_INCREF(res); + } + } + break; + + default: + res = Py_NotImplemented; + Py_INCREF(res); + break; + } + + return res; } static PyObject * object_get_class(PyObject *self, void *closure) { - Py_INCREF(Py_TYPE(self)); - return (PyObject *)(Py_TYPE(self)); + 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))); + 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; - - if (base != b->tp_base) - return 0; - if (equiv_structs(a, base) && equiv_structs(b, base)) - return 1; - 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_RichCompareBool(slots_a, slots_b, Py_EQ) != 1) - return 0; - size += sizeof(PyObject *) * PyTuple_GET_SIZE(slots_a); - } - return size == a->tp_basicsize && size == b->tp_basicsize; + PyTypeObject *base = a->tp_base; + Py_ssize_t size; + PyObject *slots_a, *slots_b; + + if (base != b->tp_base) + return 0; + if (equiv_structs(a, base) && equiv_structs(b, base)) + return 1; + 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_RichCompareBool(slots_a, slots_b, Py_EQ) != 1) + 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; + 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; - } + 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} + {"__class__", object_get_class, object_set_class, + PyDoc_STR("the object's class")}, + {0} }; @@ -2996,194 +2996,194 @@ static PyGetSetDef object_getsets[] = { static PyObject * import_copyreg(void) { - static PyObject *copyreg_str; + static PyObject *copyreg_str; - if (!copyreg_str) { - copyreg_str = PyUnicode_InternFromString("copyreg"); - if (copyreg_str == NULL) - return NULL; - } + if (!copyreg_str) { + copyreg_str = PyUnicode_InternFromString("copyreg"); + if (copyreg_str == NULL) + return NULL; + } - return PyImport_Import(copyreg_str); + 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, - "copyreg._slotnames didn't return a list or None"); - Py_DECREF(slotnames); - slotnames = NULL; - } - - return slotnames; + 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, + "copyreg._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 { - PyObject *items = PyObject_CallMethod(obj, "items", ""); - if (items == NULL) - goto end; - dictitems = PyObject_GetIter(items); - Py_DECREF(items); - 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); + 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 { + PyObject *items = PyObject_CallMethod(obj, "items", ""); + if (items == NULL) + goto end; + dictitems = PyObject_GetIter(items); + Py_DECREF(items); + 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; + 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; } /* @@ -3204,79 +3204,79 @@ reduce_2(PyObject *obj) static PyObject * _common_reduce(PyObject *self, int proto) { - PyObject *copyreg, *res; + PyObject *copyreg, *res; - if (proto >= 2) - return reduce_2(self); + if (proto >= 2) + return reduce_2(self); - copyreg = import_copyreg(); - if (!copyreg) - return NULL; + copyreg = import_copyreg(); + if (!copyreg) + return NULL; - res = PyEval_CallMethod(copyreg, "_reduce_ex", "(Oi)", self, proto); - Py_DECREF(copyreg); + res = PyEval_CallMethod(copyreg, "_reduce_ex", "(Oi)", self, proto); + Py_DECREF(copyreg); - return res; + return res; } static PyObject * object_reduce(PyObject *self, PyObject *args) { - int proto = 0; + int proto = 0; - if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto)) - return NULL; + if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto)) + return NULL; - return _common_reduce(self, proto); + 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); + 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; + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } PyDoc_STRVAR(object_subclasshook_doc, @@ -3292,104 +3292,104 @@ PyDoc_STRVAR(object_subclasshook_doc, class object: def __format__(self, format_spec): - return format(str(self), format_spec) + return format(str(self), format_spec) */ static PyObject * object_format(PyObject *self, PyObject *args) { - PyObject *format_spec; - PyObject *self_as_str = NULL; - PyObject *result = NULL; - PyObject *format_meth = NULL; - - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - - self_as_str = PyObject_Str(self); - if (self_as_str != NULL) { - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); - } + PyObject *format_spec; + PyObject *self_as_str = NULL; + PyObject *result = NULL; + PyObject *format_meth = NULL; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + + self_as_str = PyObject_Str(self); + if (self_as_str != NULL) { + /* find the format function */ + format_meth = PyObject_GetAttrString(self_as_str, "__format__"); + if (format_meth != NULL) { + /* and call it */ + result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); } + } - Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); + Py_XDECREF(self_as_str); + Py_XDECREF(format_meth); - return result; + return result; } static PyObject * object_sizeof(PyObject *self, PyObject *args) { - Py_ssize_t res, isize; + Py_ssize_t res, isize; - res = 0; - isize = self->ob_type->tp_itemsize; - if (isize > 0) - res = Py_SIZE(self->ob_type) * isize; - res += self->ob_type->tp_basicsize; + res = 0; + isize = self->ob_type->tp_itemsize; + if (isize > 0) + res = Py_SIZE(self->ob_type) * isize; + res += self->ob_type->tp_basicsize; - return PyLong_FromSsize_t(res); + return PyLong_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__() -> size of object in memory, in bytes")}, - {0} + {"__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__() -> size 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_reserved */ - 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 */ - object_richcompare, /* 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 */ + 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_reserved */ + 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 */ + object_richcompare, /* 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 */ }; @@ -3398,168 +3398,168 @@ PyTypeObject PyBaseObject_Type = { static int add_methods(PyTypeObject *type, PyMethodDef *meth) { - PyObject *dict = type->tp_dict; - - for (; meth->ml_name != NULL; meth++) { - PyObject *descr; - 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; - if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) - return -1; - Py_DECREF(descr); - } - return 0; + PyObject *dict = type->tp_dict; + + for (; meth->ml_name != NULL; meth++) { + PyObject *descr; + 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; + if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) + return -1; + Py_DECREF(descr); + } + return 0; } static int add_members(PyTypeObject *type, PyMemberDef *memb) { - PyObject *dict = type->tp_dict; + 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; + 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; + PyObject *dict = type->tp_dict; - for (; gsp->name != NULL; gsp++) { - PyObject *descr; - if (PyDict_GetItemString(dict, gsp->name)) - continue; - descr = PyDescr_NewGetSet(type, gsp); + 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; + if (descr == NULL) + return -1; + if (PyDict_SetItemString(dict, gsp->name, descr) < 0) + return -1; + Py_DECREF(descr); + } + return 0; } static void inherit_special(PyTypeObject *type, PyTypeObject *base) { - Py_ssize_t oldsize, newsize; - - /* 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_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; - } - { - /* 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 */ + Py_ssize_t oldsize, newsize; + + /* 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_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; + } + { + /* 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); - COPYVAL(tp_weaklistoffset); - 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, &PyLong_Type)) - type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; - else if (PyType_IsSubtype(base, &PyBytes_Type)) - type->tp_flags |= Py_TPFLAGS_BYTES_SUBCLASS; - else if (PyType_IsSubtype(base, &PyUnicode_Type)) - type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; - 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; + if (type->SLOT == 0) type->SLOT = base->SLOT + + COPYVAL(tp_itemsize); + COPYVAL(tp_weaklistoffset); + 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, &PyLong_Type)) + type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; + else if (PyType_IsSubtype(base, &PyBytes_Type)) + type->tp_flags |= Py_TPFLAGS_BYTES_SUBCLASS; + else if (PyType_IsSubtype(base, &PyUnicode_Type)) + type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; + 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 char *hash_name_op[] = { - "__eq__", - "__hash__", - NULL + "__eq__", + "__hash__", + NULL }; static int overrides_hash(PyTypeObject *type) { - char **p; - PyObject *dict = type->tp_dict; + char **p; + PyObject *dict = type->tp_dict; - assert(dict != NULL); - for (p = hash_name_op; *p; p++) { - if (PyDict_GetItemString(dict, *p) != NULL) - return 1; - } - return 0; + assert(dict != NULL); + for (p = hash_name_op; *p; p++) { + if (PyDict_GetItemString(dict, *p) != NULL) + return 1; + } + return 0; } static void inherit_slots(PyTypeObject *type, PyTypeObject *base) { - PyTypeObject *basebase; + PyTypeObject *basebase; #undef SLOTDEFINED #undef COPYSLOT @@ -3569,147 +3569,147 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) #undef COPYBUF #define SLOTDEFINED(SLOT) \ - (base->SLOT != 0 && \ - (basebase == NULL || base->SLOT != basebase->SLOT)) + (base->SLOT != 0 && \ + (basebase == NULL || base->SLOT != basebase->SLOT)) #define COPYSLOT(SLOT) \ - if (!type->SLOT && SLOTDEFINED(SLOT)) type->SLOT = base->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_remainder); - COPYNUM(nb_divmod); - COPYNUM(nb_power); - COPYNUM(nb_negative); - COPYNUM(nb_positive); - COPYNUM(nb_absolute); - COPYNUM(nb_bool); - COPYNUM(nb_invert); - COPYNUM(nb_lshift); - COPYNUM(nb_rshift); - COPYNUM(nb_and); - COPYNUM(nb_xor); - COPYNUM(nb_or); - COPYNUM(nb_int); - COPYNUM(nb_float); - COPYNUM(nb_inplace_add); - COPYNUM(nb_inplace_subtract); - COPYNUM(nb_inplace_multiply); - 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); - COPYNUM(nb_true_divide); - COPYNUM(nb_floor_divide); - COPYNUM(nb_inplace_true_divide); - COPYNUM(nb_inplace_floor_divide); - 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_ass_item); - 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_getbuffer); - COPYBUF(bf_releasebuffer); - } - - basebase = base->tp_base; - - COPYSLOT(tp_dealloc); - 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_reserved is ignored */ - COPYSLOT(tp_repr); - /* tp_hash see tp_richcompare */ - COPYSLOT(tp_call); - COPYSLOT(tp_str); - { - /* Copy comparison-related slots only when - not overriding them anywhere */ - if (type->tp_richcompare == NULL && - type->tp_hash == NULL && - !overrides_hash(type)) - { - type->tp_richcompare = base->tp_richcompare; - type->tp_hash = base->tp_hash; - } - } - { - COPYSLOT(tp_iter); - COPYSLOT(tp_iternext); - } - { - 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_Free) { - /* 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. - */ - } + /* 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_remainder); + COPYNUM(nb_divmod); + COPYNUM(nb_power); + COPYNUM(nb_negative); + COPYNUM(nb_positive); + COPYNUM(nb_absolute); + COPYNUM(nb_bool); + COPYNUM(nb_invert); + COPYNUM(nb_lshift); + COPYNUM(nb_rshift); + COPYNUM(nb_and); + COPYNUM(nb_xor); + COPYNUM(nb_or); + COPYNUM(nb_int); + COPYNUM(nb_float); + COPYNUM(nb_inplace_add); + COPYNUM(nb_inplace_subtract); + COPYNUM(nb_inplace_multiply); + 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); + COPYNUM(nb_true_divide); + COPYNUM(nb_floor_divide); + COPYNUM(nb_inplace_true_divide); + COPYNUM(nb_inplace_floor_divide); + 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_ass_item); + 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_getbuffer); + COPYBUF(bf_releasebuffer); + } + + basebase = base->tp_base; + + COPYSLOT(tp_dealloc); + 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_reserved is ignored */ + COPYSLOT(tp_repr); + /* tp_hash see tp_richcompare */ + COPYSLOT(tp_call); + COPYSLOT(tp_str); + { + /* Copy comparison-related slots only when + not overriding them anywhere */ + if (type->tp_richcompare == NULL && + type->tp_hash == NULL && + !overrides_hash(type)) + { + type->tp_richcompare = base->tp_richcompare; + type->tp_hash = base->tp_hash; + } + } + { + COPYSLOT(tp_iter); + COPYSLOT(tp_iternext); + } + { + 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_Free) { + /* 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 *); @@ -3717,273 +3717,273 @@ static int add_operators(PyTypeObject *); int PyType_Ready(PyTypeObject *type) { - PyObject *dict, *bases; - PyTypeObject *base; - Py_ssize_t i, n; + 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); + 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; + 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); + /* 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 != NULL && 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); - } - - /* 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 = PyUnicode_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); - } - } - - /* Hack for tp_hash and __hash__. - If after all that, tp_hash is still NULL, and __hash__ is not in - tp_dict, set tp_hash to PyObject_HashNotImplemented and - tp_dict['__hash__'] equal to None. - This signals that __hash__ is not inherited. - */ - if (type->tp_hash == NULL) { - if (PyDict_GetItemString(type->tp_dict, "__hash__") == NULL) { - if (PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0) - goto error; - type->tp_hash = PyObject_HashNotImplemented; - } - } - - /* 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; - } - - /* Warn for a type that implements tp_compare (now known as - tp_reserved) but not tp_richcompare. */ - if (type->tp_reserved && !type->tp_richcompare) { - int error; - char msg[240]; - PyOS_snprintf(msg, sizeof(msg), - "Type %.100s defines tp_reserved (formerly " - "tp_compare) but not tp_richcompare. " - "Comparisons may not behave as intended.", - type->tp_name); - error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1); - if (error == -1) - 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; + /* 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 != NULL && 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); + } + + /* 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 = PyUnicode_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); + } + } + + /* Hack for tp_hash and __hash__. + If after all that, tp_hash is still NULL, and __hash__ is not in + tp_dict, set tp_hash to PyObject_HashNotImplemented and + tp_dict['__hash__'] equal to None. + This signals that __hash__ is not inherited. + */ + if (type->tp_hash == NULL) { + if (PyDict_GetItemString(type->tp_dict, "__hash__") == NULL) { + if (PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0) + goto error; + type->tp_hash = PyObject_HashNotImplemented; + } + } + + /* 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; + } + + /* Warn for a type that implements tp_compare (now known as + tp_reserved) but not tp_richcompare. */ + if (type->tp_reserved && !type->tp_richcompare) { + int error; + char msg[240]; + PyOS_snprintf(msg, sizeof(msg), + "Type %.100s defines tp_reserved (formerly " + "tp_compare) but not tp_richcompare. " + "Comparisons may not behave as intended.", + type->tp_name); + error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1); + if (error == -1) + 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; + 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; + 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; - } - } + 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; + 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 + 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. */ @@ -3991,253 +3991,253 @@ check_num_args(PyObject *ob, int n) static PyObject * wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped) { - lenfunc func = (lenfunc)wrapped; - Py_ssize_t res; + 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 PyLong_FromLong((long)res); + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == -1 && PyErr_Occurred()) + return NULL; + return PyLong_FromLong((long)res); } static PyObject * wrap_inquirypred(PyObject *self, PyObject *args, void *wrapped) { - inquiry func = (inquiry)wrapped; - int res; + 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); + 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; + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; - if (!check_num_args(args, 1)) - return NULL; - other = PyTuple_GET_ITEM(args, 0); - return (*func)(self, 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; + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; - if (!check_num_args(args, 1)) - return NULL; - other = PyTuple_GET_ITEM(args, 0); - return (*func)(self, other); + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(self, other); } static PyObject * wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) { - binaryfunc func = (binaryfunc)wrapped; - PyObject *other; + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; - if (!check_num_args(args, 1)) - return NULL; - other = PyTuple_GET_ITEM(args, 0); - if (!PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - return (*func)(other, self); + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + if (!PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + return (*func)(other, self); } static PyObject * wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped) { - ternaryfunc func = (ternaryfunc)wrapped; - PyObject *other; - PyObject *third = Py_None; + ternaryfunc func = (ternaryfunc)wrapped; + PyObject *other; + PyObject *third = Py_None; - /* Note: This wrapper only works for __pow__() */ + /* Note: This wrapper only works for __pow__() */ - if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third)) - return NULL; - return (*func)(self, other, third); + 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; + ternaryfunc func = (ternaryfunc)wrapped; + PyObject *other; + PyObject *third = Py_None; - /* Note: This wrapper only works for __pow__() */ + /* Note: This wrapper only works for __pow__() */ - if (!PyArg_UnpackTuple(args, "", 1, 2, &other, &third)) - return NULL; - return (*func)(other, self, third); + 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; + unaryfunc func = (unaryfunc)wrapped; - if (!check_num_args(args, 0)) - return NULL; - return (*func)(self); + 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; + 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); + 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; + 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; + 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; + 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_sq_setitem(PyObject *self, PyObject *args, void *wrapped) { - ssizeobjargproc func = (ssizeobjargproc)wrapped; - Py_ssize_t i; - int res; - PyObject *arg, *value; + 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; + 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; + 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; + 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; } /* 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; + 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); + 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; + 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; + 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; + 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; + 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; } /* Helper to check for object.__setattr__ or __delattr__ applied to a type. @@ -4245,90 +4245,90 @@ wrap_delitem(PyObject *self, PyObject *args, void *wrapped) 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; + 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; + 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; + 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; + 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; + 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; + 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 PyLong_FromLong(res); + if (!check_num_args(args, 0)) + return NULL; + res = (*func)(self); + if (res == -1 && PyErr_Occurred()) + return NULL; + return PyLong_FromLong(res); } static PyObject * wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { - ternaryfunc func = (ternaryfunc)wrapped; + ternaryfunc func = (ternaryfunc)wrapped; - return (*func)(self, args, kwds); + return (*func)(self, args, kwds); } static PyObject * wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op) { - richcmpfunc func = (richcmpfunc)wrapped; - PyObject *other; + 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); + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + return (*func)(self, other, op); } #undef RICHCMP_WRAPPER @@ -4336,7 +4336,7 @@ wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op) static PyObject * \ richcmp_##NAME(PyObject *self, PyObject *args, void *wrapped) \ { \ - return wrap_richcmpfunc(self, args, wrapped, OP); \ + return wrap_richcmpfunc(self, args, wrapped, OP); \ } RICHCMP_WRAPPER(lt, Py_LT) @@ -4349,164 +4349,164 @@ RICHCMP_WRAPPER(ge, Py_GE) static PyObject * wrap_next(PyObject *self, PyObject *args, void *wrapped) { - unaryfunc func = (unaryfunc)wrapped; - PyObject *res; + 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; + 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; + 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); + 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; + 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; + 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; + 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; + 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; + initproc func = (initproc)wrapped; - if (func(self, args, kwds) < 0) - return NULL; - Py_INCREF(Py_None); - return Py_None; + 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 == NULL ? "?" : 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; + 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 == NULL ? "?" : 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} + {"__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; + 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; + 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 @@ -4516,16 +4516,16 @@ add_tp_new_wrapper(PyTypeObject *type) static PyObject * \ FUNCNAME(PyObject *self) \ { \ - static PyObject *cache_str; \ - return call_method(self, OPSTR, &cache_str, "()"); \ + 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); \ + static PyObject *cache_str; \ + return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \ } /* Boolean helper for SLOT1BINFULL(). @@ -4533,33 +4533,33 @@ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ static int method_is_overloaded(PyObject *left, PyObject *right, char *name) { - PyObject *a, *b; - int ok; + 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; - } + 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; - } + 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; - } + ok = PyObject_RichCompareBool(a, b, Py_NE); + Py_DECREF(a); + Py_DECREF(b); + if (ok < 0) { + PyErr_Clear(); + return 0; + } - return ok; + return ok; } @@ -4567,68 +4567,68 @@ method_is_overloaded(PyObject *left, PyObject *right, char *name) 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; \ + 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) + 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 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; + static PyObject *len_str; + PyObject *res = call_method(self, "__len__", &len_str, "()"); + Py_ssize_t len; - if (res == NULL) - return -1; - len = PyNumber_AsSsize_t(res, PyExc_OverflowError); - Py_DECREF(res); - if (len < 0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, - "__len__() should return >= 0"); - return -1; - } - return len; + if (res == NULL) + return -1; + len = PyNumber_AsSsize_t(res, PyExc_OverflowError); + 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. @@ -4636,93 +4636,93 @@ slot_sq_length(PyObject *self) 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 = PyUnicode_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 = PyLong_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 *getitem_str; + PyObject *func, *args = NULL, *ival = NULL, *retval = NULL; + descrgetfunc f; + + if (getitem_str == NULL) { + getitem_str = PyUnicode_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 = PyLong_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 int slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) { - PyObject *res; - static PyObject *delitem_str, *setitem_str; + 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; + 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_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; + 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 @@ -4732,19 +4732,19 @@ 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; + 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; + 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__") @@ -4756,25 +4756,25 @@ 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__") + nb_power, "__pow__", "__rpow__") static PyObject * slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) { - static PyObject *pow_str; + 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; + 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__") @@ -4784,52 +4784,52 @@ SLOT0(slot_nb_absolute, "__abs__") static int slot_nb_bool(PyObject *self) { - PyObject *func, *args; - static PyObject *bool_str, *len_str; - int result = -1; - int using_len = 0; - - func = lookup_maybe(self, "__bool__", &bool_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 (using_len) { - /* enforced by slot_nb_len */ - result = PyObject_IsTrue(temp); - } - else if (PyBool_Check(temp)) { - result = PyObject_IsTrue(temp); - } - else { - PyErr_Format(PyExc_TypeError, - "__bool__ should return " - "bool, returned %s", - Py_TYPE(temp)->tp_name); - result = -1; - } - Py_DECREF(temp); - } - } - Py_DECREF(func); - return result; + PyObject *func, *args; + static PyObject *bool_str, *len_str; + int result = -1; + int using_len = 0; + + func = lookup_maybe(self, "__bool__", &bool_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 (using_len) { + /* enforced by slot_nb_len */ + result = PyObject_IsTrue(temp); + } + else if (PyBool_Check(temp)) { + result = PyObject_IsTrue(temp); + } + else { + PyErr_Format(PyExc_TypeError, + "__bool__ should return " + "bool, returned %s", + Py_TYPE(temp)->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, "()"); + static PyObject *index_str; + return call_method(self, "__index__", &index_str, "()"); } @@ -4847,11 +4847,11 @@ SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O") SLOT1(slot_nb_inplace_multiply, "__imul__", 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); +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") @@ -4859,7 +4859,7 @@ 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__") + "__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") @@ -4867,90 +4867,90 @@ SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O") static PyObject * slot_tp_repr(PyObject *self) { - PyObject *func, *res; - static PyObject *repr_str; + 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 PyUnicode_FromFormat("<%s object at %p>", - Py_TYPE(self)->tp_name, self); + func = lookup_method(self, "__repr__", &repr_str); + if (func != NULL) { + res = PyEval_CallObject(func, NULL); + Py_DECREF(func); + return res; + } + PyErr_Clear(); + return PyUnicode_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 { - PyObject *ress; - PyErr_Clear(); - res = slot_tp_repr(self); - if (!res) - return NULL; - ress = _PyUnicode_AsDefaultEncodedString(res, NULL); - Py_DECREF(res); - return ress; - } + 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 { + PyObject *ress; + PyErr_Clear(); + res = slot_tp_repr(self); + if (!res) + return NULL; + ress = _PyUnicode_AsDefaultEncodedString(res, NULL); + Py_DECREF(res); + return ress; + } } static long slot_tp_hash(PyObject *self) { - PyObject *func, *res; - static PyObject *hash_str; - long h; + PyObject *func, *res; + static PyObject *hash_str; + long h; - func = lookup_method(self, "__hash__", &hash_str); + func = lookup_method(self, "__hash__", &hash_str); - if (func == Py_None) { - Py_DECREF(func); - func = NULL; - } + if (func == Py_None) { + Py_DECREF(func); + func = NULL; + } - if (func == NULL) { - return PyObject_HashNotImplemented(self); - } + if (func == NULL) { + return PyObject_HashNotImplemented(self); + } - 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 = PyLong_AsLong(res); - Py_DECREF(res); - if (h == -1 && !PyErr_Occurred()) - h = -2; - return h; + 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 = PyLong_AsLong(res); + Py_DECREF(res); + 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; + static PyObject *call_str; + PyObject *meth = lookup_method(self, "__call__", &call_str); + PyObject *res; - if (meth == NULL) - return NULL; + if (meth == NULL) + return NULL; - res = PyObject_Call(meth, args, kwds); + res = PyObject_Call(meth, args, kwds); - Py_DECREF(meth); - return res; + Py_DECREF(meth); + return res; } /* There are two slot dispatch functions for tp_getattro. @@ -4967,100 +4967,100 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) 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 *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; + 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; + 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 = PyUnicode_InternFromString("__getattr__"); - if (getattr_str == NULL) - return NULL; - } - if (getattribute_str == NULL) { - getattribute_str = - PyUnicode_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; + 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 = PyUnicode_InternFromString("__getattr__"); + if (getattr_str == NULL) + return NULL; + } + if (getattribute_str == NULL) { + getattribute_str = + PyUnicode_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; + 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; + 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[] = { @@ -5075,222 +5075,222 @@ static char *name_op[] = { static PyObject * slot_tp_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; + 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_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); + 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 *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 = PyUnicode_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); + PyTypeObject *tp = Py_TYPE(self); + PyObject *get; + static PyObject *get_str = NULL; + + if (get_str == NULL) { + get_str = PyUnicode_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; + 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; + 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 *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 = PyUnicode_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 PyObject *new_str; + PyObject *func; + PyObject *newargs, *x; + Py_ssize_t i, n; + + if (new_str == NULL) { + new_str = PyUnicode_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. - */ + 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; + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; #endif } @@ -5319,236 +5319,236 @@ typedef struct wrapperbase slotdef; #undef RBINSLOT #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(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} + {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)} + {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) + ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - ETSLOT(NAME, as_mapping.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) + 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) + 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") + 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") + 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") + 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) + 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) + ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ + "x." NAME "(y) <==> " DOC) static slotdef slotdefs[] = { - 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("__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("__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"), - - 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]"), - - 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("__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("__bool__", nb_bool, slot_nb_bool, 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, "|"), - UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, - "int(x)"), - UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, - "float(x)"), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, - "x[y:z] <==> x[y.__index__():z.__index__()]"), - 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("__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, "/"), - - TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, - "x.__str__() <==> str(x)"), - 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("__getattribute__", tp_getattro, slot_tp_getattr_hook, - wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), - TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), - TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), - TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), - TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, - "x.__setattr__('name', value) <==> x.name = value"), - TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, - "x.__delattr__('name') <==> del x.name"), - TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, - "x.__lt__(y) <==> x 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__() <==> next(x)"), - 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 x.__class__.__doc__ for signature", - PyWrapperFlag_KEYWORDS), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), - TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""), - {NULL} + 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("__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("__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"), + + 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]"), + + 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("__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("__bool__", nb_bool, slot_nb_bool, 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, "|"), + UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + "int(x)"), + UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + "float(x)"), + NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + "x[y:z] <==> x[y.__index__():z.__index__()]"), + 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("__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, "/"), + + TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + "x.__str__() <==> str(x)"), + 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("__getattribute__", tp_getattro, slot_tp_getattr_hook, + wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), + TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), + TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), + TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), + TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + "x.__setattr__('name', value) <==> x.name = value"), + TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + "x.__delattr__('name') <==> del x.name"), + TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + "x.__lt__(y) <==> x 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__() <==> next(x)"), + 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 x.__class__.__doc__ for signature", + PyWrapperFlag_KEYWORDS), + TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), + TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""), + {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 + 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; + 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 @@ -5562,37 +5562,37 @@ slotptr(PyTypeObject *type, int ioffset) 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; + /* 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 @@ -5604,81 +5604,81 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) 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) { - 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, PyDescr_TYPE(d))) - { - 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; + 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) { + 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, PyDescr_TYPE(d))) + { + 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. @@ -5686,11 +5686,11 @@ update_one_slot(PyTypeObject *type, slotdef *p) static int update_slots_callback(PyTypeObject *type, void *data) { - slotdef **pp = (slotdef **)data; + slotdef **pp = (slotdef **)data; - for (; *pp; pp++) - update_one_slot(type, *pp); - return 0; + for (; *pp; pp++) + update_one_slot(type, *pp); + return 0; } /* Comparison function for qsort() to compare slotdefs by their offset, and @@ -5698,14 +5698,14 @@ update_slots_callback(PyTypeObject *type, void *data) static int slotdef_cmp(const void *aa, const void *bb) { - const slotdef *a = (const slotdef *)aa, *b = (const slotdef *)bb; - int c = a->offset - b->offset; - if (c != 0) - return c; - else - /* Cannot use a-b, as this gives off_t, - which may lose precision when converted to int. */ - return (a > b) ? 1 : (a < b) ? -1 : 0; + const slotdef *a = (const slotdef *)aa, *b = (const slotdef *)bb; + int c = a->offset - b->offset; + if (c != 0) + return c; + else + /* Cannot use a-b, as this gives off_t, + which may lose precision when converted to int. */ + return (a > b) ? 1 : (a < b) ? -1 : 0; } /* Initialize the slotdefs table by adding interned string objects for the @@ -5713,56 +5713,56 @@ slotdef_cmp(const void *aa, const void *bb) static void init_slotdefs(void) { - slotdef *p; - static int initialized = 0; + slotdef *p; + static int initialized = 0; - if (initialized) - return; - for (p = slotdefs; p->name; p++) { - p->name_strobj = PyUnicode_InternFromString(p->name); - if (!p->name_strobj) - Py_FatalError("Out of memory interning slotdef names"); - } - qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), - slotdef_cmp); - initialized = 1; + if (initialized) + return; + for (p = slotdefs; p->name; p++) { + p->name_strobj = PyUnicode_InternFromString(p->name); + if (!p->name_strobj) + Py_FatalError("Out of memory interning slotdef names"); + } + qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), + slotdef_cmp); + 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); + 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) @@ -5771,23 +5771,23 @@ update_slot(PyTypeObject *type, PyObject *name) static void fixup_slot_dispatchers(PyTypeObject *type) { - slotdef *p; + slotdef *p; - init_slotdefs(); - for (p = slotdefs; p->name; ) - p = update_one_slot(type, p); + init_slotdefs(); + for (p = slotdefs; p->name; ) + p = update_one_slot(type, p); } static void update_all_slots(PyTypeObject* type) { - slotdef *p; + 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); - } + 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 @@ -5796,56 +5796,56 @@ update_all_slots(PyTypeObject* type) static int update_subclasses(PyTypeObject *type, PyObject *name, - update_callback callback, void *data) + update_callback callback, void *data) { - if (callback(type, data) < 0) - return -1; - return recurse_down_subclasses(type, name, callback, 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; + 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 + 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 encoutered wins. Since + In the latter case, the first slotdef entry encoutered 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 @@ -5868,344 +5868,344 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *name, 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; + 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; + 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} + {"__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; + 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); + _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; + superobject *su = (superobject *)self; - if (su->obj_type) - return PyUnicode_FromFormat( - ", <%s object>>", - su->type ? su->type->tp_name : "NULL", - su->obj_type->tp_name); - else - return PyUnicode_FromFormat( - ", NULL>", - su->type ? su->type->tp_name : "NULL"); + if (su->obj_type) + return PyUnicode_FromFormat( + ", <%s object>>", + su->type ? su->type->tp_name : "NULL", + su->obj_type->tp_name); + else + return PyUnicode_FromFormat( + ", 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 = (PyUnicode_Check(name) && - PyUnicode_GET_SIZE(name) == 9 && - PyUnicode_CompareWithASCIIString(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 - 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); + 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 = (PyUnicode_Check(name) && + PyUnicode_GET_SIZE(name) == 9 && + PyUnicode_CompareWithASCIIString(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 + 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 = PyUnicode_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; + /* 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 = PyUnicode_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; - } + 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 = NULL; - 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; - + superobject *su = (superobject *)self; + PyTypeObject *type = NULL; + 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 (type == NULL) { + /* Call super(), without args -- fill in from __class__ + and first local variable on the stack. */ + PyFrameObject *f = PyThreadState_GET()->frame; + PyCodeObject *co = f->f_code; + int i, n; + if (co == NULL) { + PyErr_SetString(PyExc_SystemError, + "super(): no code object"); + return -1; + } + if (co->co_argcount == 0) { + PyErr_SetString(PyExc_SystemError, + "super(): no arguments"); + return -1; + } + obj = f->f_localsplus[0]; + if (obj == NULL) { + PyErr_SetString(PyExc_SystemError, + "super(): arg[0] deleted"); + return -1; + } + if (co->co_freevars == NULL) + n = 0; + else { + assert(PyTuple_Check(co->co_freevars)); + n = PyTuple_GET_SIZE(co->co_freevars); + } + for (i = 0; i < n; i++) { + PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); + assert(PyUnicode_Check(name)); + if (!PyUnicode_CompareWithASCIIString(name, + "__class__")) { + Py_ssize_t index = co->co_nlocals + + PyTuple_GET_SIZE(co->co_cellvars) + i; + PyObject *cell = f->f_localsplus[index]; + if (cell == NULL || !PyCell_Check(cell)) { + PyErr_SetString(PyExc_SystemError, + "super(): bad __class__ cell"); + return -1; + } + type = (PyTypeObject *) PyCell_GET(cell); + if (type == NULL) { + PyErr_SetString(PyExc_SystemError, + "super(): empty __class__ cell"); + return -1; + } + if (!PyType_Check(type)) { + PyErr_Format(PyExc_SystemError, + "super(): __class__ is not a type (%s)", + Py_TYPE(type)->tp_name); + return -1; + } + break; + } + } if (type == NULL) { - /* Call super(), without args -- fill in from __class__ - and first local variable on the stack. */ - PyFrameObject *f = PyThreadState_GET()->frame; - PyCodeObject *co = f->f_code; - int i, n; - if (co == NULL) { - PyErr_SetString(PyExc_SystemError, - "super(): no code object"); - return -1; - } - if (co->co_argcount == 0) { - PyErr_SetString(PyExc_SystemError, - "super(): no arguments"); - return -1; - } - obj = f->f_localsplus[0]; - if (obj == NULL) { - PyErr_SetString(PyExc_SystemError, - "super(): arg[0] deleted"); - return -1; - } - if (co->co_freevars == NULL) - n = 0; - else { - assert(PyTuple_Check(co->co_freevars)); - n = PyTuple_GET_SIZE(co->co_freevars); - } - for (i = 0; i < n; i++) { - PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); - assert(PyUnicode_Check(name)); - if (!PyUnicode_CompareWithASCIIString(name, - "__class__")) { - Py_ssize_t index = co->co_nlocals + - PyTuple_GET_SIZE(co->co_cellvars) + i; - PyObject *cell = f->f_localsplus[index]; - if (cell == NULL || !PyCell_Check(cell)) { - PyErr_SetString(PyExc_SystemError, - "super(): bad __class__ cell"); - return -1; - } - type = (PyTypeObject *) PyCell_GET(cell); - if (type == NULL) { - PyErr_SetString(PyExc_SystemError, - "super(): empty __class__ cell"); - return -1; - } - if (!PyType_Check(type)) { - PyErr_Format(PyExc_SystemError, - "super(): __class__ is not a type (%s)", - Py_TYPE(type)->tp_name); - return -1; - } - break; - } - } - if (type == NULL) { - PyErr_SetString(PyExc_SystemError, - "super(): __class__ cell not found"); - return -1; - } + PyErr_SetString(PyExc_SystemError, + "super(): __class__ cell not found"); + 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; + } + + 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, @@ -6216,65 +6216,65 @@ PyDoc_STRVAR(super_doc, "Typical use to call a cooperative superclass method:\n" "class C(B):\n" " def meth(self, arg):\n" -" super().meth(arg)\n" +" super().meth(arg)\n" "This works for class methods too:\n" "class C(B):\n" " @classmethod\n" " def cmeth(cls, arg):\n" -" super().cmeth(arg)\n"); +" super().cmeth(arg)\n"); static int super_traverse(PyObject *self, visitproc visit, void *arg) { - superobject *su = (superobject *)self; + superobject *su = (superobject *)self; - Py_VISIT(su->obj); - Py_VISIT(su->type); - Py_VISIT(su->obj_type); + Py_VISIT(su->obj); + Py_VISIT(su->type); + Py_VISIT(su->obj_type); - return 0; + 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_reserved */ - 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 */ + 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_reserved */ + 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/Objects/weakrefobject.c b/Objects/weakrefobject.c index 27f015d3a0..f43b68d607 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -57,9 +57,9 @@ clear_weakref(PyWeakReference *self) PyWeakref_GET_OBJECT(self)); 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. */ + /* 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) @@ -161,21 +161,21 @@ weakref_repr(PyWeakReference *self) PyOS_snprintf(buffer, sizeof(buffer), "", self); } else { - char *name = NULL; - PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self), - "__name__"); - if (nameobj == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(nameobj)) - name = _PyUnicode_AsString(nameobj); + char *name = NULL; + PyObject *nameobj = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self), + "__name__"); + if (nameobj == NULL) + PyErr_Clear(); + else if (PyUnicode_Check(nameobj)) + name = _PyUnicode_AsString(nameobj); PyOS_snprintf(buffer, sizeof(buffer), - name ? "" - : "", - self, - Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self), - name); - Py_XDECREF(nameobj); + name ? "" + : "", + self, + Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, + PyWeakref_GET_OBJECT(self), + name); + Py_XDECREF(nameobj); } return PyUnicode_FromString(buffer); } @@ -188,8 +188,8 @@ static PyObject * weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) { if ((op != Py_EQ && op != Py_NE) || - !PyWeakref_Check(self) || - !PyWeakref_Check(other)) { + !PyWeakref_Check(self) || + !PyWeakref_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -339,10 +339,10 @@ _PyWeakref_RefType = { sizeof(PyWeakReference), 0, weakref_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_reserved*/ (reprfunc)weakref_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -358,7 +358,7 @@ _PyWeakref_RefType = { 0, /*tp_doc*/ (traverseproc)gc_traverse, /*tp_traverse*/ (inquiry)gc_clear, /*tp_clear*/ - (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ + (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ @@ -438,9 +438,9 @@ proxy_checkref(PyWeakReference *proxy) #define WRAP_METHOD(method, special) \ static PyObject * \ method(PyObject *proxy) { \ - UNWRAP(proxy); \ - return PyObject_CallMethod(proxy, special, ""); \ - } + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } /* direct slots */ @@ -454,9 +454,9 @@ proxy_repr(PyWeakReference *proxy) { char buf[160]; PyOS_snprintf(buf, sizeof(buf), - "", proxy, - Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name, - PyWeakref_GET_OBJECT(proxy)); + "", proxy, + Py_TYPE(PyWeakref_GET_OBJECT(proxy))->tp_name, + PyWeakref_GET_OBJECT(proxy)); return PyUnicode_FromString(buf); } @@ -587,8 +587,8 @@ WRAP_METHOD(proxy_bytes, "__bytes__"); static PyMethodDef proxy_methods[] = { - {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, - {NULL, NULL} + {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, + {NULL, NULL} }; @@ -636,7 +636,7 @@ static PySequenceMethods proxy_as_sequence = { 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ + 0, /*sq_ass_slice*/ (objobjproc)proxy_contains, /* sq_contains */ }; @@ -655,20 +655,20 @@ _PyWeakref_ProxyType = { 0, /* methods */ (destructor)proxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gc_traverse, /* tp_traverse */ @@ -677,7 +677,7 @@ _PyWeakref_ProxyType = { 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ - proxy_methods, /* tp_methods */ + proxy_methods, /* tp_methods */ }; @@ -689,20 +689,20 @@ _PyWeakref_CallableProxyType = { 0, /* methods */ (destructor)proxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gc_traverse, /* tp_traverse */ @@ -724,7 +724,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, - "cannot create weak reference to '%s' object", + "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); return NULL; } @@ -783,7 +783,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, - "cannot create weak reference to '%s' object", + "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); return NULL; } @@ -908,7 +908,7 @@ PyObject_ClearWeakRefs(PyObject *object) else { PyObject *tuple; Py_ssize_t i = 0; - + tuple = PyTuple_New(count * 2); if (tuple == NULL) { if (restore_error) -- cgit v1.2.1 From 157e13060e13dd7673dfb648952b4668aca33893 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 10 May 2010 21:27:53 +0000 Subject: Merged revisions 81036 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81036 | mark.dickinson | 2010-05-09 21:30:29 +0100 (Sun, 09 May 2010) | 1 line Post-detabification cleanup: whitespace fixes and long line rewraps only. ........ --- Objects/longobject.c | 203 +++++++++++++++++++++++++-------------------------- 1 file changed, 101 insertions(+), 102 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index d4b26d65b9..ca069f60dc 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -278,12 +278,12 @@ PyLong_FromDouble(double dval) neg = 0; if (Py_IS_INFINITY(dval)) { PyErr_SetString(PyExc_OverflowError, - "cannot convert float infinity to integer"); + "cannot convert float infinity to integer"); return NULL; } if (Py_IS_NAN(dval)) { PyErr_SetString(PyExc_ValueError, - "cannot convert float NaN to integer"); + "cannot convert float NaN to integer"); return NULL; } if (dval < 0.0) { @@ -404,7 +404,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) /* res is already set to -1 */ } } - exit: + exit: if (do_decref) { Py_DECREF(vv); } @@ -474,7 +474,7 @@ PyLong_AsSsize_t(PyObject *vv) { } /* else overflow */ - overflow: + overflow: PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C ssize_t"); return -1; @@ -504,7 +504,7 @@ PyLong_AsUnsignedLong(PyObject *vv) x = 0; if (i < 0) { PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned int"); + "can't convert negative value to unsigned int"); return (unsigned long) -1; } switch (i) { @@ -516,7 +516,8 @@ PyLong_AsUnsignedLong(PyObject *vv) x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, - "python int too large to convert to C unsigned long"); + "python int too large to convert " + "to C unsigned long"); return (unsigned long) -1; } } @@ -671,7 +672,7 @@ _PyLong_NumBits(PyObject *vv) } return result; -Overflow: + Overflow: PyErr_SetString(PyExc_OverflowError, "int has too many bits " "to express in a platform size_t"); return (size_t)-1; @@ -681,7 +682,7 @@ PyObject * _PyLong_FromByteArray(const unsigned char* bytes, size_t n, int little_endian, int is_signed) { - const unsigned char* pstartbyte;/* LSB of bytes */ + const unsigned char* pstartbyte; /* LSB of bytes */ int incr; /* direction to move pstartbyte */ const unsigned char* pendbyte; /* MSB of bytes */ size_t numsignificantbytes; /* number of bytes that matter */ @@ -769,8 +770,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, if (accumbits >= PyLong_SHIFT) { /* There's enough to fill a Python digit. */ assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)(accum & - PyLong_MASK); + v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); ++idigit; accum >>= PyLong_SHIFT; accumbits -= PyLong_SHIFT; @@ -795,9 +795,9 @@ _PyLong_AsByteArray(PyLongObject* v, int little_endian, int is_signed) { Py_ssize_t i; /* index into v->ob_digit */ - Py_ssize_t ndigits; /* |v->ob_size| */ + Py_ssize_t ndigits; /* |v->ob_size| */ twodigits accum; /* sliding register */ - unsigned int accumbits; /* # bits in accum */ + unsigned int accumbits; /* # bits in accum */ int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ digit carry; /* for computing 2's-comp */ size_t j; /* # bytes filled */ @@ -810,7 +810,7 @@ _PyLong_AsByteArray(PyLongObject* v, ndigits = -(Py_SIZE(v)); if (!is_signed) { PyErr_SetString(PyExc_OverflowError, - "can't convert negative int to unsigned"); + "can't convert negative int to unsigned"); return -1; } do_twos_comp = 1; @@ -856,8 +856,7 @@ _PyLong_AsByteArray(PyLongObject* v, /* Count # of sign bits -- they needn't be stored, * although for signed conversion we need later to * make sure at least one sign bit gets stored. */ - digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : - thisdigit; + digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit; while (s != 0) { s >>= 1; accumbits++; @@ -917,7 +916,7 @@ _PyLong_AsByteArray(PyLongObject* v, return 0; -Overflow: + Overflow: PyErr_SetString(PyExc_OverflowError, "int too big to convert"); return -1; @@ -986,7 +985,7 @@ PyLong_AsVoidPtr(PyObject *vv) */ #define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one -#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) +#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) /* Create a new long int object from a C PY_LONG_LONG int. */ @@ -1172,9 +1171,8 @@ PyLong_AsLongLong(PyObject *vv) case 0: return 0; case 1: return v->ob_digit[0]; } - res = _PyLong_AsByteArray( - (PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@ -1205,9 +1203,8 @@ PyLong_AsUnsignedLongLong(PyObject *vv) case 1: return v->ob_digit[0]; } - res = _PyLong_AsByteArray( - (PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@ -1373,7 +1370,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) /* res is already set to -1 */ } } - exit: + exit: if (do_decref) { Py_DECREF(vv); } @@ -1600,9 +1597,9 @@ long_to_decimal_string(PyObject *aa) } /* check for keyboard interrupt */ SIGCHECK({ - Py_DECREF(scratch); - return NULL; - }) + Py_DECREF(scratch); + return NULL; + }) } /* pout should have at least one digit, so that the case when a = 0 works correctly */ @@ -1998,8 +1995,8 @@ digit beyond the first. twodigits convmax = base; int i = 1; - log_base_BASE[base] = log((double)base) / - log((double)PyLong_BASE); + log_base_BASE[base] = (log((double)base) / + log((double)PyLong_BASE)); for (;;) { twodigits next = convmax * base; if (next > PyLong_BASE) @@ -2043,7 +2040,7 @@ digit beyond the first. c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; for (i = 1; i < convwidth && str != scan; ++i, ++str) { c = (twodigits)(c * base + - (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); + (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); assert(c < PyLong_BASE); } @@ -2116,7 +2113,7 @@ digit beyond the first. long_normalize(z); return (PyObject *) maybe_small_long(z); - onError: + onError: Py_XDECREF(z); slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; strobj = PyUnicode_FromStringAndSize(orig_str, slen); @@ -2272,12 +2269,12 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) single-digit quotient q, remainder in vk[0:size_w]. */ SIGCHECK({ - Py_DECREF(a); - Py_DECREF(w); - Py_DECREF(v); - *prem = NULL; - return NULL; - }) + Py_DECREF(a); + Py_DECREF(w); + Py_DECREF(v); + *prem = NULL; + return NULL; + }) /* estimate quotient digit q; may overestimate by 1 (rare) */ vtop = vk[size_w]; @@ -2303,7 +2300,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) (stwodigits)q * (stwodigits)w0[i]; vk[i] = (digit)z & PyLong_MASK; zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits, - z, PyLong_SHIFT); + z, PyLong_SHIFT); } /* add w back if q was too large (this branch taken rarely) */ @@ -2370,7 +2367,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 || a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1)) - goto overflow; + goto overflow; a_bits = (a_size - 1) * PyLong_SHIFT + a_bits; /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size] @@ -2428,7 +2425,8 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) break; } } - assert(1 <= x_size && x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit))); + assert(1 <= x_size && + x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit))); /* Round, and convert to double. */ x_digits[0] += half_even_correction[x_digits[0] & 7]; @@ -2603,8 +2601,8 @@ x_add(PyLongObject *a, PyLongObject *b) if (size_a < size_b) { { PyLongObject *temp = a; a = b; b = temp; } { Py_ssize_t size_temp = size_a; - size_a = size_b; - size_b = size_temp; } + size_a = size_b; + size_b = size_temp; } } z = _PyLong_New(size_a+1); if (z == NULL) @@ -2639,8 +2637,8 @@ x_sub(PyLongObject *a, PyLongObject *b) sign = -1; { PyLongObject *temp = a; a = b; b = temp; } { Py_ssize_t size_temp = size_a; - size_a = size_b; - size_b = size_temp; } + size_a = size_b; + size_b = size_temp; } } else if (size_a == size_b) { /* Find highest digit where a and b differ: */ @@ -2768,9 +2766,9 @@ x_mul(PyLongObject *a, PyLongObject *b) digit *paend = a->ob_digit + size_a; SIGCHECK({ - Py_DECREF(z); - return NULL; - }) + Py_DECREF(z); + return NULL; + }) carry = *pz + f * f; *pz++ = (digit)(carry & PyLong_MASK); @@ -2806,9 +2804,9 @@ x_mul(PyLongObject *a, PyLongObject *b) digit *pbend = b->ob_digit + size_b; SIGCHECK({ - Py_DECREF(z); - return NULL; - }) + Py_DECREF(z); + return NULL; + }) while (pb < pbend) { carry += *pz + *pb++ * f; @@ -2832,7 +2830,10 @@ x_mul(PyLongObject *a, PyLongObject *b) Returns 0 on success, -1 on failure. */ static int -kmul_split(PyLongObject *n, Py_ssize_t size, PyLongObject **high, PyLongObject **low) +kmul_split(PyLongObject *n, + Py_ssize_t size, + PyLongObject **high, + PyLongObject **low) { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; @@ -3021,7 +3022,7 @@ k_mul(PyLongObject *a, PyLongObject *b) return long_normalize(ret); - fail: + fail: Py_XDECREF(ret); Py_XDECREF(ah); Py_XDECREF(al); @@ -3131,7 +3132,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) Py_DECREF(bslice); return long_normalize(ret); - fail: + fail: Py_DECREF(ret); Py_XDECREF(bslice); return NULL; @@ -3414,7 +3415,7 @@ long_true_divide(PyObject *v, PyObject *w) here. Both a and b would have to be enormous, using close to SIZE_T_MAX bytes of memory each. */ PyErr_SetString(PyExc_OverflowError, - "intermediate overflow during division"); + "intermediate overflow during division"); goto error; } x = _PyLong_New(a_size + shift_digits + 1); @@ -3578,7 +3579,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (Py_SIZE(b) < 0) { /* if exponent is negative */ if (c) { PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " - "cannot be negative when 3rd argument specified"); + "cannot be negative when 3rd argument specified"); goto Error; } else { @@ -3708,13 +3709,13 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) } goto Done; - Error: + Error: if (z != NULL) { Py_DECREF(z); z = NULL; } /* fall through */ - Done: + Done: if (Py_SIZE(b) > FIVEARY_CUTOFF) { for (i = 0; i < 32; ++i) Py_XDECREF(table[i]); @@ -3819,12 +3820,11 @@ long_rshift(PyLongObject *a, PyLongObject *b) for (i = 0, j = wordshift; i < newsize; i++, j++) { z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; if (i+1 < newsize) - z->ob_digit[i] |= - (a->ob_digit[j+1] << hishift) & himask; + z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; } z = long_normalize(z); } -rshift_error: + rshift_error: return (PyObject *) maybe_small_long(z); } @@ -3874,7 +3874,7 @@ long_lshift(PyObject *v, PyObject *w) else assert(!accum); z = long_normalize(z); -lshift_error: + lshift_error: return (PyObject *) maybe_small_long(z); } @@ -3900,7 +3900,7 @@ v_complement(digit *z, digit *a, Py_ssize_t m) static PyObject * long_bitwise(PyLongObject *a, int op, /* '&', '|', '^' */ - PyLongObject *b) + PyLongObject *b) { int nega, negb, negz; Py_ssize_t size_a, size_b, size_z, i; @@ -4103,15 +4103,15 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* We only see this if there's a null byte in x, x is a bytes or buffer, *and* a base is given. */ PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", - base, x); + "invalid literal for int() with base %d: %R", + base, x); return NULL; } return PyLong_FromString(string, NULL, base); } else { PyErr_SetString(PyExc_TypeError, - "int() can't convert non-string with explicit base"); + "int() can't convert non-string with explicit base"); return NULL; } } @@ -4371,7 +4371,7 @@ long_bit_length(PyLongObject *v) return (PyObject *)result; -error: + error: Py_DECREF(result); return NULL; } @@ -4633,40 +4633,40 @@ string, use the optional base. It is an error to supply a base when\n\ converting a non-string."); static PyNumberMethods long_as_number = { - (binaryfunc) long_add, /*nb_add*/ - (binaryfunc) long_sub, /*nb_subtract*/ - (binaryfunc) long_mul, /*nb_multiply*/ - long_mod, /*nb_remainder*/ - long_divmod, /*nb_divmod*/ - long_pow, /*nb_power*/ - (unaryfunc) long_neg, /*nb_negative*/ - (unaryfunc) long_long, /*tp_positive*/ - (unaryfunc) long_abs, /*tp_absolute*/ - (inquiry) long_bool, /*tp_bool*/ - (unaryfunc) long_invert, /*nb_invert*/ - long_lshift, /*nb_lshift*/ - (binaryfunc) long_rshift, /*nb_rshift*/ - long_and, /*nb_and*/ - long_xor, /*nb_xor*/ - long_or, /*nb_or*/ - long_long, /*nb_int*/ - 0, /*nb_reserved*/ - long_float, /*nb_float*/ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 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 */ - long_div, /* nb_floor_divide */ - long_true_divide, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - long_long, /* nb_index */ + (binaryfunc)long_add, /*nb_add*/ + (binaryfunc)long_sub, /*nb_subtract*/ + (binaryfunc)long_mul, /*nb_multiply*/ + long_mod, /*nb_remainder*/ + long_divmod, /*nb_divmod*/ + long_pow, /*nb_power*/ + (unaryfunc)long_neg, /*nb_negative*/ + (unaryfunc)long_long, /*tp_positive*/ + (unaryfunc)long_abs, /*tp_absolute*/ + (inquiry)long_bool, /*tp_bool*/ + (unaryfunc)long_invert, /*nb_invert*/ + long_lshift, /*nb_lshift*/ + (binaryfunc)long_rshift, /*nb_rshift*/ + long_and, /*nb_and*/ + long_xor, /*nb_xor*/ + long_or, /*nb_or*/ + long_long, /*nb_int*/ + 0, /*nb_reserved*/ + long_float, /*nb_float*/ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 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 */ + long_div, /* nb_floor_divide */ + long_true_divide, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + long_long, /* nb_index */ }; PyTypeObject PyLong_Type = { @@ -4722,8 +4722,7 @@ internal representation of integers. The attributes are read only."); static PyStructSequence_Field int_info_fields[] = { {"bits_per_digit", "size of a digit in bits"}, - {"sizeof_digit", "size in bytes of the C type used to " - "represent a digit"}, + {"sizeof_digit", "size in bytes of the C type used to represent a digit"}, {NULL, NULL} }; -- cgit v1.2.1 From 5d081a09b01f67ed9b1440e63bbf292699a02689 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 10 May 2010 21:37:34 +0000 Subject: Merged revisions 81037 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81037 | mark.dickinson | 2010-05-09 21:42:09 +0100 (Sun, 09 May 2010) | 1 line Wrap multiline macros in a 'do {} while(0)', for safety. ........ --- Objects/longobject.c | 72 ++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 33 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index ca069f60dc..850396b8ef 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -95,8 +95,10 @@ maybe_small_long(PyLongObject *v) #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) > (y) ? (y) : (x)) -#define SIGCHECK(PyTryBlock) \ - if (PyErr_CheckSignals()) PyTryBlock \ +#define SIGCHECK(PyTryBlock) \ + do { \ + if (PyErr_CheckSignals()) PyTryBlock \ + } while(0) /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature @@ -1379,11 +1381,13 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) #endif /* HAVE_LONG_LONG */ -#define CHECK_BINOP(v,w) \ - if (!PyLong_Check(v) || !PyLong_Check(w)) { \ - Py_INCREF(Py_NotImplemented); \ - return Py_NotImplemented; \ - } +#define CHECK_BINOP(v,w) \ + do { \ + if (!PyLong_Check(v) || !PyLong_Check(w)) { \ + Py_INCREF(Py_NotImplemented); \ + return Py_NotImplemented; \ + } \ + } while(0) /* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < 2**k if d is nonzero, else 0. */ @@ -1599,7 +1603,7 @@ long_to_decimal_string(PyObject *aa) SIGCHECK({ Py_DECREF(scratch); return NULL; - }) + }); } /* pout should have at least one digit, so that the case when a = 0 works correctly */ @@ -2274,7 +2278,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) Py_DECREF(v); *prem = NULL; return NULL; - }) + }); /* estimate quotient digit q; may overestimate by 1 (rare) */ vtop = vk[size_w]; @@ -2768,7 +2772,7 @@ x_mul(PyLongObject *a, PyLongObject *b) SIGCHECK({ Py_DECREF(z); return NULL; - }) + }); carry = *pz + f * f; *pz++ = (digit)(carry & PyLong_MASK); @@ -2806,7 +2810,7 @@ x_mul(PyLongObject *a, PyLongObject *b) SIGCHECK({ Py_DECREF(z); return NULL; - }) + }); while (pb < pbend) { carry += *pz + *pb++ * f; @@ -3645,26 +3649,28 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) * is NULL. */ #define REDUCE(X) \ - if (c != NULL) { \ - if (l_divmod(X, c, NULL, &temp) < 0) \ - goto Error; \ - Py_XDECREF(X); \ - X = temp; \ - temp = NULL; \ - } + do { \ + if (c != NULL) { \ + if (l_divmod(X, c, NULL, &temp) < 0) \ + goto Error; \ + Py_XDECREF(X); \ + X = temp; \ + temp = NULL; \ + } \ + } while(0) /* Multiply two values, then reduce the result: result = X*Y % c. If c is NULL, skip the mod. */ -#define MULT(X, Y, result) \ -{ \ - temp = (PyLongObject *)long_mul(X, Y); \ - if (temp == NULL) \ - goto Error; \ - Py_XDECREF(result); \ - result = temp; \ - temp = NULL; \ - REDUCE(result) \ -} +#define MULT(X, Y, result) \ + do { \ + temp = (PyLongObject *)long_mul(X, Y); \ + if (temp == NULL) \ + goto Error; \ + Py_XDECREF(result); \ + result = temp; \ + temp = NULL; \ + REDUCE(result); \ + } while(0) if (Py_SIZE(b) <= FIVEARY_CUTOFF) { /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ @@ -3673,9 +3679,9 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) digit bi = b->ob_digit[i]; for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) { - MULT(z, z, z) + MULT(z, z, z); if (bi & j) - MULT(z, a, z) + MULT(z, a, z); } } } @@ -3684,7 +3690,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_INCREF(z); /* still holds 1L */ table[0] = z; for (i = 1; i < 32; ++i) - MULT(table[i-1], a, table[i]) + MULT(table[i-1], a, table[i]); for (i = Py_SIZE(b) - 1; i >= 0; --i) { const digit bi = b->ob_digit[i]; @@ -3692,9 +3698,9 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { const int index = (bi >> j) & 0x1f; for (k = 0; k < 5; ++k) - MULT(z, z, z) + MULT(z, z, z); if (index) - MULT(z, table[index], z) + MULT(z, table[index], z); } } } -- cgit v1.2.1 From 377bd5c569fa9b359109e1df4fcf5277f4070b90 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 15 May 2010 13:14:32 +0000 Subject: Enable shortcuts for common encodings in PyUnicode_AsEncodedString() for any error handler, not only the default error handler (strict) --- Objects/unicodeobject.c | 54 ++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 23 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 23b322f304..307027a811 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1476,31 +1476,39 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, 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 (strcmp(encoding, "utf-8") == 0) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + else if (strcmp(encoding, "latin-1") == 0) + return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(encoding, "mbcs") == 0) - return PyUnicode_AsMBCSString(unicode); + else if (strcmp(encoding, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #endif - else if (strcmp(encoding, "ascii") == 0) - return PyUnicode_AsASCIIString(unicode); - /* During bootstrap, we may need to find the encodings - package, to load the file system encoding, and require the - file system encoding in order to load the encodings - package. - - Break out of this dependency by assuming that the path to - the encodings module is ASCII-only. XXX could try wcstombs - instead, if the file system encoding is the locale's - encoding. */ - else if (Py_FileSystemDefaultEncoding && - strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && - !PyThreadState_GET()->interp->codecs_initialized) - return PyUnicode_AsASCIIString(unicode); - } + else if (strcmp(encoding, "ascii") == 0) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + /* During bootstrap, we may need to find the encodings + package, to load the file system encoding, and require the + file system encoding in order to load the encodings + package. + + Break out of this dependency by assuming that the path to + the encodings module is ASCII-only. XXX could try wcstombs + instead, if the file system encoding is the locale's + encoding. */ + else if (Py_FileSystemDefaultEncoding && + strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && + !PyThreadState_GET()->interp->codecs_initialized) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); /* Encode via the codec registry */ v = PyCodec_Encode(unicode, encoding, errors); -- cgit v1.2.1 From 54567ad24842b6c6c98423b6614d22b0de784915 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 15 May 2010 16:27:27 +0000 Subject: Issue #8715: Create PyUnicode_EncodeFSDefault() function: Encode a Unicode object to Py_FileSystemDefaultEncoding with the "surrogateescape" error handler, return a bytes object. If Py_FileSystemDefaultEncoding is not set, fall back to UTF-8. --- Objects/unicodeobject.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 307027a811..b97621b934 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1461,6 +1461,18 @@ PyObject *PyUnicode_AsEncodedObject(PyObject *unicode, return NULL; } +PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) +{ + if (Py_FileSystemDefaultEncoding) + return PyUnicode_AsEncodedString(unicode, + Py_FileSystemDefaultEncoding, + "surrogateescape"); + else + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + "surrogateescape"); +} + PyObject *PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) @@ -1646,9 +1658,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) arg = PyUnicode_FromObject(arg); if (!arg) return 0; - output = PyUnicode_AsEncodedObject(arg, - Py_FileSystemDefaultEncoding, - "surrogateescape"); + output = PyUnicode_EncodeFSDefault(arg); Py_DECREF(arg); if (!output) return 0; -- cgit v1.2.1 From 66046bbcf9c795d76c75dcb5d518305d2f0c957c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 17 May 2010 01:26:01 +0000 Subject: PyObject_Dump() encodes unicode objects to utf8 with backslashreplace (instead of strict) error handler to escape surrogates --- Objects/object.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 8ddc7ec78c..1f4e3dd445 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -303,7 +303,9 @@ internal_print(PyObject *op, FILE *fp, int flags, int nesting) } else if (PyUnicode_Check(s)) { PyObject *t; - t = _PyUnicode_AsDefaultEncodedString(s, NULL); + t = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(s), + PyUnicode_GET_SIZE(s), + "backslashreplace"); if (t == NULL) ret = 0; else { -- cgit v1.2.1 From fba08c6e676328b3d9ae51df4de643f19df7f652 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 17 May 2010 09:33:42 +0000 Subject: Fix refleak in internal_print() introduced by myself in r81251 _PyUnicode_AsDefaultEncodedString() uses a magical PyUnicode attribute to automatically destroy PyUnicode_EncodeUTF8() result when the unicode string is destroyed. --- Objects/object.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 1f4e3dd445..7907a8e566 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -311,6 +311,7 @@ internal_print(PyObject *op, FILE *fp, int flags, int nesting) else { fwrite(PyBytes_AS_STRING(t), 1, PyBytes_GET_SIZE(t), fp); + Py_DECREF(t); } } else { -- cgit v1.2.1 From eccd1c0fb2d70544c806f4a262b173c3c53ff01d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 May 2010 00:03:09 +0000 Subject: Issue #6697: Fix a crash if a module attribute name contains a surrogate --- Objects/moduleobject.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 9ef7339c14..6c6eac1c8d 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -263,10 +263,15 @@ _PyModule_Clear(PyObject *m) pos = 0; while (PyDict_Next(d, &pos, &key, &value)) { if (value != Py_None && PyUnicode_Check(key)) { - const char *s = _PyUnicode_AsString(key); - if (s[0] == '_' && s[1] != '_') { - if (Py_VerboseFlag > 1) - PySys_WriteStderr("# clear[1] %s\n", s); + Py_UNICODE *u = PyUnicode_AS_UNICODE(key); + if (u[0] == '_' && u[1] != '_') { + if (Py_VerboseFlag > 1) { + const char *s = _PyUnicode_AsString(key); + if (s != NULL) + PySys_WriteStderr("# clear[1] %s\n", s); + else + PyErr_Clear(); + } PyDict_SetItem(d, key, Py_None); } } @@ -276,10 +281,17 @@ _PyModule_Clear(PyObject *m) pos = 0; while (PyDict_Next(d, &pos, &key, &value)) { if (value != Py_None && PyUnicode_Check(key)) { - const char *s = _PyUnicode_AsString(key); - if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { - if (Py_VerboseFlag > 1) - PySys_WriteStderr("# clear[2] %s\n", s); + Py_UNICODE *u = PyUnicode_AS_UNICODE(key); + if (u[0] != '_' + || PyUnicode_CompareWithASCIIString(key, "__builtins__") != 0) + { + if (Py_VerboseFlag > 1) { + const char *s = _PyUnicode_AsString(key); + if (s != NULL) + PySys_WriteStderr("# clear[2] %s\n", s); + else + PyErr_Clear(); + } PyDict_SetItem(d, key, Py_None); } } -- cgit v1.2.1 From 266f7ae2a1615e7758dc796568b765de90edddfa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 May 2010 01:42:46 +0000 Subject: Issue #6697: Check that _PyUnicode_AsString() result is not NULL in typeobject Type name and slots are already checked for surrogates somewhere else, but it's better to ensure that the result is not NULL. --- Objects/typeobject.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2ec9829231..3dfc037aa7 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1347,8 +1347,14 @@ 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 ? _PyUnicode_AsString(name) : "?"); + char *name_str; + if (name != NULL) { + name_str = _PyUnicode_AsString(name); + if (name_str == NULL) + name_str = "?" + } else + name_str = "?" + off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s", name_str); Py_XDECREF(name); if (--n && (size_t)(off+1) < sizeof(buf)) { buf[off++] = ','; @@ -2220,6 +2226,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) for (i = 0; i < nslots; i++, mp++) { mp->name = _PyUnicode_AsString( PyTuple_GET_ITEM(slots, i)); + if (mp->name == NULL) { + Py_DECREF(type); + return NULL; + } mp->type = T_OBJECT_EX; mp->offset = slotoffset; -- cgit v1.2.1 From e3662b0e7ef885d8e04dc8fcc3b7040bdeff6b76 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 19 May 2010 01:50:45 +0000 Subject: Ooops, add missing ";" in my previous commit (r81324, typeobject.c) It's time to go to bed... --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3dfc037aa7..369bac6bb9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1351,9 +1351,9 @@ consistent method resolution\norder (MRO) for bases"); if (name != NULL) { name_str = _PyUnicode_AsString(name); if (name_str == NULL) - name_str = "?" + name_str = "?"; } else - name_str = "?" + name_str = "?"; off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s", name_str); Py_XDECREF(name); if (--n && (size_t)(off+1) < sizeof(buf)) { -- cgit v1.2.1 From c596f8c7c02617d190cead99793f8050ca52c949 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 21 May 2010 14:55:26 +0000 Subject: Issue #8748: Fix two issues with comparisons between complex and integer objects. (1) The comparison could incorrectly return True in some cases (2**53+1 == complex(2**53) == 2**53), breaking transivity of equality. (2) The comparison raised an OverflowError for large integers, leading to unpredictable exceptions when combining integers and complex objects in sets or dicts. Patch by Meador Inge. --- Objects/complexobject.c | 52 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index ec26e0a700..9e1e217856 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -620,22 +620,58 @@ static PyObject * complex_richcompare(PyObject *v, PyObject *w, int op) { PyObject *res; - Py_complex i, j; - TO_COMPLEX(v, i); - TO_COMPLEX(w, j); + Py_complex i; + int equal; if (op != Py_EQ && op != Py_NE) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + goto Unimplemented; } - if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) - res = Py_True; + assert(PyComplex_Check(v)); + TO_COMPLEX(v, i); + + if (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; + res = Py_False; Py_INCREF(res); return res; + +Unimplemented: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } static PyObject * -- cgit v1.2.1 From 50d6ea48e94580b1084527713fd4942fbb0a40c6 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 22 May 2010 12:02:35 +0000 Subject: Issue #8749: remove unused code in Objects/object.c. Thanks Yaniv Aknin. --- Objects/object.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 7907a8e566..0802348455 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -950,31 +950,7 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) 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); - 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; -- cgit v1.2.1 From dc57afcc7e7f4450d0ba47b67b6feec201c13a94 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 23 May 2010 13:33:13 +0000 Subject: Issue #8188: Introduce a new scheme for computing hashes of numbers (instances of int, float, complex, decimal.Decimal and fractions.Fraction) that makes it easy to maintain the invariant that hash(x) == hash(y) whenever x and y have equal value. --- Objects/complexobject.c | 18 +++---- Objects/longobject.c | 39 ++++++++++---- Objects/object.c | 136 +++++++++++++++++++++++++++++++----------------- Objects/typeobject.c | 26 ++++++--- 4 files changed, 145 insertions(+), 74 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 9e1e217856..7594c886ec 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -403,12 +403,12 @@ complex_str(PyComplexObject *v) static long complex_hash(PyComplexObject *v) { - long hashreal, hashimag, combined; - hashreal = _Py_HashDouble(v->cval.real); - if (hashreal == -1) + unsigned long hashreal, hashimag, combined; + hashreal = (unsigned long)_Py_HashDouble(v->cval.real); + if (hashreal == (unsigned long)-1) return -1; - hashimag = _Py_HashDouble(v->cval.imag); - if (hashimag == -1) + hashimag = (unsigned long)_Py_HashDouble(v->cval.imag); + if (hashimag == (unsigned long)-1) return -1; /* Note: if the imaginary part is 0, hashimag is 0 now, * so the following returns hashreal unchanged. This is @@ -416,10 +416,10 @@ complex_hash(PyComplexObject *v) * 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; + combined = hashreal + _PyHASH_IMAG * hashimag; + if (combined == (unsigned long)-1) + combined = (unsigned long)-2; + return (long)combined; } /* This macro may return! */ diff --git a/Objects/longobject.c b/Objects/longobject.c index 850396b8ef..564d1a0459 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2571,18 +2571,37 @@ long_hash(PyLongObject *v) sign = -1; i = -(i); } - /* The following loop produces a C unsigned long x such that x is - congruent to the absolute value of v modulo ULONG_MAX. The - resulting x is nonzero if and only if v is. */ while (--i >= 0) { - /* Force a native long #-bits (32 or 64) circular shift */ - x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT); + /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we + want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + _PyHASH_MODULUS. + + The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS + amounts to a rotation of the bits of x. To see this, write + + x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z + + where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top + PyLong_SHIFT bits of x (those that are shifted out of the + original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) & + _PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT + bits of x, shifted up. Then since 2**_PyHASH_BITS is + congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is + congruent to y modulo _PyHASH_MODULUS. So + + x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS). + + The right-hand side is just the result of rotating the + _PyHASH_BITS bits of x left by PyLong_SHIFT places; since + not all _PyHASH_BITS bits of x are 1s, the same is true + after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is + the reduction of x*2**PyLong_SHIFT modulo + _PyHASH_MODULUS. */ + x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | + (x >> (_PyHASH_BITS - PyLong_SHIFT)); x += v->ob_digit[i]; - /* If the addition above overflowed we compensate by - incrementing. This preserves the value modulo - ULONG_MAX. */ - if (x < v->ob_digit[i]) - x++; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; } x = x * sign; if (x == (unsigned long)-1) diff --git a/Objects/object.c b/Objects/object.c index 0802348455..76d018f7f1 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -647,63 +647,101 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op) All the utility functions (_Py_Hash*()) return "-1" to signify an error. */ +/* For numeric types, the hash of a number x is based on the reduction + of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that + hash(x) == hash(y) whenever x and y are numerically equal, even if + x and y have different types. + + A quick summary of the hashing strategy: + + (1) First define the 'reduction of x modulo P' for any rational + number x; this is a standard extension of the usual notion of + reduction modulo P for integers. If x == p/q (written in lowest + terms), the reduction is interpreted as the reduction of p times + the inverse of the reduction of q, all modulo P; if q is exactly + divisible by P then define the reduction to be infinity. So we've + got a well-defined map + + reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }. + + (2) Now for a rational number x, define hash(x) by: + + reduce(x) if x >= 0 + -reduce(-x) if x < 0 + + If the result of the reduction is infinity (this is impossible for + integers, floats and Decimals) then use the predefined hash value + _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. + _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the + hashes of float and Decimal infinities and nans. + + A selling point for the above strategy is that it makes it possible + to compute hashes of decimal and binary floating-point numbers + efficiently, even if the exponent of the binary or decimal number + is large. The key point is that + + reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS) + + provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a + binary or decimal float is never infinity, since the denominator is a power + of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have, + for nonnegative x, + + reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS + + reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS + + and reduce(10**e) can be computed efficiently by the usual modular + exponentiation algorithm. For reduce(2**e) it's even better: since + P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication + by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits. + + */ + 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. - */ + int e, sign; + double m; + unsigned long x, y; if (!Py_IS_FINITE(v)) { if (Py_IS_INFINITY(v)) - return v < 0 ? -271828 : 314159; + return v > 0 ? _PyHASH_INF : -_PyHASH_INF; else - return 0; + return _PyHASH_NAN; } - 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; + + m = frexp(v, &e); + + sign = 1; + if (m < 0) { + sign = -1; + m = -m; + } + + /* process 28 bits at a time; this should work well both for binary + and hexadecimal floating point. */ + x = 0; + while (m) { + x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); + m *= 268435456.0; /* 2**28 */ + e -= 28; + y = (unsigned long)m; /* pull out integer part */ + m -= y; + x += y; + if (x >= _PyHASH_MODULUS) + x -= _PyHASH_MODULUS; + } + + /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */ + e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS); + x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); + + x = x * sign; + if (x == (unsigned long)-1) + x = (unsigned long)-2; + return (long)x; } long diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 369bac6bb9..adfb0ec067 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4921,6 +4921,7 @@ slot_tp_hash(PyObject *self) PyObject *func, *res; static PyObject *hash_str; long h; + int overflow; func = lookup_method(self, "__hash__", &hash_str); @@ -4937,14 +4938,27 @@ slot_tp_hash(PyObject *self) Py_DECREF(func); if (res == NULL) return -1; - if (PyLong_Check(res)) + + if (!PyLong_Check(res)) { + PyErr_SetString(PyExc_TypeError, + "__hash__ method should return an integer"); + return -1; + } + /* Transform the PyLong `res` to a C long `h`. For an existing + hashable Python object x, hash(x) will always lie within the range + of a C long. Therefore our transformation must preserve values + that already lie within this range, to ensure that if x.__hash__() + returns hash(y) then hash(x) == hash(y). */ + h = PyLong_AsLongAndOverflow(res, &overflow); + if (overflow) + /* res was not within the range of a C long, so we're free to + use any sufficiently bit-mixing transformation; + long.__hash__ will do nicely. */ h = PyLong_Type.tp_hash(res); - else - h = PyLong_AsLong(res); Py_DECREF(res); - if (h == -1 && !PyErr_Occurred()) - h = -2; - return h; + if (h == -1 && !PyErr_Occurred()) + h = -2; + return h; } static PyObject * -- cgit v1.2.1 From cf02335a74139c6d55770a65a65763c493ac43c4 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 26 May 2010 16:02:59 +0000 Subject: Issue #8817: Expose round-to-nearest variant of divmod in _PyLong_Divmod_Near for use by the datetime module; also refactor long_round to use this function. --- Objects/longobject.c | 251 ++++++++++++++++++++++++++++----------------------- 1 file changed, 140 insertions(+), 111 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 564d1a0459..3eb0c44b58 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4201,140 +4201,169 @@ long__format__(PyObject *self, PyObject *args) PyUnicode_GET_SIZE(format_spec)); } -static PyObject * -long_round(PyObject *self, PyObject *args) +/* Return a pair (q, r) such that a = b * q + r, and + abs(r) <= abs(b)/2, with equality possible only if q is even. + In other words, q == a / b, rounded to the nearest integer using + round-half-to-even. */ + +PyObject * +_PyLong_Divmod_Near(PyObject *a, PyObject *b) { - PyObject *o_ndigits=NULL, *temp; - PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one; - int errcode; - digit q_mod_4; - - /* Notes on the algorithm: to round to the nearest 10**n (n positive), - the straightforward method is: - - (1) divide by 10**n - (2) round to nearest integer (round to even in case of tie) - (3) multiply result by 10**n. - - But the rounding step involves examining the fractional part of the - quotient to see whether it's greater than 0.5 or not. Since we - want to do the whole calculation in integer arithmetic, it's - simpler to do: - - (1) divide by (10**n)/2 - (2) round to nearest multiple of 2 (multiple of 4 in case of tie) - (3) multiply result by (10**n)/2. - - Then all we need to know about the fractional part of the quotient - arising in step (2) is whether it's zero or not. - - Doing both a multiplication and division is wasteful, and is easily - avoided if we just figure out how much to adjust the original input - by to do the rounding. - - Here's the whole algorithm expressed in Python. - - def round(self, ndigits = None): - """round(int, int) -> int""" - if ndigits is None or ndigits >= 0: - return self - pow = 10**-ndigits >> 1 - q, r = divmod(self, pow) - self -= r - if (q & 1 != 0): - if (q & 2 == r == 0): - self -= pow - else: - self += pow - return self + PyLongObject *quo = NULL, *rem = NULL; + PyObject *one = NULL, *twice_rem, *result, *temp; + int cmp, quo_is_odd, quo_is_neg; + + /* Equivalent Python code: + + def divmod_near(a, b): + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. + # The expression r / b > 0.5 is equivalent to 2 * r > b if b is + # positive, 2 * r < b if b negative. + greater_than_half = 2*r > b if b > 0 else 2*r < b + exactly_half = 2*r == b + if greater_than_half or exactly_half and q % 2 == 1: + q += 1 + r -= b + return q, r */ + if (!PyLong_Check(a) || !PyLong_Check(b)) { + PyErr_SetString(PyExc_TypeError, + "non-integer arguments in division"); + return NULL; + } + + /* Do a and b have different signs? If so, quotient is negative. */ + quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + + one = PyLong_FromLong(1L); + if (one == NULL) + return NULL; + + if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) + goto error; + + /* compare twice the remainder with the divisor, to see + if we need to adjust the quotient and remainder */ + twice_rem = long_lshift((PyObject *)rem, one); + if (twice_rem == NULL) + goto error; + if (quo_is_neg) { + temp = long_neg((PyLongObject*)twice_rem); + Py_DECREF(twice_rem); + twice_rem = temp; + if (twice_rem == NULL) + goto error; + } + cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); + Py_DECREF(twice_rem); + + quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); + if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + /* fix up quotient */ + if (quo_is_neg) + temp = long_sub(quo, (PyLongObject *)one); + else + temp = long_add(quo, (PyLongObject *)one); + Py_DECREF(quo); + quo = (PyLongObject *)temp; + if (quo == NULL) + goto error; + /* and remainder */ + if (quo_is_neg) + temp = long_add(rem, (PyLongObject *)b); + else + temp = long_sub(rem, (PyLongObject *)b); + Py_DECREF(rem); + rem = (PyLongObject *)temp; + if (rem == NULL) + goto error; + } + + result = PyTuple_New(2); + if (result == NULL) + goto error; + + /* PyTuple_SET_ITEM steals references */ + PyTuple_SET_ITEM(result, 0, (PyObject *)quo); + PyTuple_SET_ITEM(result, 1, (PyObject *)rem); + Py_DECREF(one); + return result; + + error: + Py_XDECREF(quo); + Py_XDECREF(rem); + Py_XDECREF(one); + return NULL; +} + +static PyObject * +long_round(PyObject *self, PyObject *args) +{ + PyObject *o_ndigits=NULL, *temp, *result, *ndigits; + + /* To round an integer m to the nearest 10**n (n positive), we make use of + * the divmod_near operation, defined by: + * + * divmod_near(a, b) = (q, r) + * + * where q is the nearest integer to the quotient a / b (the + * nearest even integer in the case of a tie) and r == a - q * b. + * Hence q * b = a - r is the nearest multiple of b to a, + * preferring even multiples in the case of a tie. + * + * So the nearest multiple of 10**n to m is: + * + * m - divmod_near(m, 10**n)[1]. + */ if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) return NULL; if (o_ndigits == NULL) return long_long(self); - ndigits = (PyLongObject *)PyNumber_Index(o_ndigits); + ndigits = PyNumber_Index(o_ndigits); if (ndigits == NULL) return NULL; + /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ if (Py_SIZE(ndigits) >= 0) { Py_DECREF(ndigits); return long_long(self); } - Py_INCREF(self); /* to keep refcounting simple */ - /* we now own references to self, ndigits */ - - /* pow = 10 ** -ndigits >> 1 */ - pow = (PyLongObject *)PyLong_FromLong(10L); - if (pow == NULL) - goto error; - temp = long_neg(ndigits); + /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ + temp = long_neg((PyLongObject*)ndigits); Py_DECREF(ndigits); - ndigits = (PyLongObject *)temp; + ndigits = temp; if (ndigits == NULL) - goto error; - temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; - assert(PyLong_Check(pow)); /* check long_pow returned a long */ - one = (PyLongObject *)PyLong_FromLong(1L); - if (one == NULL) - goto error; - temp = long_rshift(pow, one); - Py_DECREF(one); - Py_DECREF(pow); - pow = (PyLongObject *)temp; - if (pow == NULL) - goto error; + return NULL; - /* q, r = divmod(self, pow) */ - errcode = l_divmod((PyLongObject *)self, pow, &q, &r); - if (errcode == -1) - goto error; + result = PyLong_FromLong(10L); + if (result == NULL) { + Py_DECREF(ndigits); + return NULL; + } - /* self -= r */ - temp = long_sub((PyLongObject *)self, r); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; + temp = long_pow(result, ndigits, Py_None); + Py_DECREF(ndigits); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; - /* get value of quotient modulo 4 */ - if (Py_SIZE(q) == 0) - q_mod_4 = 0; - else if (Py_SIZE(q) > 0) - q_mod_4 = q->ob_digit[0] & 3; - else - q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3; + temp = _PyLong_Divmod_Near(self, result); + Py_DECREF(result); + result = temp; + if (result == NULL) + return NULL; - if ((q_mod_4 & 1) == 1) { - /* q is odd; round self up or down by adding or subtracting pow */ - if (q_mod_4 == 1 && Py_SIZE(r) == 0) - temp = (PyObject *)long_sub((PyLongObject *)self, pow); - else - temp = (PyObject *)long_add((PyLongObject *)self, pow); - Py_DECREF(self); - self = temp; - if (self == NULL) - goto error; - } - Py_DECREF(q); - Py_DECREF(r); - Py_DECREF(pow); - Py_DECREF(ndigits); - return self; + temp = long_sub((PyLongObject *)self, + (PyLongObject *)PyTuple_GET_ITEM(result, 1)); + Py_DECREF(result); + result = temp; - error: - Py_XDECREF(q); - Py_XDECREF(r); - Py_XDECREF(pow); - Py_XDECREF(self); - Py_XDECREF(ndigits); - return NULL; + return result; } static PyObject * -- cgit v1.2.1 From cd52a69186199286a7f48d8058b096473be63898 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 26 May 2010 20:07:58 +0000 Subject: Issue #2844: Make int('42', n) consistently raise ValueError for invalid integers n (including n = -909). --- Objects/longobject.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 3eb0c44b58..ed41010b04 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4098,23 +4098,34 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *x = NULL; - int base = -909; /* unlikely! */ + PyObject *obase = NULL, *x = NULL; + long base; + int overflow; static char *kwlist[] = {"x", "base", 0}; if (type != &PyLong_Type) return long_subtype_new(type, args, kwds); /* Wimp out */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, - &x, &base)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:int", kwlist, + &x, &obase)) return NULL; if (x == NULL) return PyLong_FromLong(0L); - if (base == -909) + if (obase == NULL) return PyNumber_Long(x); - else if (PyUnicode_Check(x)) + + base = PyLong_AsLongAndOverflow(obase, &overflow); + if (base == -1 && PyErr_Occurred()) + return NULL; + if (overflow || (base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + + if (PyUnicode_Check(x)) return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), PyUnicode_GET_SIZE(x), - base); + (int)base); else if (PyByteArray_Check(x) || PyBytes_Check(x)) { /* Since PyLong_FromString doesn't have a length parameter, * check here for possible NULs in the string. */ @@ -4129,10 +4140,10 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) x is a bytes or buffer, *and* a base is given. */ PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %R", - base, x); + (int)base, x); return NULL; } - return PyLong_FromString(string, NULL, base); + return PyLong_FromString(string, NULL, (int)base); } else { PyErr_SetString(PyExc_TypeError, -- cgit v1.2.1 From 615099d40c6e2c91bd2b1d06358d277655164927 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 5 Jun 2010 00:45:37 +0000 Subject: Merged revisions 81706-81707 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81706 | benjamin.peterson | 2010-06-04 19:32:50 -0500 (Fri, 04 Jun 2010) | 1 line properly lookup the __format__ special method ........ r81707 | benjamin.peterson | 2010-06-04 19:38:22 -0500 (Fri, 04 Jun 2010) | 1 line remove PyType_Ready call; float should be initialized in interpreter startup ........ --- Objects/abstract.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 5a904b44d1..1b6c2b4279 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -693,48 +693,36 @@ PyBuffer_Release(Py_buffer *view) PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; - } + static PyObject *format_cache = NULL; /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(obj), str__format__); + meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: -- cgit v1.2.1 From 878d67bf1e098adb71a19749417b566a6a56207b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 5 Jun 2010 01:03:24 +0000 Subject: Merged revisions 81709-81710 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81709 | benjamin.peterson | 2010-06-04 19:56:46 -0500 (Fri, 04 Jun 2010) | 1 line implement object.__format__ with PyObject_Format ........ r81710 | benjamin.peterson | 2010-06-04 20:00:10 -0500 (Fri, 04 Jun 2010) | 1 line fix ref counting ........ --- Objects/typeobject.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index adfb0ec067..2d9d031a09 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3310,23 +3310,15 @@ object_format(PyObject *self, PyObject *args) PyObject *format_spec; PyObject *self_as_str = NULL; PyObject *result = NULL; - PyObject *format_meth = NULL; if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; self_as_str = PyObject_Str(self); - if (self_as_str != NULL) { - /* find the format function */ - format_meth = PyObject_GetAttrString(self_as_str, "__format__"); - if (format_meth != NULL) { - /* and call it */ - result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL); - } - } + if (self_as_str != NULL) + result = PyObject_Format(self_as_str, format_spec); Py_XDECREF(self_as_str); - Py_XDECREF(format_meth); return result; } -- cgit v1.2.1 From d3491f09249085d1f7238f4072b7c1ec3d4d46f6 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 5 Jun 2010 02:11:45 +0000 Subject: Merged revisions 81712 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81712 | benjamin.peterson | 2010-06-04 21:07:01 -0500 (Fri, 04 Jun 2010) | 1 line _PyObject_LookupSpecial returns a new reference ........ --- Objects/abstract.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 1b6c2b4279..9fb56b6b17 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -716,6 +716,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* And call it. */ result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); + Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { PyErr_SetString(PyExc_TypeError, -- cgit v1.2.1 From 493fd252e4f7fd49dc2dc2923dbcc1dae9a23c9c Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 7 Jun 2010 18:47:09 +0000 Subject: Fix naming inconsistency. --- Objects/longobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index ed41010b04..c9c9817f12 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4218,7 +4218,7 @@ long__format__(PyObject *self, PyObject *args) round-half-to-even. */ PyObject * -_PyLong_Divmod_Near(PyObject *a, PyObject *b) +_PyLong_DivmodNear(PyObject *a, PyObject *b) { PyLongObject *quo = NULL, *rem = NULL; PyObject *one = NULL, *twice_rem, *result, *temp; @@ -4363,7 +4363,7 @@ long_round(PyObject *self, PyObject *args) if (result == NULL) return NULL; - temp = _PyLong_Divmod_Near(self, result); + temp = _PyLong_DivmodNear(self, result); Py_DECREF(result); result = temp; if (result == NULL) -- cgit v1.2.1 From 046dd2b5f082e1f3975d7cea07826db45c72c259 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 7 Jun 2010 19:57:46 +0000 Subject: Issue #8848: U / U# formats of Py_BuildValue() are just alias to s / s# --- Objects/exceptions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 8200d4d321..3d5b1ea94f 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1510,7 +1510,7 @@ 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, "Uu#nnU", + return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns", encoding, object, length, start, end, reason); } @@ -1625,7 +1625,7 @@ PyUnicodeDecodeError_Create( assert(length < INT_MAX); assert(start < INT_MAX); assert(end < INT_MAX); - return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU", + return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } -- cgit v1.2.1 From cabba29aae4a227b0f5097150c9917763ed5a693 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 7 Jun 2010 21:41:35 +0000 Subject: Merged revisions 81813 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81813 | benjamin.peterson | 2010-06-07 16:37:09 -0500 (Mon, 07 Jun 2010) | 2 lines locale grouping strings should end in '\0' ........ --- Objects/stringlib/formatter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index a807b97fa8..5b7b3dcf08 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -649,7 +649,7 @@ get_locale_info(int type, LocaleInfo *locale_info) case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* Group every 3 characters, + locale_info->grouping = "\3\0"; /* Group every 3 characters, trailing 0 means repeat infinitely. */ break; -- cgit v1.2.1 From 1be88564234a329a0d60a2ab182d26fc51c6fb70 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 7 Jun 2010 22:31:26 +0000 Subject: Merged revisions 81820 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81820 | benjamin.peterson | 2010-06-07 17:23:23 -0500 (Mon, 07 Jun 2010) | 1 line correctly overflow when indexes are too large ........ --- Objects/stringlib/string_format.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index ecb00a9a1e..bc70e97be4 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -373,6 +373,8 @@ FieldNameIterator_next(FieldNameIterator *self, int *is_attribute, 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 ']' */ @@ -429,6 +431,8 @@ field_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first, /* 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; -- cgit v1.2.1 From 02cbf1a61e4966c1e73077b0f619e4027ceda530 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 7 Jun 2010 22:35:08 +0000 Subject: Merged revisions 81824 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81824 | benjamin.peterson | 2010-06-07 17:32:44 -0500 (Mon, 07 Jun 2010) | 1 line remove extra byte and fix comment ........ --- Objects/stringlib/formatter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 5b7b3dcf08..7b29a9de3a 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -649,8 +649,8 @@ get_locale_info(int type, LocaleInfo *locale_info) case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3\0"; /* Group every 3 characters, - trailing 0 means repeat + locale_info->grouping = "\3"; /* Group every 3 characters. The + (implicit) trailing 0 means repeat infinitely. */ break; case LT_NO_LOCALE: -- cgit v1.2.1 From ae3b1c20097014a8cd06b038c73e47ccb6bca32a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 9 Jun 2010 16:38:55 +0000 Subject: Merged revisions 81860 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81860 | antoine.pitrou | 2010-06-09 18:24:00 +0200 (mer., 09 juin 2010) | 3 lines Issue #8930: fix some C code indentation ........ --- Objects/bytearrayobject.c | 64 +++++++++++++++++++++++------------------------ Objects/bytesobject.c | 38 ++++++++++++++-------------- 2 files changed, 51 insertions(+), 51 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 165ccae9f4..16350ff8c0 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1650,43 +1650,43 @@ 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; + 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); + /* 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); + next = findchar(self_s, self_len, from_c); - if (next == NULL) { - /* No matches; return the original bytes */ - return return_self(self); - } + 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; - } + /* 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; + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8a15e89c9b..fa31a8090f 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -14,10 +14,10 @@ _getbuffer(PyObject *obj, Py_buffer *view) 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; + 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) @@ -776,19 +776,19 @@ bytes_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(PyBytes_AS_STRING(self), Py_SIZE(self), - varg.buf, varg.len, 0); - PyBuffer_Release(&varg); - return pos >= 0; + Py_buffer varg; + int pos; + PyErr_Clear(); + if (_getbuffer(arg, &varg) < 0) + return -1; + pos = stringlib_find(PyBytes_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; + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; } return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; @@ -2345,12 +2345,12 @@ bytes_splitlines(PyObject *self, PyObject *args) int keepends = 0; if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) - return NULL; + return NULL; return stringlib_splitlines( - (PyObject*) self, PyBytes_AS_STRING(self), - PyBytes_GET_SIZE(self), keepends - ); + (PyObject*) self, PyBytes_AS_STRING(self), + PyBytes_GET_SIZE(self), keepends + ); } -- cgit v1.2.1 From ecccd2881ab03c9aa4f94081c3a43f8b40fd6975 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Jun 2010 12:00:55 +0000 Subject: Issue #8922: Normalize the encoding name in PyUnicode_AsEncodedString() to enable shortcuts for upper case encoding name. Add also a shortcut for "iso-8859-1" in PyUnicode_AsEncodedString() and PyUnicode_Decode(). --- Objects/unicodeobject.c | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index b97621b934..86fd153bcd 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1293,25 +1293,21 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj, return NULL; } -PyObject *PyUnicode_Decode(const char *s, - Py_ssize_t size, - const char *encoding, - const char *errors) +/* Convert encoding to lower case and replace '_' with '-' in order to + catch e.g. UTF_8. Truncate the string if it is longer than lower_len-1 + characters. */ +static void normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { - PyObject *buffer = NULL, *unicode; - Py_buffer info; - char lower[20]; /* Enough for any encoding name we recognize */ - char *l; const char *e; + char *l; + char *l_end; - if (encoding == NULL) - encoding = PyUnicode_GetDefaultEncoding(); - - /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8 */ e = encoding; l = lower; - while (*e && l < &lower[(sizeof lower) - 2]) { + l_end = &lower[lower_len - 1]; + while (*e && l < l_end) { if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1324,8 +1320,22 @@ PyObject *PyUnicode_Decode(const char *s, } } *l = '\0'; +} + +PyObject *PyUnicode_Decode(const char *s, + Py_ssize_t size, + const char *encoding, + const char *errors) +{ + PyObject *buffer = NULL, *unicode; + Py_buffer info; + char lower[11]; /* Enough for any encoding shortcut */ + + if (encoding == NULL) + encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ + normalize_encoding(encoding, lower, sizeof(lower)); if (strcmp(lower, "utf-8") == 0) return PyUnicode_DecodeUTF8(s, size, errors); else if ((strcmp(lower, "latin-1") == 0) || @@ -1478,6 +1488,7 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, const char *errors) { PyObject *v; + char lower[11]; /* Enough for any encoding shortcut */ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); @@ -1488,21 +1499,23 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - if (strcmp(encoding, "utf-8") == 0) + normalize_encoding(encoding, lower, sizeof(lower)); + if (strcmp(lower, "utf-8") == 0) return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); - else if (strcmp(encoding, "latin-1") == 0) + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(encoding, "mbcs") == 0) + else if (strcmp(lower, "mbcs") == 0) return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); #endif - else if (strcmp(encoding, "ascii") == 0) + else if (strcmp(lower, "ascii") == 0) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), errors); -- cgit v1.2.1 From a8f37e60b752a6d54cab87c05917435b6483872a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 10 Jun 2010 13:36:23 +0000 Subject: Fix r81869: ISO-8859-15 was seen as an alias to ISO-8859-1 Don't use normalize_encoding() result if it is truncated. --- Objects/unicodeobject.c | 84 ++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 39 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 86fd153bcd..aa0b4c6c53 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1294,11 +1294,12 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj, } /* Convert encoding to lower case and replace '_' with '-' in order to - catch e.g. UTF_8. Truncate the string if it is longer than lower_len-1 - characters. */ -static void normalize_encoding(const char *encoding, - char *lower, - size_t lower_len) + catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1), + 1 on success. */ +static int +normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) { const char *e; char *l; @@ -1307,7 +1308,9 @@ static void normalize_encoding(const char *encoding, e = encoding; l = lower; l_end = &lower[lower_len - 1]; - while (*e && l < l_end) { + while (*e) { + if (l == l_end) + return 0; if (ISUPPER(*e)) { *l++ = TOLOWER(*e++); } @@ -1320,6 +1323,7 @@ static void normalize_encoding(const char *encoding, } } *l = '\0'; + return 1; } PyObject *PyUnicode_Decode(const char *s, @@ -1335,22 +1339,23 @@ PyObject *PyUnicode_Decode(const char *s, encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - normalize_encoding(encoding, lower, sizeof(lower)); - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_DecodeUTF8(s, size, errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_DecodeLatin1(s, size, errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_DecodeUTF8(s, size, errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_DecodeLatin1(s, size, errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_DecodeMBCS(s, size, errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_DecodeMBCS(s, size, errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_DecodeASCII(s, size, errors); - else if (strcmp(lower, "utf-16") == 0) - return PyUnicode_DecodeUTF16(s, size, errors, 0); - else if (strcmp(lower, "utf-32") == 0) - return PyUnicode_DecodeUTF32(s, size, errors, 0); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_DecodeASCII(s, size, errors); + else if (strcmp(lower, "utf-16") == 0) + return PyUnicode_DecodeUTF16(s, size, errors, 0); + else if (strcmp(lower, "utf-32") == 0) + return PyUnicode_DecodeUTF32(s, size, errors, 0); + } /* Decode via the codec registry */ buffer = NULL; @@ -1499,26 +1504,27 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, encoding = PyUnicode_GetDefaultEncoding(); /* Shortcuts for common default encodings */ - normalize_encoding(encoding, lower, sizeof(lower)); - if (strcmp(lower, "utf-8") == 0) - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); - else if ((strcmp(lower, "latin-1") == 0) || - (strcmp(lower, "iso-8859-1") == 0)) - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + if (normalize_encoding(encoding, lower, sizeof(lower))) { + if (strcmp(lower, "utf-8") == 0) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + else if ((strcmp(lower, "latin-1") == 0) || + (strcmp(lower, "iso-8859-1") == 0)) + return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - else if (strcmp(lower, "mbcs") == 0) - return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); #endif - else if (strcmp(lower, "ascii") == 0) - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - errors); + else if (strcmp(lower, "ascii") == 0) + return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + errors); + } /* During bootstrap, we may need to find the encodings package, to load the file system encoding, and require the file system encoding in order to load the encodings @@ -1528,7 +1534,7 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, the encodings module is ASCII-only. XXX could try wcstombs instead, if the file system encoding is the locale's encoding. */ - else if (Py_FileSystemDefaultEncoding && + if (Py_FileSystemDefaultEncoding && strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 && !PyThreadState_GET()->interp->codecs_initialized) return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), -- cgit v1.2.1 From 3c1dbd9154d38ab72788e8f2a98538aacd7dd98d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 11 Jun 2010 21:46:32 +0000 Subject: Merged revisions 81907 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81907 | antoine.pitrou | 2010-06-11 23:42:26 +0200 (ven., 11 juin 2010) | 5 lines Issue #8941: decoding big endian UTF-32 data in UCS-2 builds could crash the interpreter with characters outside the Basic Multilingual Plane (higher than 0x10000). ........ --- Objects/unicodeobject.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index aa0b4c6c53..de92787cc6 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2730,11 +2730,11 @@ PyUnicode_DecodeUTF32Stateful(const char *s, PyUnicodeObject *unicode; Py_UNICODE *p; #ifndef Py_UNICODE_WIDE - int i, pairs; + int pairs = 0; #else const int pairs = 0; #endif - const unsigned char *q, *e; + const unsigned char *q, *e, *qq; int bo = 0; /* assume native ordering by default */ const char *errmsg = ""; /* Offsets from q for retrieving bytes in the right order. */ @@ -2745,23 +2745,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* On narrow builds we split characters outside the BMP into two - codepoints => count how much extra space we need. */ -#ifndef Py_UNICODE_WIDE - for (i = pairs = 0; i < size/4; i++) - if (((Py_UCS4 *)s)[i] >= 0x10000) - 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; + q = (unsigned char *)s; e = q + size; @@ -2813,6 +2797,24 @@ PyUnicode_DecodeUTF32Stateful(const char *s, iorder[3] = 0; } + /* On narrow builds we split characters outside the BMP into two + codepoints => count how much extra space we need. */ +#ifndef Py_UNICODE_WIDE + for (qq = q; qq < e; 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) */ -- cgit v1.2.1 From d86accdc8690e3cf9c61ae9f9ad353b6f1ff284e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 11 Jun 2010 23:56:51 +0000 Subject: Issue #8969: On Windows, use mbcs codec in strict mode to encode and decode filenames and enable os.fsencode(). --- Objects/unicodeobject.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index de92787cc6..8d75b205de 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1478,11 +1478,17 @@ PyObject *PyUnicode_AsEncodedObject(PyObject *unicode, PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) { - if (Py_FileSystemDefaultEncoding) + if (Py_FileSystemDefaultEncoding) { +#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) + if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + NULL); +#endif return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); - else + } else return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), "surrogateescape"); @@ -1639,7 +1645,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, "surrogateescape"); + return PyUnicode_DecodeMBCS(s, size, NULL); } #elif defined(__APPLE__) if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { @@ -2745,7 +2751,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, #endif PyObject *errorHandler = NULL; PyObject *exc = NULL; - + q = (unsigned char *)s; e = q + size; -- cgit v1.2.1 From 89448c1931f4bf18d091230ff3526ccf5bffd38f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 12 Jun 2010 09:10:14 +0000 Subject: =?UTF-8?q?Silence=20'unused=20variable'=20gcc=20warning.=20=20Pat?= =?UTF-8?q?ch=20by=20=C3=89ric=20Araujo.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Objects/unicodeobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8d75b205de..4153c25f53 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2737,10 +2737,11 @@ PyUnicode_DecodeUTF32Stateful(const char *s, 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, *qq; + 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. */ -- cgit v1.2.1 From 9ab7b8dd3d5b47b615c191c6baaf512c36b74a60 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 16 Jun 2010 23:33:54 +0000 Subject: Issue #850997: mbcs encoding (Windows only) handles errors argument: strict mode raises unicode errors. The encoder only supports "strict" and "replace" error handlers, the decoder only supports "strict" and "ignore" error handlers. --- Objects/unicodeobject.c | 163 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 38 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4153c25f53..83e036099f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1767,6 +1767,33 @@ int PyUnicode_SetDefaultEncoding(const char *encoding) return 0; } +/* create or adjust a UnicodeDecodeError */ +static void +make_decode_exception(PyObject **exceptionObject, + const char *encoding, + const char *input, Py_ssize_t length, + Py_ssize_t startpos, Py_ssize_t endpos, + const char *reason) +{ + if (*exceptionObject == NULL) { + *exceptionObject = PyUnicodeDecodeError_Create( + encoding, input, length, startpos, endpos, reason); + } + else { + if (PyUnicodeDecodeError_SetStart(*exceptionObject, startpos)) + goto onError; + if (PyUnicodeDecodeError_SetEnd(*exceptionObject, endpos)) + goto onError; + if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason)) + goto onError; + } + return; + +onError: + Py_DECREF(*exceptionObject); + *exceptionObject = NULL; +} + /* error handling callback helper: build arguments, call the callback and check the arguments, if no exception occurred, copy the replacement to the output @@ -1800,20 +1827,13 @@ int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler goto onError; } - if (*exceptionObject == NULL) { - *exceptionObject = PyUnicodeDecodeError_Create( - encoding, *input, *inend-*input, *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; - } + make_decode_exception(exceptionObject, + encoding, + *input, *inend - *input, + *startinpos, *endinpos, + reason); + if (*exceptionObject == NULL) + goto onError; restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL); if (restuple == NULL) @@ -4552,32 +4572,46 @@ static int is_dbcs_lead_byte(const char *s, int offset) static int decode_mbcs(PyUnicodeObject **v, const char *s, /* MBCS string */ int size, /* sizeof MBCS string */ - int final) + int final, + const char *errors) { Py_UNICODE *p; - Py_ssize_t n = 0; - int usize = 0; + Py_ssize_t n; + DWORD usize; + DWORD flags; assert(size >= 0); + /* check and handle 'errors' arg */ + if (errors==NULL || strcmp(errors, "strict")==0) + flags = MB_ERR_INVALID_CHARS; + else if (strcmp(errors, "ignore")==0) + flags = 0; + else { + PyErr_Format(PyExc_ValueError, + "mbcs encoding does not support errors='%s'", + errors); + return -1; + } + /* 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; - } - } + usize = MultiByteToWideChar(CP_ACP, flags, s, size, NULL, 0); + if (usize==0) + goto mbcs_decode_error; + } else + usize = 0; if (*v == NULL) { /* Create unicode object */ *v = _PyUnicode_New(usize); if (*v == NULL) return -1; + n = 0; } else { /* Extend unicode object */ @@ -4587,15 +4621,35 @@ static int decode_mbcs(PyUnicodeObject **v, } /* Do the conversion */ - if (size > 0) { + if (usize > 0) { p = PyUnicode_AS_UNICODE(*v) + n; - if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) { - PyErr_SetFromWindowsErrWithFilename(0, NULL); - return -1; + if (0 == MultiByteToWideChar(CP_ACP, flags, s, size, p, usize)) { + goto mbcs_decode_error; } } - return size; + +mbcs_decode_error: + /* If the last error was ERROR_NO_UNICODE_TRANSLATION, then + we raise a UnicodeDecodeError - else it is a 'generic' + windows error + */ + if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) { + /* Ideally, we should get reason from FormatMessage - this + is the Windows 2000 English version of the message + */ + PyObject *exc = NULL; + const char *reason = "No mapping for the Unicode character exists " + "in the target multi-byte code page."; + make_decode_exception(&exc, "mbcs", s, size, 0, 0, reason); + if (exc != NULL) { + PyCodec_StrictErrors(exc); + Py_DECREF(exc); + } + } else { + PyErr_SetFromWindowsErrWithFilename(0, NULL); + } + return -1; } PyObject *PyUnicode_DecodeMBCSStateful(const char *s, @@ -4612,10 +4666,10 @@ PyObject *PyUnicode_DecodeMBCSStateful(const char *s, #ifdef NEED_RETRY retry: if (size > INT_MAX) - done = decode_mbcs(&v, s, INT_MAX, 0); + done = decode_mbcs(&v, s, INT_MAX, 0, errors); else #endif - done = decode_mbcs(&v, s, (int)size, !consumed); + done = decode_mbcs(&v, s, (int)size, !consumed, errors); if (done < 0) { Py_XDECREF(v); @@ -4649,20 +4703,45 @@ PyObject *PyUnicode_DecodeMBCS(const char *s, */ static int encode_mbcs(PyObject **repr, const Py_UNICODE *p, /* unicode */ - int size) /* size of unicode */ + int size, /* size of unicode */ + const char* errors) { - int mbcssize = 0; - Py_ssize_t n = 0; + BOOL usedDefaultChar = FALSE; + BOOL *pusedDefaultChar; + int mbcssize; + Py_ssize_t n; + PyObject *exc = NULL; + DWORD flags; assert(size >= 0); + /* check and handle 'errors' arg */ + if (errors==NULL || strcmp(errors, "strict")==0) { + flags = WC_NO_BEST_FIT_CHARS; + pusedDefaultChar = &usedDefaultChar; + } else if (strcmp(errors, "replace")==0) { + flags = 0; + pusedDefaultChar = NULL; + } else { + PyErr_Format(PyExc_ValueError, + "mbcs encoding does not support errors='%s'", + errors); + return -1; + } + /* First get the size of the result */ if (size > 0) { - mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL); + mbcssize = WideCharToMultiByte(CP_ACP, flags, p, size, NULL, 0, + NULL, pusedDefaultChar); if (mbcssize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } + /* If we used a default char, then we failed! */ + if (pusedDefaultChar && *pusedDefaultChar) + goto mbcs_encode_error; + } else { + mbcssize = 0; } if (*repr == NULL) { @@ -4670,6 +4749,7 @@ static int encode_mbcs(PyObject **repr, *repr = PyBytes_FromStringAndSize(NULL, mbcssize); if (*repr == NULL) return -1; + n = 0; } else { /* Extend string object */ @@ -4681,13 +4761,20 @@ static int encode_mbcs(PyObject **repr, /* Do the conversion */ if (size > 0) { char *s = PyBytes_AS_STRING(*repr) + n; - if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) { + if (0 == WideCharToMultiByte(CP_ACP, flags, p, size, s, mbcssize, + NULL, pusedDefaultChar)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } + if (pusedDefaultChar && *pusedDefaultChar) + goto mbcs_encode_error; } - return 0; + +mbcs_encode_error: + raise_encode_exception(&exc, "mbcs", p, size, 0, 0, "invalid character"); + Py_XDECREF(exc); + return -1; } PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p, @@ -4700,10 +4787,10 @@ PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p, #ifdef NEED_RETRY retry: if (size > INT_MAX) - ret = encode_mbcs(&repr, p, INT_MAX); + ret = encode_mbcs(&repr, p, INT_MAX, errors); else #endif - ret = encode_mbcs(&repr, p, (int)size); + ret = encode_mbcs(&repr, p, (int)size, errors); if (ret < 0) { Py_XDECREF(repr); -- cgit v1.2.1 From 5df3d3e122f85e97ffbf0c79212b376aa0947f78 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 22 Jun 2010 19:21:52 +0000 Subject: Merged revisions 82157 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r82157 | benjamin.peterson | 2010-06-22 14:16:37 -0500 (Tue, 22 Jun 2010) | 1 line remove INT_MAX assertions; they can fail with large Py_ssize_t #9058 ........ --- Objects/exceptions.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 3d5b1ea94f..b82b6ba87f 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1622,9 +1622,6 @@ PyUnicodeDecodeError_Create( const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason) { - assert(length < INT_MAX); - assert(start < INT_MAX); - assert(end < INT_MAX); return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns", encoding, object, length, start, end, reason); } -- cgit v1.2.1 From 5e6ff1de99b5a683185af7b5ca01d227de4d8001 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sat, 26 Jun 2010 18:50:39 +0000 Subject: Merged revisions 82248 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r82248 | ezio.melotti | 2010-06-26 21:44:42 +0300 (Sat, 26 Jun 2010) | 1 line Fix extra space. ........ --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 83e036099f..4328f9370b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7977,7 +7977,7 @@ PyObject *PyUnicode_Replace(PyObject *obj, } PyDoc_STRVAR(replace__doc__, - "S.replace (old, new[, count]) -> str\n\ + "S.replace(old, new[, count]) -> str\n\ \n\ Return a copy of S with all occurrences of substring\n\ old replaced by new. If the optional argument count is\n\ -- cgit v1.2.1 From 657082557517642baeb1f172e4ba504d62bb5a08 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 27 Jun 2010 10:17:12 +0000 Subject: #9078: fix some Unicode C API descriptions, in comments and docs. --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4328f9370b..b25bcec47f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1273,7 +1273,7 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj, case of a TypeError. */ if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_Format(PyExc_TypeError, - "coercing to str: need string or buffer, " + "coercing to str: need bytes, bytearray or char buffer, " "%.80s found", Py_TYPE(obj)->tp_name); goto onError; -- cgit v1.2.1 From 85cc0e002b7a4b396648d2b95639079feed28872 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 27 Jun 2010 18:19:09 +0000 Subject: Issue #9089: Remove references to intobject.c and intobject.h from comments. --- Objects/floatobject.c | 17 ++++++++++++++++- Objects/frameobject.c | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 9f94003184..a2c281eaf8 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -21,7 +21,22 @@ extern int finite(double); #endif -/* Special free list -- see comments for same code in intobject.c. */ +/* Special free list + + Since some Python programs can spend much of their time allocating + and deallocating floats, 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 PyFloatBlocks ever allocated, + linked via their next members. PyFloatBlocks are never returned to the + system before shutdown (PyFloat_Fini). + + free_list is a singly-linked list of available PyFloatObjects, 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_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 191c6b622f..10fb8b350e 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -391,7 +391,7 @@ static PyGetSetDef frame_getsetlist[] = { 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 + floats are allocated in a special way -- see floatobject.c). When a stack frame is on the free list, only the following members have a meaning: ob_type == &Frametype -- cgit v1.2.1 From 61922f057eff2bf4e6d5e3b56645fa85b28f0fc5 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 27 Jun 2010 21:45:24 +0000 Subject: Merged revisions 81465-81466,81468,81679,81735,81760,81868,82183 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81465 | georg.brandl | 2010-05-22 06:29:19 -0500 (Sat, 22 May 2010) | 2 lines Issue #3924: Ignore cookies with invalid "version" field in cookielib. ........ r81466 | georg.brandl | 2010-05-22 06:31:16 -0500 (Sat, 22 May 2010) | 1 line Underscore the name of an internal utility function. ........ r81468 | georg.brandl | 2010-05-22 06:43:25 -0500 (Sat, 22 May 2010) | 1 line #8635: document enumerate() start parameter in docstring. ........ r81679 | benjamin.peterson | 2010-06-03 16:21:03 -0500 (Thu, 03 Jun 2010) | 1 line use a set for membership testing ........ r81735 | michael.foord | 2010-06-05 06:46:59 -0500 (Sat, 05 Jun 2010) | 1 line Extract error message truncating into a method (unittest.TestCase._truncateMessage). ........ r81760 | michael.foord | 2010-06-05 14:38:42 -0500 (Sat, 05 Jun 2010) | 1 line Issue 8302. SkipTest exception is setUpClass or setUpModule is now reported as a skip rather than an error. ........ r81868 | benjamin.peterson | 2010-06-09 14:45:04 -0500 (Wed, 09 Jun 2010) | 1 line fix code formatting ........ r82183 | benjamin.peterson | 2010-06-23 15:29:26 -0500 (Wed, 23 Jun 2010) | 1 line cpython only gc tests ........ --- Objects/enumobject.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/enumobject.c b/Objects/enumobject.c index b579f9672f..00a33463cd 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -159,12 +159,13 @@ enum_next(enumobject *en) } PyDoc_STRVAR(enum_doc, -"enumerate(iterable) -> iterator for index, value of iterable\n" +"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" -"zero) and a value yielded by the iterable argument. enumerate is useful\n" -"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."); +"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) -- cgit v1.2.1 From f60f6606857dee2184a887d00cebc22960ada64a Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 28 Jun 2010 03:07:10 +0000 Subject: Merged revisions 82317 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r82317 | benjamin.peterson | 2010-06-27 21:58:25 -0500 (Sun, 27 Jun 2010) | 1 line remove unused last argument to property_copy ........ --- Objects/descrobject.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index aa4411c027..8a2ddfd8a8 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1115,7 +1115,7 @@ typedef struct { } propertyobject; static PyObject * property_copy(PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *); + PyObject *); static PyMemberDef property_members[] = { {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, @@ -1132,7 +1132,7 @@ PyDoc_STRVAR(getter_doc, static PyObject * property_getter(PyObject *self, PyObject *getter) { - return property_copy(self, getter, NULL, NULL, NULL); + return property_copy(self, getter, NULL, NULL); } @@ -1142,7 +1142,7 @@ PyDoc_STRVAR(setter_doc, static PyObject * property_setter(PyObject *self, PyObject *setter) { - return property_copy(self, NULL, setter, NULL, NULL); + return property_copy(self, NULL, setter, NULL); } @@ -1152,7 +1152,7 @@ PyDoc_STRVAR(deleter_doc, static PyObject * property_deleter(PyObject *self, PyObject *deleter) { - return property_copy(self, NULL, NULL, deleter, NULL); + return property_copy(self, NULL, NULL, deleter); } @@ -1221,11 +1221,10 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) } static PyObject * -property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del, - PyObject *doc) +property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) { propertyobject *pold = (propertyobject *)old; - PyObject *new, *type; + PyObject *new, *type, *doc; type = PyObject_Type(old); if (type == NULL) @@ -1243,15 +1242,12 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del, Py_XDECREF(del); del = pold->prop_del ? pold->prop_del : Py_None; } - if (doc == NULL || doc == Py_None) { - Py_XDECREF(doc); - 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; - } + 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); -- cgit v1.2.1 From 01dcd9708b68c056c1049528d83159823bc5361d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 28 Jun 2010 19:43:42 +0000 Subject: update error message --- Objects/abstract.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 9fb56b6b17..fa2611aec9 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2522,8 +2522,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls) } else { if (!check_class(cls, - "isinstance() arg 2 must be a class, type," - " or tuple of classes and types")) + "isinstance() arg 2 must be a type or tuple of types")) return -1; icls = PyObject_GetAttr(inst, __class__); if (icls == NULL) { -- cgit v1.2.1 From 6d1bd19455ce5dbb22eef87290138295d5b57346 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Thu, 1 Jul 2010 07:32:02 +0000 Subject: Update PyUnicode_DecodeUTF8 from RFC 2279 to RFC 3629. 1) #8271: when a byte sequence is invalid, only the start byte and all the valid continuation bytes are now replaced by U+FFFD, instead of replacing the number of bytes specified by the start byte. See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf (pages 94-95); 2) 5- and 6-bytes-long UTF-8 sequences are now considered invalid (no changes in behavior); 3) Change the error messages "unexpected code byte" to "invalid start byte" and "invalid data" to "invalid continuation byte"; 4) Add an extensive set of tests in test_unicode; 5) Fix test_codeccallbacks because it was failing after this change. --- Objects/unicodeobject.c | 112 ++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 56 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index b25bcec47f..83bc4228bb 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2285,24 +2285,24 @@ encode_char: static char utf8_code_length[256] = { - /* Map UTF-8 encoded prefix byte to sequence length. zero means - illegal prefix. see RFC 2279 for details */ + /* 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, - 1, 1, 1, 1, 1, 1, 1, 1, 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, /* 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, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 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, @@ -2332,6 +2332,7 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, { const char *starts = s; int n; + int k; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; @@ -2415,7 +2416,9 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, else { errmsg = "unexpected end of data"; startinpos = s-starts; - endinpos = size; + endinpos = startinpos+1; + for (k=1; (k < size-startinpos) && ((s[k]&0xC0) == 0x80); k++) + endinpos++; goto utf8Error; } } @@ -2423,7 +2426,7 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, switch (n) { case 0: - errmsg = "unexpected code byte"; + errmsg = "invalid start byte"; startinpos = s-starts; endinpos = startinpos+1; goto utf8Error; @@ -2436,63 +2439,67 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, case 2: if ((s[1] & 0xc0) != 0x80) { - errmsg = "invalid data"; + errmsg = "invalid continuation byte"; startinpos = s-starts; - endinpos = startinpos+2; + endinpos = startinpos + 1; goto utf8Error; } ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f); - if (ch < 0x80) { - startinpos = s-starts; - endinpos = startinpos+2; - errmsg = "illegal encoding"; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + 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, + codepoints: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */ if ((s[1] & 0xc0) != 0x80 || - (s[2] & 0xc0) != 0x80) { - errmsg = "invalid data"; + (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+3; + 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); - if (ch < 0x0800 || (ch >= 0xd800 && ch <= 0xDFFF)) { - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+3; - goto utf8Error; - } - else - *p++ = (Py_UNICODE)ch; + 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) { - errmsg = "invalid data"; + (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+4; + 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); - /* validate and convert to UTF-16 */ - if ((ch < 0x10000) /* minimum value allowed for 4 - byte encoding */ - || (ch > 0x10ffff)) /* maximum value allowed for - UTF-16 */ - { - errmsg = "illegal encoding"; - startinpos = s-starts; - endinpos = startinpos+4; - goto utf8Error; - } + ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); + assert ((ch > 0xFFFF) && (ch <= 0x10ffff)); + #ifdef Py_UNICODE_WIDE *p++ = (Py_UNICODE)ch; #else @@ -2508,13 +2515,6 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, *p++ = (Py_UNICODE)(0xDC00 + (ch & 0x03FF)); #endif break; - - default: - /* Other sizes are only needed for UCS-4 */ - errmsg = "unsupported Unicode code range"; - startinpos = s-starts; - endinpos = startinpos+n; - goto utf8Error; } s += n; continue; -- cgit v1.2.1 From 1cbebdd8afa4a88b0006513b2b1af00d9dcbc08a Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 2 Jul 2010 19:45:07 +0000 Subject: Merged revisions 82447 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r82447 | benjamin.peterson | 2010-07-02 14:41:39 -0500 (Fri, 02 Jul 2010) | 1 line add space ........ --- Objects/floatobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index a2c281eaf8..2b61d2ccda 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1172,7 +1172,7 @@ float_hex(PyObject *v) return float_str((PyFloatObject *)v); if (x == 0.0) { - if(copysign(1.0, x) == -1.0) + if (copysign(1.0, x) == -1.0) return PyUnicode_FromString("-0x0.0p+0"); else return PyUnicode_FromString("0x0.0p+0"); -- cgit v1.2.1 From 91544b8cfb79873ad6b5204c593d494cb2e99977 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sat, 3 Jul 2010 04:52:19 +0000 Subject: Update comment about surrogates. --- Objects/unicodeobject.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 83bc4228bb..dba3d365fc 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2450,11 +2450,11 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, 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, - codepoints: d800-dfff; UTF-8: \xed\xa0\x80-\xed\xbf\xbf. */ + /* Decoding UTF-8 sequences in range \xed\xa0\x80-\xed\xbf\xbf + will result in surrogates in range d800-dfff. Surrogates are + not valid UTF-8 so they are rejected. + See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || ((unsigned char)s[0] == 0xE0 && -- cgit v1.2.1 From 9e27dd8a5a20104c4b761a58707253aa9d1af8ba Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 5 Jul 2010 12:00:56 +0000 Subject: Fix the docstrings of the capitalize method. --- Objects/bytes_methods.c | 3 ++- Objects/unicodeobject.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 215a1fac0f..b41b3d9b80 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -332,7 +332,8 @@ _Py_bytes_title(char *result, char *s, Py_ssize_t len) 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)."); +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) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index dba3d365fc..6270e9bffc 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6705,7 +6705,7 @@ PyDoc_STRVAR(capitalize__doc__, "S.capitalize() -> str\n\ \n\ Return a capitalized version of S, i.e. make the first character\n\ -have upper case."); +have upper case and the rest lower case."); static PyObject* unicode_capitalize(PyUnicodeObject *self) -- cgit v1.2.1 From 846dc919549844167d990ebbc49b65149b10ae10 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 5 Jul 2010 15:01:22 +0000 Subject: cleanup basicsize logic #3268 --- Objects/typeobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2d9d031a09..268a9244bb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3476,11 +3476,8 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp) static void inherit_special(PyTypeObject *type, PyTypeObject *base) { - Py_ssize_t oldsize, newsize; /* 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_traverse && !type->tp_clear)) { @@ -3507,7 +3504,8 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) type->tp_new = base->tp_new; } } - type->tp_basicsize = newsize; + if (type->tp_basicsize == 0) + type->tp_basicsize = base->tp_basicsize; /* Copy other non-function slots */ -- cgit v1.2.1 From d57030ec4ed47d04bcc1c17496b0bc7a584d6801 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 6 Jul 2010 15:11:44 +0000 Subject: Style nit. --- Objects/floatobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 2b61d2ccda..c75720354f 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1422,7 +1422,7 @@ float_fromhex(PyObject *cls, PyObject *arg) round_up = 1; break; } - if (round_up == 1) { + if (round_up) { x += 2*half_eps; if (top_exp == DBL_MAX_EXP && x == ldexp((double)(2*half_eps), DBL_MANT_DIG)) -- cgit v1.2.1 From 3c05122d780f058b55caf51142856c8e1e0267d7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 7 Jul 2010 20:54:01 +0000 Subject: make struct sequences subclass tuple; kill lots of code This fixes #8413. --- Objects/structseq.c | 225 +++++----------------------------------------------- 1 file changed, 18 insertions(+), 207 deletions(-) (limited to 'Objects') diff --git a/Objects/structseq.c b/Objects/structseq.c index 7031225cb0..647586c4a4 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -30,113 +30,15 @@ PyObject * PyStructSequence_New(PyTypeObject *type) { PyStructSequence *obj; + Py_ssize_t size = REAL_SIZE_TP(type), i; - obj = PyObject_New(PyStructSequence, type); + obj = PyObject_GC_NewVar(PyStructSequence, type, size); if (obj == NULL) return NULL; - Py_SIZE(obj) = VISIBLE_SIZE_TP(type); + for (i = 0; i < size; i++) + obj->ob_item[i] = NULL; - 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; - } + return (PyObject*)obj; } static PyObject * @@ -223,11 +125,6 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject*) res; } -static PyObject * -make_tuple(PyStructSequence *obj) -{ - return structseq_slice(obj, 0, VISIBLE_SIZE(obj)); -} static PyObject * structseq_repr(PyStructSequence *obj) @@ -236,7 +133,6 @@ structseq_repr(PyStructSequence *obj) #define REPR_BUFFER_SIZE 512 #define TYPE_MAXSIZE 100 - PyObject *tup; PyTypeObject *typ = Py_TYPE(obj); int i, removelast = 0; Py_ssize_t len; @@ -246,10 +142,6 @@ structseq_repr(PyStructSequence *obj) /* 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); @@ -262,19 +154,14 @@ structseq_repr(PyStructSequence *obj) char *cname, *crepr; cname = typ->tp_members[i].name; - - val = PyTuple_GetItem(tup, i); - if (cname == NULL || val == NULL) { + if (cname == NULL) return NULL; - } + val = PyStructSequence_GET_ITEM(obj, i); repr = PyObject_Repr(val); - if (repr == NULL) { - Py_DECREF(tup); + if (repr == NULL) return NULL; - } crepr = _PyUnicode_AsString(repr); if (crepr == NULL) { - Py_DECREF(tup); Py_DECREF(repr); return NULL; } @@ -300,7 +187,6 @@ structseq_repr(PyStructSequence *obj) break; } } - Py_DECREF(tup); if (removelast) { /* overwrite last ", " */ pbuf-=2; @@ -311,62 +197,6 @@ structseq_repr(PyStructSequence *obj) return PyUnicode_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) { @@ -409,53 +239,36 @@ structseq_reduce(PyStructSequence* self) 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 */ - 0, /* 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}, + {"__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 */ + sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */ + sizeof(PyObject *), /* tp_itemsize */ + 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (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_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 */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ NULL, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - structseq_richcompare, /* tp_richcompare */ + 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ @@ -494,11 +307,9 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) n_members = i; memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject)); + type->tp_base = &PyTuple_Type; 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) -- cgit v1.2.1 From 17457328fb4fbff7e0d0013456cee257fd3ef2e4 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 8 Jul 2010 22:33:03 +0000 Subject: fix repr of complicated structseqs #9206 --- Objects/structseq.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/structseq.c b/Objects/structseq.c index 647586c4a4..52ff301ff6 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -35,12 +35,27 @@ PyStructSequence_New(PyTypeObject *type) obj = PyObject_GC_NewVar(PyStructSequence, type, size); if (obj == NULL) return NULL; + /* Hack the size of the variable object, so invisible fields don't appear + to Python code. */ + Py_SIZE(obj) = VISIBLE_SIZE_TP(type); for (i = 0; i < size; i++) obj->ob_item[i] = NULL; 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_GC_Del(obj); +} + static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -154,8 +169,11 @@ structseq_repr(PyStructSequence *obj) char *cname, *crepr; cname = typ->tp_members[i].name; - if (cname == NULL) + if (cname == NULL) { + PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL" + " for type %.500s", i, typ->tp_name); return NULL; + } val = PyStructSequence_GET_ITEM(obj, i); repr = PyObject_Repr(val); if (repr == NULL) @@ -249,7 +267,7 @@ static PyTypeObject _struct_sequence_template = { NULL, /* tp_name */ sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */ sizeof(PyObject *), /* tp_itemsize */ - 0, /* tp_dealloc */ + (destructor)structseq_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ -- cgit v1.2.1 From 83acf827034477b0b95ad15170d7ecba82841929 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 9 Jul 2010 19:25:48 +0000 Subject: Silence gcc warning. (In function 'bytearray_init': warning: 'value' may be used uninitialized in this function). --- Objects/bytearrayobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 16350ff8c0..021ab1a531 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -33,6 +33,7 @@ _getbytevalue(PyObject* arg, int *value) PyObject *index = PyNumber_Index(arg); if (index == NULL) { PyErr_Format(PyExc_TypeError, "an integer is required"); + *value = -1; return 0; } face_value = PyLong_AsLong(index); @@ -42,6 +43,7 @@ _getbytevalue(PyObject* arg, int *value) 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)"); + *value = -1; return 0; } -- cgit v1.2.1 From 5dacfdeae1d8cb624fd533bdb67336a707a0f948 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 11 Jul 2010 03:36:35 +0000 Subject: remove unneeded error check --- Objects/stringlib/formatter.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 7b29a9de3a..ba2a251c2f 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -776,14 +776,6 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, 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 */ -- cgit v1.2.1 From 3c4ebb545e75d24f6ac918bb266bc406e15cf37e Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 11 Jul 2010 12:12:00 +0000 Subject: Issue #7616: Fix copying of overlapping memoryview slices with the Intel compiler. --- Objects/memoryobject.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index e92a771dfd..5b3caf272c 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -624,7 +624,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) static int memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) { - Py_ssize_t start, len, bytelen, i; + Py_ssize_t start, len, bytelen; Py_buffer srcview; Py_buffer *view = &(self->view); char *srcbuf, *destbuf; @@ -694,16 +694,8 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf) /* No overlapping */ memcpy(destbuf, srcbuf, bytelen); - else if (destbuf < srcbuf) { - /* Copy in ascending order */ - for (i = 0; i < bytelen; i++) - destbuf[i] = srcbuf[i]; - } - else { - /* Copy in descencing order */ - for (i = bytelen - 1; i >= 0; i--) - destbuf[i] = srcbuf[i]; - } + else + memmove(destbuf, srcbuf, bytelen); PyBuffer_Release(&srcview); return 0; -- cgit v1.2.1 From 917ea3ffa3028d8e32dcb64e4605b5be204e009c Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Mon, 19 Jul 2010 17:58:26 +0000 Subject: Sub-issue of #9036: Fix incorrect use of Py_CHARMASK. --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6270e9bffc..43c827f981 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9242,7 +9242,7 @@ PyObject *PyUnicode_Format(PyObject *format, else if (c >= '0' && c <= '9') { prec = c - '0'; while (--fmtcnt >= 0) { - c = Py_CHARMASK(*fmt++); + c = *fmt++; if (c < '0' || c > '9') break; if ((prec*10) / 10 != prec) { -- cgit v1.2.1 From a1047ef59eacea8f3b31386bb6c4a766d6237fd7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Jul 2010 22:37:19 +0000 Subject: move test_trace.py so as not to conflict with future tests for the trace module --- Objects/typeobject.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 268a9244bb..505ca68c2f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6094,6 +6094,7 @@ supercheck(PyTypeObject *type, PyObject *obj) PyErr_SetString(PyExc_TypeError, "super(type, obj): " "obj must be an instance or subtype of type"); + printf("%s\n", type->tp_name); return NULL; } -- cgit v1.2.1 From b1dabe110111af235ea2829b44e9e9f44aed91ef Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Jul 2010 22:39:34 +0000 Subject: revert unintended changes --- Objects/typeobject.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 505ca68c2f..268a9244bb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6094,7 +6094,6 @@ supercheck(PyTypeObject *type, PyObject *obj) PyErr_SetString(PyExc_TypeError, "super(type, obj): " "obj must be an instance or subtype of type"); - printf("%s\n", type->tp_name); return NULL; } -- cgit v1.2.1 From 110d0e368ac6c08f512820c672424970f2d1eb9c Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 27 Jul 2010 22:08:27 +0000 Subject: Issue #9294: remove dead code in Objects/object.c. Patch by Grant Limberg. --- Objects/object.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 76d018f7f1..ef23ac194a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -258,15 +258,10 @@ _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems) return PyObject_INIT_VAR(op, tp, nitems); } -/* Implementation of PyObject_Print with recursion checking */ -static int -internal_print(PyObject *op, FILE *fp, int flags, int nesting) +int +PyObject_Print(PyObject *op, FILE *fp, int flags) { int ret = 0; - if (nesting > 10) { - PyErr_SetString(PyExc_RuntimeError, "print recursion"); - return -1; - } if (PyErr_CheckSignals()) return -1; #ifdef USE_STACKCHECK @@ -333,12 +328,6 @@ internal_print(PyObject *op, FILE *fp, int flags, int nesting) return ret; } -int -PyObject_Print(PyObject *op, FILE *fp, int flags) -{ - return internal_print(op, fp, flags, 0); -} - /* For debugging convenience. Set a breakpoint here and call it from your DLL */ void _Py_BreakPoint(void) -- cgit v1.2.1 From 6275527d4d272c198a2a4f4ebd1a910d7a14b3c6 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 29 Jul 2010 14:23:06 +0000 Subject: Use Py_CLEAR(). --- Objects/unicodeobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 43c827f981..f2d666de12 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -307,8 +307,7 @@ int unicode_resize(register PyUnicodeObject *unicode, reset: /* Reset the object caches */ if (unicode->defenc) { - Py_DECREF(unicode->defenc); - unicode->defenc = NULL; + Py_CLEAR(unicode->defenc); } unicode->hash = -1; @@ -427,8 +426,7 @@ void unicode_dealloc(register PyUnicodeObject *unicode) unicode->length = 0; } if (unicode->defenc) { - Py_DECREF(unicode->defenc); - unicode->defenc = NULL; + Py_CLEAR(unicode->defenc); } /* Add to free list */ *(PyUnicodeObject **)unicode = free_list; -- cgit v1.2.1 From 5fe7888e6e2f09f874b97a4d40893df2be06eff8 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 1 Aug 2010 08:49:18 +0000 Subject: #8821: do not rely on Unicode strings being terminated with a \u0000, rather explicitly check range before looking for a second surrogate character. --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f2d666de12..bfd19ebbbf 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3734,7 +3734,7 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, ch2 = *s++; size--; - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF && size) { ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; *p++ = '\\'; *p++ = 'U'; @@ -3976,7 +3976,7 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, ch2 = *s++; size--; - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF && size) { ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; *p++ = '\\'; *p++ = 'U'; -- cgit v1.2.1 From 0adda1c4ae62f6c55517e92887cbe02891cf560c Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 1 Aug 2010 10:41:49 +0000 Subject: Issue #9416: Fix some issues with complex formatting where the output with no type specifier failed to match the str output: - format(complex(-0.0, 2.0), '-') omitted the real part from the output, - format(complex(0.0, 2.0), '-') included a sign and parentheses. --- Objects/stringlib/formatter.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index ba2a251c2f..ab57a82288 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -1136,9 +1136,10 @@ format_complex_internal(PyObject *value, /* Omitted type specifier. Should be like str(self). */ type = 'g'; default_precision = PyFloat_STR_PRECISION; - add_parens = 1; - if (re == 0.0) + if (re == 0.0 && copysign(1.0, re) == 1.0) skip_re = 1; + else + add_parens = 1; } if (type == 'n') @@ -1223,8 +1224,11 @@ format_complex_internal(PyObject *value, n_re_digits, n_re_remainder, re_has_decimal, &locale, &tmp_format); - /* Same formatting, but always include a sign. */ - tmp_format.sign = '+'; + /* 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); -- cgit v1.2.1 From 28cf3b414722ac70715da2495867729779bc70e2 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 1 Aug 2010 20:51:02 +0000 Subject: Revert r83395, it introduces test failures and is not necessary anyway since we now have to nul-terminate the string anyway. --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index bfd19ebbbf..f2d666de12 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3734,7 +3734,7 @@ PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, ch2 = *s++; size--; - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF && size) { + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; *p++ = '\\'; *p++ = 'U'; @@ -3976,7 +3976,7 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, ch2 = *s++; size--; - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF && size) { + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; *p++ = '\\'; *p++ = 'U'; -- cgit v1.2.1 From 1aad0f038d6c685f874c66c65ea0e4a8f9cf0dab Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 4 Aug 2010 20:56:28 +0000 Subject: Issue #9337: Make float.__str__ identical to float.__repr__. (And similarly for complex numbers.) --- Objects/complexobject.c | 8 +------- Objects/floatobject.c | 22 +++++----------------- Objects/stringlib/formatter.h | 17 +++++++++++------ 3 files changed, 17 insertions(+), 30 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 7594c886ec..674362f9eb 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -394,12 +394,6 @@ 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) { @@ -1104,7 +1098,7 @@ PyTypeObject PyComplex_Type = { 0, /* tp_as_mapping */ (hashfunc)complex_hash, /* tp_hash */ 0, /* tp_call */ - (reprfunc)complex_str, /* tp_str */ + (reprfunc)complex_repr, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index c75720354f..b792c196e2 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -305,32 +305,20 @@ convert_to_double(PyObject **v, double *dbl) } static PyObject * -float_str_or_repr(PyFloatObject *v, int precision, char format_code) +float_repr(PyFloatObject *v) { PyObject *result; char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - format_code, precision, + 'r', 0, Py_DTSF_ADD_DOT_0, NULL); if (!buf) - return PyErr_NoMemory(); + return PyErr_NoMemory(); result = PyUnicode_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 @@ -1169,7 +1157,7 @@ float_hex(PyObject *v) CONVERT_TO_DOUBLE(v, x); if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) - return float_str((PyFloatObject *)v); + return float_repr((PyFloatObject *)v); if (x == 0.0) { if (copysign(1.0, x) == -1.0) @@ -1873,7 +1861,7 @@ PyTypeObject PyFloat_Type = { 0, /* tp_as_mapping */ (hashfunc)float_hash, /* tp_hash */ 0, /* tp_call */ - (reprfunc)float_str, /* tp_str */ + (reprfunc)float_repr, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index ab57a82288..4fdab06229 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -950,11 +950,12 @@ format_float_internal(PyObject *value, } 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; + /* Omitted type specifier. Behaves in the same way as repr(x) + and str(x) if no precision is given, else like 'g', but with + at least one digit after the decimal point. */ flags |= Py_DTSF_ADD_DOT_0; + type = 'r'; + default_precision = 0; } if (type == 'n') @@ -974,6 +975,8 @@ format_float_internal(PyObject *value, if (precision < 0) precision = default_precision; + else if (type == 'r') + type = 'g'; /* 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" @@ -1134,8 +1137,8 @@ format_complex_internal(PyObject *value, if (type == '\0') { /* Omitted type specifier. Should be like str(self). */ - type = 'g'; - default_precision = PyFloat_STR_PRECISION; + type = 'r'; + default_precision = 0; if (re == 0.0 && copysign(1.0, re) == 1.0) skip_re = 1; else @@ -1149,6 +1152,8 @@ format_complex_internal(PyObject *value, if (precision < 0) precision = default_precision; + else if (type == 'r') + type = 'g'; /* 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" -- cgit v1.2.1 From bd25f9a1c04cd691863db5c73b8d7ecf4f4bcec3 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 6 Aug 2010 09:52:17 +0000 Subject: Issue8757: Implicit set-to-frozenset conversion not thread-safe. --- Objects/setobject.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index b35fef5ed6..3b448daa10 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1846,12 +1846,10 @@ set_contains(PySetObject *so, PyObject *key) if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return -1; PyErr_Clear(); - tmpkey = make_new_set(&PyFrozenSet_Type, NULL); + tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return -1; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); rv = set_contains(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); Py_DECREF(tmpkey); } return rv; @@ -1881,12 +1879,10 @@ set_remove(PySetObject *so, PyObject *key) if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; PyErr_Clear(); - tmpkey = make_new_set(&PyFrozenSet_Type, NULL); + tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return NULL; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); rv = set_discard_key(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); Py_DECREF(tmpkey); if (rv == -1) return NULL; @@ -1915,12 +1911,10 @@ set_discard(PySetObject *so, PyObject *key) if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; PyErr_Clear(); - tmpkey = make_new_set(&PyFrozenSet_Type, NULL); + tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return NULL; - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); result = set_discard(so, tmpkey); - set_swap_bodies((PySetObject *)tmpkey, (PySetObject *)key); Py_DECREF(tmpkey); return result; } -- cgit v1.2.1 From 9fc886127c9332acc1b7b6595dd782969ec2d870 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 6 Aug 2010 18:55:26 +0000 Subject: In PySlice_IndicesEx, clip the step to [-PY_SSIZE_T_MAX, PY_SSIZE_T_MAX] rather than [PY_SSIZE_T_MIN, PY_SSIZE_T_MAX]. --- Objects/sliceobject.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index ee89006688..55fda52987 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -131,7 +131,8 @@ PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, 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) + 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 */ @@ -147,6 +148,13 @@ PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, "slice step cannot be zero"); return -1; } + /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it + * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it + * guards against later undefined behaviour resulting from code that + * does "step = -step" as part of a slice reversal. + */ + if (*step < -PY_SSIZE_T_MAX) + *step = -PY_SSIZE_T_MAX; } defstart = *step < 0 ? length-1 : 0; -- cgit v1.2.1 From d7c481d0704bc2c65a3b7c9cdb155b2b10e8f296 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 6 Aug 2010 21:33:18 +0000 Subject: Issue #9530: Fix a couple of places where undefined behaviour can occur, as a result of signed integer overflow. --- Objects/bytearrayobject.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 021ab1a531..33f80d56f5 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -649,6 +649,11 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu if (!_canresize(self)) return -1; + + if (slicelen == 0) + /* Nothing to do here. */ + return 0; + if (step < 0) { stop = start + 1; start = stop + step * (slicelen - 1) - 1; @@ -665,7 +670,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu self->ob_bytes + cur + 1, lim); } /* Move the tail of the bytes, in one chunk */ - cur = start + slicelen*step; + cur = start + (size_t)slicelen*step; if (cur < (size_t)PyByteArray_GET_SIZE(self)) { memmove(self->ob_bytes + cur - slicelen, self->ob_bytes + cur, @@ -679,7 +684,8 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } else { /* Assign slice */ - Py_ssize_t cur, i; + Py_ssize_t i; + size_t cur; if (needed != slicelen) { PyErr_Format(PyExc_ValueError, -- cgit v1.2.1 From c9c98964a5a5536fbb9426a1b964608fdbd8f8fd Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 7 Aug 2010 05:54:08 +0000 Subject: Fix nit (sentinel on lhs of comparison). --- Objects/iterobject.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/iterobject.c b/Objects/iterobject.c index b534b4af8e..91a93f55be 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -177,9 +177,7 @@ calliter_iternext(calliterobject *it) Py_DECREF(args); if (result != NULL) { int ok; - ok = PyObject_RichCompareBool(result, - it->it_sentinel, - Py_EQ); + ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ); if (ok == 0) return result; /* Common case, fast path */ Py_DECREF(result); -- cgit v1.2.1 From f445cdca00f3dec33ebcf41f25a59afa113470f3 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Sun, 8 Aug 2010 22:07:16 +0000 Subject: Fix #8530: Prevent stringlib fastsearch from reading beyond the front of an array. --- Objects/stringlib/fastsearch.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 7525951c06..e231c587e4 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -140,13 +140,13 @@ fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n, /* got a match! */ return i; /* miss: check if previous character is part of pattern */ - if (!STRINGLIB_BLOOM(mask, s[i-1])) + 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 (!STRINGLIB_BLOOM(mask, s[i-1])) + if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1])) i = i - m; } } -- cgit v1.2.1 From 1002c6b4521a9207ae8a857ab0e3e512f47765c8 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 9 Aug 2010 08:56:25 +0000 Subject: Fix Issue5416 - explain negative value for count in bytes object replace. --- Objects/bytesobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fa31a8090f..4d546105ba 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2150,7 +2150,8 @@ PyDoc_STRVAR(replace__doc__, \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."); +positive, only the first count occurrences are replaced. A\n\ +negative value of count replaces all occurences"); static PyObject * bytes_replace(PyBytesObject *self, PyObject *args) -- cgit v1.2.1 From 20c14d7f3f3a542013ae06136109e3be238e14d2 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 9 Aug 2010 09:03:57 +0000 Subject: spelling mistake. --- Objects/bytesobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 4d546105ba..eb8036065a 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2151,7 +2151,7 @@ PyDoc_STRVAR(replace__doc__, Return a copy of B with all occurrences of subsection\n\ old replaced by new. If the optional argument count is\n\ positive, only the first count occurrences are replaced. A\n\ -negative value of count replaces all occurences"); +negative value of count replaces all occurrences"); static PyObject * bytes_replace(PyBytesObject *self, PyObject *args) -- cgit v1.2.1 From 40cbe578145b5c5e3e7f3cb445a5c490c4938e5b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 10 Aug 2010 16:37:20 +0000 Subject: Issue #9425: create Py_UNICODE_strrchr() function --- Objects/unicodeobject.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f2d666de12..478f9a976e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9965,6 +9965,19 @@ Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c) return NULL; } +Py_UNICODE* +Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) +{ + const Py_UNICODE *p; + p = s + Py_UNICODE_strlen(s); + while (p != s) { + p--; + if (*p == c) + return (Py_UNICODE*)p; + } + return NULL; +} + #ifdef __cplusplus } -- cgit v1.2.1 From c5d1975f4a18ebde60da2cfa55c683f7807b91b3 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Tue, 10 Aug 2010 18:35:01 +0000 Subject: Issue #9530: Fix undefined-behaviour-inducing overflow checks in bytes and bytearray implementations. --- Objects/bytearrayobject.c | 54 ++++++++++++++++++-------------------------- Objects/bytesobject.c | 57 +++++++++++++++++++---------------------------- 2 files changed, 45 insertions(+), 66 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 33f80d56f5..cdc860fc32 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -310,9 +310,9 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) if (count < 0) count = 0; mysize = Py_SIZE(self); - size = mysize * count; - if (count != 0 && size / count != mysize) + if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); + size = mysize * count; result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); if (result != NULL && size != 0) { if (mysize == 1) @@ -335,9 +335,9 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) if (count < 0) count = 0; mysize = Py_SIZE(self); - size = mysize * count; - if (count != 0 && size / count != mysize) + if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); + size = mysize * count; if (size < self->ob_alloc) { Py_SIZE(self) = size; self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ @@ -1505,30 +1505,28 @@ replace_interleave(PyByteArrayObject *self, { char *self_s, *result_s; Py_ssize_t self_len, result_len; - Py_ssize_t count, i, product; + Py_ssize_t count, i; PyByteArrayObject *result; self_len = PyByteArray_GET_SIZE(self); - /* 1 at the end plus 1 after every character */ - count = self_len+1; - if (maxcount < count) + /* 1 at the end plus 1 after every character; + count = min(maxcount, self_len + 1) */ + if (maxcount <= self_len) count = maxcount; + else + /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */ + count = self_len + 1; /* 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) { + assert(count > 0); + if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } + result_len = count * to_len + self_len; if (! (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) ) @@ -1758,7 +1756,7 @@ replace_single_character(PyByteArrayObject *self, char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, product; + Py_ssize_t count; PyByteArrayObject *result; self_s = PyByteArray_AS_STRING(self); @@ -1772,16 +1770,12 @@ replace_single_character(PyByteArrayObject *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) { + assert(count > 0); + if (to_len - 1 > (PY_SSIZE_T_MAX - self_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; - } + result_len = self_len + count * (to_len - 1); if ( (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) @@ -1825,7 +1819,7 @@ replace_substring(PyByteArrayObject *self, char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, offset, product; + Py_ssize_t count, offset; PyByteArrayObject *result; self_s = PyByteArray_AS_STRING(self); @@ -1842,16 +1836,12 @@ replace_substring(PyByteArrayObject *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) { + assert(count > 0); + if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { PyErr_SetString(PyExc_OverflowError, "replace bytes is too long"); return NULL; } + result_len = self_len + count * (to_len - from_len); if ( (result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, result_len)) == NULL) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index eb8036065a..c0c82f73a6 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -579,13 +579,14 @@ PyBytes_Repr(PyObject *obj, int smartquotes) static const char *hexdigits = "0123456789abcdef"; register PyBytesObject* op = (PyBytesObject*) obj; Py_ssize_t length = Py_SIZE(op); - size_t newsize = 3 + 4 * length; + size_t newsize; PyObject *v; - if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) { + if (length > (PY_SSIZE_T_MAX - 3) / 4) { PyErr_SetString(PyExc_OverflowError, "bytes object is too large to make repr"); return NULL; } + newsize = 3 + 4 * length; v = PyUnicode_FromUnicode(NULL, newsize); if (v == NULL) { return NULL; @@ -732,12 +733,12 @@ bytes_repeat(register PyBytesObject *a, register Py_ssize_t n) /* 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)) { + if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) { PyErr_SetString(PyExc_OverflowError, "repeated bytes are too long"); return NULL; } + size = Py_SIZE(a) * n; if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { Py_INCREF(a); return (PyObject *)a; @@ -1687,30 +1688,28 @@ replace_interleave(PyBytesObject *self, { char *self_s, *result_s; Py_ssize_t self_len, result_len; - Py_ssize_t count, i, product; + Py_ssize_t count, i; PyBytesObject *result; self_len = PyBytes_GET_SIZE(self); - /* 1 at the end plus 1 after every character */ - count = self_len+1; - if (maxcount < count) + /* 1 at the end plus 1 after every character; + count = min(maxcount, self_len + 1) */ + if (maxcount <= self_len) count = maxcount; + else + /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */ + count = self_len + 1; /* Check for overflow */ /* result_len = count * to_len + self_len; */ - product = count * to_len; - if (product / to_len != count) { - PyErr_SetString(PyExc_OverflowError, - "replacement bytes are too long"); - return NULL; - } - result_len = product + self_len; - if (result_len < 0) { + assert(count > 0); + if (to_len > (PY_SSIZE_T_MAX - self_len) / count) { PyErr_SetString(PyExc_OverflowError, "replacement bytes are too long"); return NULL; } + result_len = count * to_len + self_len; if (! (result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, result_len)) ) @@ -1939,7 +1938,7 @@ replace_single_character(PyBytesObject *self, char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, product; + Py_ssize_t count; PyBytesObject *result; self_s = PyBytes_AS_STRING(self); @@ -1953,18 +1952,13 @@ replace_single_character(PyBytesObject *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) { + assert(count > 0); + if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) { PyErr_SetString(PyExc_OverflowError, "replacement bytes are too long"); return NULL; } - result_len = self_len + product; - if (result_len < 0) { - PyErr_SetString(PyExc_OverflowError, - "replacment bytes are too long"); - return NULL; - } + result_len = self_len + count * (to_len - 1); if ( (result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, result_len)) == NULL) @@ -2007,7 +2001,7 @@ replace_substring(PyBytesObject *self, char *self_s, *result_s; char *start, *next, *end; Py_ssize_t self_len, result_len; - Py_ssize_t count, offset, product; + Py_ssize_t count, offset; PyBytesObject *result; self_s = PyBytes_AS_STRING(self); @@ -2024,18 +2018,13 @@ replace_substring(PyBytesObject *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, - "replacement bytes are too long"); - return NULL; - } - result_len = self_len + product; - if (result_len < 0) { + assert(count > 0); + if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) { PyErr_SetString(PyExc_OverflowError, "replacement bytes are too long"); return NULL; } + result_len = self_len + count * (to_len-from_len); if ( (result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, result_len)) == NULL) -- cgit v1.2.1 From 35ce36d96009a24d4f588bf27c1c07e2af4fc822 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Wed, 11 Aug 2010 17:31:17 +0000 Subject: Issue #2443: Added a new macro, Py_VA_COPY, which is equivalent to C99 va_copy, but available on all python platforms. Untabified a few unrelated files. --- Objects/abstract.c | 10 +--------- Objects/bytearrayobject.c | 14 +++++++------- Objects/bytesobject.c | 10 +--------- Objects/capsule.c | 36 ++++++++++++++++++------------------ Objects/memoryobject.c | 8 ++++---- Objects/unicodectype.c | 16 ++++++++-------- Objects/unicodeobject.c | 10 +--------- 7 files changed, 40 insertions(+), 64 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index fa2611aec9..d5a5d3c129 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2311,15 +2311,7 @@ objargs_mktuple(va_list va) 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 + Py_VA_COPY(countva, va); while (((PyObject *)va_arg(countva, PyObject *)) != NULL) ++n; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index cdc860fc32..be19a82766 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -936,12 +936,12 @@ bytearray_repr(PyByteArrayObject *self) static PyObject * bytearray_str(PyObject *op) { - if (Py_BytesWarningFlag) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "str() on a bytearray instance", 1)) - return NULL; - } - return bytearray_repr((PyByteArrayObject*)op); + if (Py_BytesWarningFlag) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "str() on a bytearray instance", 1)) + return NULL; + } + return bytearray_repr((PyByteArrayObject*)op); } static PyObject * @@ -1458,7 +1458,7 @@ done: static PyObject * bytearray_maketrans(PyObject *null, PyObject *args) { - return _Py_bytes_maketrans(args); + return _Py_bytes_maketrans(args); } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index c0c82f73a6..41c86d9544 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -173,15 +173,7 @@ PyBytes_FromFormatV(const char *format, va_list vargs) 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 + Py_VA_COPY(count, vargs); /* step 1: figure out how large a buffer we need */ for (f = format; *f; f++) { if (*f == '%') { diff --git a/Objects/capsule.c b/Objects/capsule.c index e25af6c2aa..acd3de637d 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -298,27 +298,27 @@ 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*/ + "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*/ + 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*/ + 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/Objects/memoryobject.c b/Objects/memoryobject.c index 5b3caf272c..70ae6ccea0 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -775,10 +775,10 @@ static PyMappingMethods memory_as_mapping = { }; static PySequenceMethods memory_as_sequence = { - 0, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)memory_item, /* sq_item */ + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)memory_item, /* sq_item */ }; /* Buffer methods */ diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index 1849831e84..db4f513d05 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -63,10 +63,10 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) int delta = ctype->title; if (ctype->flags & NODELTA_MASK) - return delta; + return delta; if (delta >= 32768) - delta -= 65536; + delta -= 65536; return ch + delta; } @@ -114,7 +114,7 @@ int _PyUnicode_ToDecimalDigit(Py_UNICODE ch) int _PyUnicode_IsDecimalDigit(Py_UNICODE ch) { if (_PyUnicode_ToDecimalDigit(ch) < 0) - return 0; + return 0; return 1; } @@ -131,7 +131,7 @@ int _PyUnicode_ToDigit(Py_UNICODE ch) int _PyUnicode_IsDigit(Py_UNICODE ch) { if (_PyUnicode_ToDigit(ch) < 0) - return 0; + return 0; return 1; } @@ -195,9 +195,9 @@ Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->upper; if (ctype->flags & NODELTA_MASK) - return delta; + return delta; if (delta >= 32768) - delta -= 65536; + delta -= 65536; return ch + delta; } @@ -209,9 +209,9 @@ Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->lower; if (ctype->flags & NODELTA_MASK) - return delta; + return delta; if (delta >= 32768) - delta -= 65536; + delta -= 65536; return ch + delta; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 478f9a976e..849f33e076 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -755,15 +755,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) char fmt[61]; /* should be enough for %0width.precisionlld */ 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 + Py_VA_COPY(count, vargs); /* step 1: count the number of %S/%R/%A/%s format specifications * (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/ * PyUnicode_DecodeUTF8() for these objects once during step 3 and put the -- cgit v1.2.1 From 34d649e3c8e3f7041f2ad874d4377e938b3d7eeb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 13 Aug 2010 13:34:52 +0000 Subject: Issue #9425: PyFile_FromFd() ignores the name argument This function is only by imp.find_module() which does return the filename in a separated variable. --- Objects/fileobject.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'Objects') diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 3709e00bc1..9288e35b70 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -29,7 +29,7 @@ PyObject * PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) { - PyObject *io, *stream, *nameobj = NULL; + PyObject *io, *stream; io = PyImport_ImportModule("io"); if (io == NULL) @@ -40,16 +40,8 @@ PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, Py_DECREF(io); if (stream == NULL) return NULL; - if (name != NULL) { - nameobj = PyUnicode_DecodeFSDefault(name); - if (nameobj == NULL) - PyErr_Clear(); - else { - if (PyObject_SetAttrString(stream, "name", nameobj) < 0) - PyErr_Clear(); - Py_DECREF(nameobj); - } - } + /* ignore name attribute because the name attribute of _BufferedIOMixin + and TextIOWrapper is read only */ return stream; } -- cgit v1.2.1 From 5c829d60a6fdece8817e469ceff6441101193fc7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 13 Aug 2010 14:03:48 +0000 Subject: Issue #9425: Create PyErr_WarnFormat() function Similar to PyErr_WarnEx() but use PyUnicode_FromFormatV() to format the warning message. Strip also some trailing spaces. --- Objects/moduleobject.c | 17 +++++++---------- Objects/typeobject.c | 11 ++++------- Objects/unicodeobject.c | 15 ++++++++------- 3 files changed, 19 insertions(+), 24 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 6c6eac1c8d..7b8e1b63c4 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -56,10 +56,6 @@ PyModule_New(const char *name) return NULL; } -static char api_version_warning[] = -"Python C API version mismatch for module %.100s:\ - This Python has API version %d, module %.100s has version %d."; - PyObject * PyModule_Create2(struct PyModuleDef* module, int module_api_version) { @@ -79,12 +75,13 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) } name = module->m_name; if (module_api_version != PYTHON_API_VERSION) { - char message[512]; - PyOS_snprintf(message, sizeof(message), - api_version_warning, name, - PYTHON_API_VERSION, name, - module_api_version); - if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) + int err; + err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "Python C API version mismatch for module %.100s: " + "This Python has API version %d, module %.100s has version %d.", + name, + PYTHON_API_VERSION, name, module_api_version); + if (err) return NULL; } /* Make sure name is fully qualified. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 268a9244bb..7bb686421b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3892,13 +3892,10 @@ PyType_Ready(PyTypeObject *type) tp_reserved) but not tp_richcompare. */ if (type->tp_reserved && !type->tp_richcompare) { int error; - char msg[240]; - PyOS_snprintf(msg, sizeof(msg), - "Type %.100s defines tp_reserved (formerly " - "tp_compare) but not tp_richcompare. " - "Comparisons may not behave as intended.", - type->tp_name); - error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1); + error = PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Type %.100s defines tp_reserved (formerly tp_compare) " + "but not tp_richcompare. Comparisons may not behave as intended.", + type->tp_name); if (error == -1) goto error; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 849f33e076..7c9b882738 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -755,7 +755,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) char fmt[61]; /* should be enough for %0width.precisionlld */ const char *copy; - Py_VA_COPY(count, vargs); + Py_VA_COPY(count, vargs); /* step 1: count the number of %S/%R/%A/%s format specifications * (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/ * PyUnicode_DecodeUTF8() for these objects once during step 3 and put the @@ -1548,12 +1548,13 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode, /* If the codec returns a buffer, raise a warning and convert to bytes */ if (PyByteArray_Check(v)) { - char msg[100]; + int error; PyObject *b; - PyOS_snprintf(msg, sizeof(msg), - "encoder %s returned buffer instead of bytes", - encoding); - if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) { + + error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "encoder %s returned bytearray instead of bytes", + encoding); + if (error) { Py_DECREF(v); return NULL; } @@ -2279,7 +2280,7 @@ char utf8_code_length[256] = { 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, -- cgit v1.2.1 From 0cf2b8108fc6e60f0cbbe2ae00337022afb14c39 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 13 Aug 2010 23:59:58 +0000 Subject: Issue #9542: Create PyUnicode_FSDecoder() function It's a ParseTuple converter: decode bytes objects to unicode using PyUnicode_DecodeFSDefaultAndSize(); str objects are output as-is. * Don't specify surrogateescape error handler in the comments nor the documentation, but PyUnicode_DecodeFSDefaultAndSize() and PyUnicode_EncodeFSDefault() because these functions use strict error handler for the mbcs encoding (on Windows). * Remove PyUnicode_FSConverter() comment in unicodeobject.c to avoid inconsistency with unicodeobject.h. --- Objects/unicodeobject.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7c9b882738..676c693040 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1652,9 +1652,6 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) } } -/* Convert the argument to a bytes object, according to the file - system encoding. The addr param must be a PyObject**. - This is designed to be used with "O&" in PyArg_Parse APIs. */ int PyUnicode_FSConverter(PyObject* arg, void* addr) @@ -1696,6 +1693,47 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) } +int +PyUnicode_FSDecoder(PyObject* arg, void* addr) +{ + PyObject *output = NULL; + Py_ssize_t size; + void *data; + if (arg == NULL) { + Py_DECREF(*(PyObject**)addr); + return 1; + } + if (PyUnicode_Check(arg)) { + output = arg; + Py_INCREF(output); + } + else { + arg = PyBytes_FromObject(arg); + if (!arg) + return 0; + output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(arg), + PyBytes_GET_SIZE(arg)); + Py_DECREF(arg); + if (!output) + return 0; + if (!PyUnicode_Check(output)) { + Py_DECREF(output); + PyErr_SetString(PyExc_TypeError, "decoder failed to return unicode"); + return 0; + } + } + size = PyUnicode_GET_SIZE(output); + data = PyUnicode_AS_UNICODE(output); + if (size != Py_UNICODE_strlen(data)) { + PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + Py_DECREF(output); + return 0; + } + *(PyObject**)addr = output; + return Py_CLEANUP_SUPPORTED; +} + + char* _PyUnicode_AsStringAndSize(PyObject *unicode, Py_ssize_t *psize) { -- cgit v1.2.1 From 6f7cb958de1fba1e11571e1d9991dcf3b93eacce Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 15 Aug 2010 17:12:55 +0000 Subject: Fix some compilation warnings under 64-bit Windows (issue #9566). Some of these are genuine bugs with objects bigger than 2GB, but my system doesn't allow me to write tests for it. --- Objects/bytearrayobject.c | 4 ++-- Objects/bytesobject.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index be19a82766..283102ae6f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1214,7 +1214,7 @@ 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; + Py_ssize_t pos; PyErr_Clear(); if (_getbuffer(arg, &varg) < 0) return -1; @@ -1228,7 +1228,7 @@ bytearray_contains(PyObject *self, PyObject *arg) return -1; } - return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL; + return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 41c86d9544..77f193cf45 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -770,7 +770,7 @@ bytes_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; + Py_ssize_t pos; PyErr_Clear(); if (_getbuffer(arg, &varg) < 0) return -1; @@ -784,7 +784,7 @@ bytes_contains(PyObject *self, PyObject *arg) return -1; } - return memchr(PyBytes_AS_STRING(self), ival, Py_SIZE(self)) != NULL; + return memchr(PyBytes_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL; } static PyObject * @@ -1654,7 +1654,7 @@ return_self(PyBytesObject *self) } Py_LOCAL_INLINE(Py_ssize_t) -countchar(const char *target, int target_len, char c, Py_ssize_t maxcount) +countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount) { Py_ssize_t count=0; const char *start=target; @@ -2609,7 +2609,7 @@ PyBytes_FromObject(PyObject *x) Py_DECREF(new); return NULL; } - ((PyBytesObject *)new)->ob_sval[i] = value; + ((PyBytesObject *)new)->ob_sval[i] = (char) value; } return new; } @@ -2630,7 +2630,7 @@ PyBytes_FromObject(PyObject *x) Py_DECREF(new); return NULL; } - ((PyBytesObject *)new)->ob_sval[i] = value; + ((PyBytesObject *)new)->ob_sval[i] = (char) value; } return new; } @@ -2685,7 +2685,7 @@ PyBytes_FromObject(PyObject *x) if (_PyBytes_Resize(&new, size) < 0) goto error; } - ((PyBytesObject *)new)->ob_sval[i] = value; + ((PyBytesObject *)new)->ob_sval[i] = (char) value; } _PyBytes_Resize(&new, i); -- cgit v1.2.1 From 6934957f11e2cea503fe509ec98ab24602105898 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 15 Aug 2010 17:38:46 +0000 Subject: Fix indentation and remove dead code. --- Objects/bytes_methods.c | 230 +++++++++++++++++++++--------------------------- 1 file changed, 98 insertions(+), 132 deletions(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index b41b3d9b80..099cee60a5 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -246,23 +246,15 @@ 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; + Py_ssize_t i; - /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (!newobj) - return NULL; + Py_MEMCPY(result, cptr, len); - s = PyBytes_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); - } + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(result[i]); + if (Py_ISUPPER(c)) + result[i] = Py_TOLOWER(c); + } } @@ -274,23 +266,15 @@ 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 = PyBytes_FromStringAndSize(NULL, len); - if (!newobj) - return NULL; + Py_ssize_t i; - s = PyBytes_AS_STRING(newobj); - */ + Py_MEMCPY(result, cptr, len); - 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); - } + for (i = 0; i < len; i++) { + int c = Py_CHARMASK(result[i]); + if (Py_ISLOWER(c)) + result[i] = Py_TOUPPER(c); + } } @@ -303,29 +287,23 @@ 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 = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_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; - } + Py_ssize_t i; + int previous_is_cased = 0; + + 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; + } } @@ -338,30 +316,24 @@ and the rest lower-cased."); void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len) { - Py_ssize_t i; - - /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_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++; - } + Py_ssize_t i; + + 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++; + } } @@ -374,26 +346,20 @@ to lowercase ASCII and vice versa."); void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len) { - Py_ssize_t i; - - /* - newobj = PyBytes_FromStringAndSize(NULL, len); - if (newobj == NULL) - return NULL; - s_new = PyBytes_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++; + Py_ssize_t i; + + 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++; + } } @@ -419,47 +385,47 @@ _getbuffer(PyObject *obj, Py_buffer *view) } if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; + return -1; return view->len; } PyObject * _Py_bytes_maketrans(PyObject *args) { - PyObject *frm, *to, *res = NULL; - Py_buffer bfrm, bto; - Py_ssize_t i; - char *p; - - bfrm.len = -1; - bto.len = -1; - - if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) - return NULL; - if (_getbuffer(frm, &bfrm) < 0) - return NULL; - if (_getbuffer(to, &bto) < 0) - goto done; - if (bfrm.len != bto.len) { - PyErr_Format(PyExc_ValueError, - "maketrans arguments must have same length"); - goto done; - } - res = PyBytes_FromStringAndSize(NULL, 256); - if (!res) { - goto done; - } - p = PyBytes_AS_STRING(res); - for (i = 0; i < 256; i++) - p[i] = i; - for (i = 0; i < bfrm.len; i++) { - p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; - } + PyObject *frm, *to, *res = NULL; + Py_buffer bfrm, bto; + Py_ssize_t i; + char *p; + + bfrm.len = -1; + bto.len = -1; + + if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) + return NULL; + if (_getbuffer(frm, &bfrm) < 0) + return NULL; + if (_getbuffer(to, &bto) < 0) + goto done; + if (bfrm.len != bto.len) { + PyErr_Format(PyExc_ValueError, + "maketrans arguments must have same length"); + goto done; + } + res = PyBytes_FromStringAndSize(NULL, 256); + if (!res) { + goto done; + } + p = PyBytes_AS_STRING(res); + for (i = 0; i < 256; i++) + p[i] = i; + for (i = 0; i < bfrm.len; i++) { + p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + } - done: - if (bfrm.len != -1) - PyBuffer_Release(&bfrm); - if (bto.len != -1) - PyBuffer_Release(&bto); - return res; +done: + if (bfrm.len != -1) + PyBuffer_Release(&bfrm); + if (bto.len != -1) + PyBuffer_Release(&bto); + return res; } -- cgit v1.2.1 From 9486ace53954ce99805405df96eb2378cbee31c7 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 15 Aug 2010 17:41:31 +0000 Subject: Fix (harmless) warning with MSVC. --- Objects/bytes_methods.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 099cee60a5..ef91b7f337 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -417,7 +417,7 @@ _Py_bytes_maketrans(PyObject *args) } p = PyBytes_AS_STRING(res); for (i = 0; i < 256; i++) - p[i] = i; + p[i] = (char) i; for (i = 0; i < bfrm.len; i++) { p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; } -- cgit v1.2.1 From 2b4ff19f36b196ae4f424f63131e897a48c20d82 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Mon, 16 Aug 2010 20:17:07 +0000 Subject: Issue #8983: Corrected docstrings. --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7bb686421b..1babcb605c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2515,7 +2515,7 @@ static PyMethodDef type_methods[] = { {"__instancecheck__", type___instancecheck__, METH_O, PyDoc_STR("__instancecheck__() -> check if an object is an instance")}, {"__subclasscheck__", type___subclasscheck__, METH_O, - PyDoc_STR("__subclasschck__ -> check if an class is a subclass")}, + PyDoc_STR("__subclasscheck__() -> check if a class is a subclass")}, {0} }; @@ -5521,7 +5521,7 @@ static slotdef slotdefs[] = { wrap_descr_delete, "descr.__delete__(obj)"), FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " - "see x.__class__.__doc__ for signature", + "see help(type(x)) for signature", PyWrapperFlag_KEYWORDS), TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""), -- cgit v1.2.1 From 26fd2a01ce558290dc8c4f27c8b783683f0b6ee1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 16 Aug 2010 22:03:11 +0000 Subject: Issue #9425: Create Py_UNICODE_strncmp() function The code is based on strncmp() of the libiberty library, function in the public domain. --- Objects/unicodeobject.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 676c693040..9fd342bf0d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9986,6 +9986,23 @@ Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2) return 0; } +int +Py_UNICODE_strncmp(const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) +{ + register Py_UNICODE u1, u2; + for (; n != 0; n--) { + u1 = *s1; + u2 = *s2; + if (u1 != u2) + return (u1 < u2) ? -1 : +1; + if (u1 == '\0') + return 0; + s1++; + s2++; + } + return 0; +} + Py_UNICODE* Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c) { -- cgit v1.2.1 From b3571357ef37ed51a71a0156ccc9d383c4c125e4 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 17 Aug 2010 17:55:07 +0000 Subject: Issue #9612: The set object is now 64-bit clean under Windows. --- Objects/setobject.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 3b448daa10..e275bcc9d4 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -349,7 +349,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) } else { /* ACTIVE */ --i; - set_insert_clean(so, entry->key, entry->hash); + set_insert_clean(so, entry->key, (long) entry->hash); } } @@ -368,7 +368,7 @@ set_add_entry(register PySetObject *so, setentry *entry) assert(so->fill <= so->mask); /* at least one empty slot */ n_used = so->used; Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, entry->hash) == -1) { + if (set_insert_key(so, entry->key, (long) entry->hash) == -1) { Py_DECREF(entry->key); return -1; } @@ -409,7 +409,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry) { register setentry *entry; PyObject *old_key; - entry = (so->lookup)(so, oldentry->key, oldentry->hash); + entry = (so->lookup)(so, oldentry->key, (long) oldentry->hash); if (entry == NULL) return -1; if (entry->key == NULL || entry->key == dummy) @@ -660,7 +660,7 @@ set_merge(PySetObject *so, PyObject *otherset) if (entry->key != NULL && entry->key != dummy) { Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, entry->hash) == -1) { + if (set_insert_key(so, entry->key, (long) entry->hash) == -1) { Py_DECREF(entry->key); return -1; } @@ -694,7 +694,7 @@ set_contains_entry(PySetObject *so, setentry *entry) PyObject *key; setentry *lu_entry; - lu_entry = (so->lookup)(so, entry->key, entry->hash); + lu_entry = (so->lookup)(so, entry->key, (long) entry->hash); if (lu_entry == NULL) return -1; key = lu_entry->key; @@ -769,14 +769,14 @@ frozenset_hash(PyObject *self) if (so->hash != -1) return so->hash; - hash *= PySet_GET_SIZE(self) + 1; + hash *= (long) 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; + h = (long) entry->hash; hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u; } hash = hash * 69069L + 907133923L; @@ -816,7 +816,7 @@ 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 PyLong_FromLong(len); + return PyLong_FromSsize_t(len); } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); @@ -1547,7 +1547,7 @@ set_difference(PySetObject *so, PyObject *other) setentry entrycopy; entrycopy.hash = entry->hash; entrycopy.key = entry->key; - if (!_PyDict_Contains(other, entry->key, entry->hash)) { + if (!_PyDict_Contains(other, entry->key, (long) entry->hash)) { if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { Py_DECREF(result); return NULL; @@ -2309,7 +2309,7 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash) if (set_next((PySetObject *)set, pos, &entry) == 0) return 0; *key = entry->key; - *hash = entry->hash; + *hash = (long) entry->hash; return 1; } -- cgit v1.2.1 From b3a1d9ef37f0f587204963b8d82d84358ce91516 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Aug 2010 23:37:11 +0000 Subject: Issue #9425: Create PyModule_GetFilenameObject() function ... to get the filename as a unicode object, instead of a byte string. Function needed to support unencodable filenames. Deprecate PyModule_GetFilename() in favor on the new function. --- Objects/moduleobject.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 7b8e1b63c4..3a95261028 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -188,8 +188,8 @@ PyModule_GetName(PyObject *m) return _PyUnicode_AsString(nameobj); } -static PyObject* -module_getfilename(PyObject *m) +PyObject* +PyModule_GetFilenameObject(PyObject *m) { PyObject *d; PyObject *fileobj; @@ -205,6 +205,7 @@ module_getfilename(PyObject *m) PyErr_SetString(PyExc_SystemError, "module filename missing"); return NULL; } + Py_INCREF(fileobj); return fileobj; } @@ -212,10 +213,13 @@ const char * PyModule_GetFilename(PyObject *m) { PyObject *fileobj; - fileobj = module_getfilename(m); + char *utf8; + fileobj = PyModule_GetFilenameObject(m); if (fileobj == NULL) return NULL; - return _PyUnicode_AsString(fileobj); + utf8 = _PyUnicode_AsString(fileobj); + Py_DECREF(fileobj); + return utf8; } PyModuleDef* @@ -346,19 +350,21 @@ static PyObject * module_repr(PyModuleObject *m) { const char *name; - PyObject *filename; + PyObject *filename, *repr; name = PyModule_GetName((PyObject *)m); if (name == NULL) { PyErr_Clear(); name = "?"; } - filename = module_getfilename((PyObject *)m); + filename = PyModule_GetFilenameObject((PyObject *)m); if (filename == NULL) { PyErr_Clear(); return PyUnicode_FromFormat("", name); } - return PyUnicode_FromFormat("", name, filename); + repr = PyUnicode_FromFormat("", name, filename); + Py_DECREF(filename); + return repr; } static int -- cgit v1.2.1 From 8d5b2896cdb7c6a4e8ff9f0566bd75cec0b50651 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Wed, 18 Aug 2010 20:44:58 +0000 Subject: #5127: Even on narrow unicode builds, the C functions that access the Unicode Database (Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL, and others) now accept and return characters from the full Unicode range (Py_UCS4). The differences from Python code are few: - unicodedata.numeric(), unicodedata.decimal() and unicodedata.digit() now return the correct value for large code points - repr() may consider more characters as printable. --- Objects/unicodectype.c | 50 ++++++++++----------- Objects/unicodetype_db.h | 114 ++--------------------------------------------- 2 files changed, 27 insertions(+), 137 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index db4f513d05..f6e3250824 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -26,9 +26,9 @@ #define NUMERIC_MASK 0x1000 typedef struct { - const Py_UNICODE upper; - const Py_UNICODE lower; - const Py_UNICODE title; + const Py_UCS4 upper; + const Py_UCS4 lower; + const Py_UCS4 title; const unsigned char decimal; const unsigned char digit; const unsigned short flags; @@ -37,15 +37,13 @@ typedef struct { #include "unicodetype_db.h" static const _PyUnicode_TypeRecord * -gettyperecord(Py_UNICODE code) +gettyperecord(Py_UCS4 code) { int index; -#ifdef Py_UNICODE_WIDE if (code >= 0x110000) index = 0; else -#endif { index = index1[(code>>SHIFT)]; index = index2[(index<title; @@ -74,7 +72,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) /* Returns 1 for Unicode characters having the category 'Lt', 0 otherwise. */ -int _PyUnicode_IsTitlecase(Py_UNICODE ch) +int _PyUnicode_IsTitlecase(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -84,7 +82,7 @@ int _PyUnicode_IsTitlecase(Py_UNICODE ch) /* Returns 1 for Unicode characters having the XID_Start property, 0 otherwise. */ -int _PyUnicode_IsXidStart(Py_UNICODE ch) +int _PyUnicode_IsXidStart(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -94,7 +92,7 @@ int _PyUnicode_IsXidStart(Py_UNICODE ch) /* Returns 1 for Unicode characters having the XID_Continue property, 0 otherwise. */ -int _PyUnicode_IsXidContinue(Py_UNICODE ch) +int _PyUnicode_IsXidContinue(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -104,14 +102,14 @@ int _PyUnicode_IsXidContinue(Py_UNICODE ch) /* Returns the integer decimal (0-9) for Unicode characters having this property, -1 otherwise. */ -int _PyUnicode_ToDecimalDigit(Py_UNICODE ch) +int _PyUnicode_ToDecimalDigit(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1; } -int _PyUnicode_IsDecimalDigit(Py_UNICODE ch) +int _PyUnicode_IsDecimalDigit(Py_UCS4 ch) { if (_PyUnicode_ToDecimalDigit(ch) < 0) return 0; @@ -121,14 +119,14 @@ int _PyUnicode_IsDecimalDigit(Py_UNICODE ch) /* Returns the integer digit (0-9) for Unicode characters having this property, -1 otherwise. */ -int _PyUnicode_ToDigit(Py_UNICODE ch) +int _PyUnicode_ToDigit(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1; } -int _PyUnicode_IsDigit(Py_UNICODE ch) +int _PyUnicode_IsDigit(Py_UCS4 ch) { if (_PyUnicode_ToDigit(ch) < 0) return 0; @@ -138,7 +136,7 @@ int _PyUnicode_IsDigit(Py_UNICODE ch) /* Returns the numeric value as double for Unicode characters having this property, -1.0 otherwise. */ -int _PyUnicode_IsNumeric(Py_UNICODE ch) +int _PyUnicode_IsNumeric(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -158,7 +156,7 @@ int _PyUnicode_IsNumeric(Py_UNICODE ch) * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR) * Zs (Separator, Space) other than ASCII space('\x20'). */ -int _PyUnicode_IsPrintable(Py_UNICODE ch) +int _PyUnicode_IsPrintable(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -170,7 +168,7 @@ int _PyUnicode_IsPrintable(Py_UNICODE ch) /* Returns 1 for Unicode characters having the category 'Ll', 0 otherwise. */ -int _PyUnicode_IsLowercase(Py_UNICODE ch) +int _PyUnicode_IsLowercase(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -180,7 +178,7 @@ int _PyUnicode_IsLowercase(Py_UNICODE ch) /* Returns 1 for Unicode characters having the category 'Lu', 0 otherwise. */ -int _PyUnicode_IsUppercase(Py_UNICODE ch) +int _PyUnicode_IsUppercase(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -190,7 +188,7 @@ int _PyUnicode_IsUppercase(Py_UNICODE ch) /* Returns the uppercase Unicode characters corresponding to ch or just ch if no uppercase mapping is known. */ -Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) +Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->upper; @@ -204,7 +202,7 @@ Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) /* Returns the lowercase Unicode characters corresponding to ch or just ch if no lowercase mapping is known. */ -Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) +Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->lower; @@ -218,7 +216,7 @@ Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) /* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt', 'Lo' or 'Lm', 0 otherwise. */ -int _PyUnicode_IsAlpha(Py_UNICODE ch) +int _PyUnicode_IsAlpha(Py_UCS4 ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); @@ -230,27 +228,27 @@ int _PyUnicode_IsAlpha(Py_UNICODE ch) /* Export the interfaces using the wchar_t type for portability reasons: */ -int _PyUnicode_IsLowercase(Py_UNICODE ch) +int _PyUnicode_IsLowercase(Py_UCS4 ch) { return iswlower(ch); } -int _PyUnicode_IsUppercase(Py_UNICODE ch) +int _PyUnicode_IsUppercase(Py_UCS4 ch) { return iswupper(ch); } -Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch) +Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch) { return towlower(ch); } -Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) +Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch) { return towupper(ch); } -int _PyUnicode_IsAlpha(Py_UNICODE ch) +int _PyUnicode_IsAlpha(Py_UCS4 ch) { return iswalpha(ch); } diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 424a317219..637f6298cd 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -1980,7 +1980,7 @@ static unsigned char index2[] = { /* Returns the numeric value as double for Unicode characters * having this property, -1.0 otherwise. */ -double _PyUnicode_ToNumeric(Py_UNICODE ch) +double _PyUnicode_ToNumeric(Py_UCS4 ch) { switch (ch) { case 0x0F33: @@ -2031,7 +2031,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xABF0: case 0xF9B2: case 0xFF10: -#ifdef Py_UNICODE_WIDE case 0x1018A: case 0x104A0: case 0x1D7CE: @@ -2041,7 +2040,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7F6: case 0x1F100: case 0x1F101: -#endif return (double) 0.0; case 0x0031: case 0x00B9: @@ -2105,7 +2103,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA51: case 0xABF1: case 0xFF11: -#ifdef Py_UNICODE_WIDE case 0x10107: case 0x10142: case 0x10158: @@ -2135,7 +2132,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x1D7F7: case 0x1F102: case 0x2092A: -#endif return (double) 1.0; case 0x2152: return (double) 1.0/10.0; @@ -2147,46 +2143,36 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2210,7 +2196,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x62FE: case 0xF973: case 0xF9FD: -#ifdef Py_UNICODE_WIDE case 0x10110: case 0x10149: case 0x10150: @@ -2229,7 +2214,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10B7C: case 0x10E69: case 0x1D369: -#endif return (double) 10.0; case 0x0BF1: case 0x0D71: @@ -2239,7 +2223,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x4F70: case 0x767E: case 0x964C: -#ifdef Py_UNICODE_WIDE case 0x10119: case 0x1014B: case 0x10152: @@ -2251,7 +2234,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x10B5E: case 0x10B7E: case 0x10E72: -#endif return (double) 100.0; case 0x0BF2: case 0x0D72: @@ -2261,7 +2243,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x4EDF: case 0x5343: case 0x9621: -#ifdef Py_UNICODE_WIDE case 0x10122: case 0x1014D: case 0x10154: @@ -2270,17 +2251,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2414,7 +2392,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xABF2: case 0xF978: case 0xFF12: -#ifdef Py_UNICODE_WIDE case 0x10108: case 0x1015B: case 0x1015C: @@ -2445,15 +2422,12 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2465,7 +2439,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x3039: case 0x5344: case 0x5EFF: -#ifdef Py_UNICODE_WIDE case 0x10111: case 0x103D4: case 0x1085C: @@ -2475,21 +2448,14 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2571,7 +2537,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xABF3: case 0xF96B: case 0xFF13: -#ifdef Py_UNICODE_WIDE case 0x10109: case 0x104A3: case 0x1085A: @@ -2605,7 +2570,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x20B19: case 0x22998: case 0x23B1B: -#endif return (double) 3.0; case 0x09F6: case 0xA835: @@ -2616,9 +2580,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2628,28 +2590,20 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2724,7 +2678,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA54: case 0xABF4: case 0xFF14: -#ifdef Py_UNICODE_WIDE case 0x1010A: case 0x104A4: case 0x10A43: @@ -2756,34 +2709,25 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2858,7 +2802,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA55: case 0xABF5: case 0xFF15: -#ifdef Py_UNICODE_WIDE case 0x1010B: case 0x10143: case 0x10148: @@ -2887,14 +2830,11 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; @@ -2903,7 +2843,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0x217C: case 0x2186: case 0x32BF: -#ifdef Py_UNICODE_WIDE case 0x10114: case 0x10144: case 0x1014A: @@ -2917,11 +2856,9 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -2932,22 +2869,17 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3007,7 +2939,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xF9D1: case 0xF9D3: case 0xFF16: -#ifdef Py_UNICODE_WIDE case 0x1010C: case 0x104A6: case 0x10E65: @@ -3026,28 +2957,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3104,7 +3026,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA57: case 0xABF7: case 0xFF17: -#ifdef Py_UNICODE_WIDE case 0x1010D: case 0x104A7: case 0x10E66: @@ -3124,32 +3045,23 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3204,7 +3116,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA58: case 0xABF8: case 0xFF18: -#ifdef Py_UNICODE_WIDE case 0x1010E: case 0x104A8: case 0x10E67: @@ -3222,28 +3133,19 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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: @@ -3299,7 +3201,6 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) case 0xAA59: case 0xABF9: case 0xFF19: -#ifdef Py_UNICODE_WIDE case 0x1010F: case 0x104A9: case 0x10E68: @@ -3320,32 +3221,23 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) 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; } @@ -3353,7 +3245,7 @@ double _PyUnicode_ToNumeric(Py_UNICODE ch) /* 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) +int _PyUnicode_IsWhitespace(register const Py_UCS4 ch) { #ifdef WANT_WCTYPE_FUNCTIONS return iswspace(ch); @@ -3399,7 +3291,7 @@ int _PyUnicode_IsWhitespace(register const Py_UNICODE ch) * property 'BK', 'CR', 'LF' or 'NL' or having bidirectional * type 'B', 0 otherwise. */ -int _PyUnicode_IsLinebreak(register const Py_UNICODE ch) +int _PyUnicode_IsLinebreak(register const Py_UCS4 ch) { switch (ch) { case 0x000A: -- cgit v1.2.1 From fd751a66960636a6dadbbb095635f9a39fc5b2fc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Aug 2010 22:26:50 +0000 Subject: Fix PyUnicode_EncodeFSDefault() indentation --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9fd342bf0d..c50f60165b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1480,8 +1480,8 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) "surrogateescape"); } else return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - "surrogateescape"); + PyUnicode_GET_SIZE(unicode), + "surrogateescape"); } PyObject *PyUnicode_AsEncodedString(PyObject *unicode, -- cgit v1.2.1 From 3d39f22282e76e598bba57fb5adb07a003802879 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 23 Aug 2010 19:35:39 +0000 Subject: reorder and save a comparison --- Objects/listobject.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 0dab7843af..88478f3db0 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1934,17 +1934,17 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) } } - /* 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); nremaining = saved_ob_size; if (nremaining < 2) goto succeed; + /* Reverse sort stability achieved by initially reversing the list, + applying a stable forward sort, then reversing the final result. */ + if (reverse) + reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size); + /* March over the array once, left to right, finding natural runs, * and extending short natural runs to minrun elements. */ -- cgit v1.2.1 From 8b4800c8a891a3954f91ebb91c7caf06ea266074 Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Tue, 24 Aug 2010 21:57:33 +0000 Subject: Issue 8781: On systems a signed 4-byte wchar_t and a 4-byte Py_UNICODE, use memcpy to convert between the two (as already done when wchar_t is unsigned) --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c50f60165b..4c4b43c0e1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -664,7 +664,7 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w, return NULL; /* Copy the wchar_t data into the new object */ -#ifdef HAVE_USABLE_WCHAR_T +#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T memcpy(unicode->str, w, size * sizeof(wchar_t)); #else { @@ -1167,7 +1167,7 @@ Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, if (size > PyUnicode_GET_SIZE(unicode)) size = PyUnicode_GET_SIZE(unicode) + 1; -#ifdef HAVE_USABLE_WCHAR_T +#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T memcpy(w, unicode->str, size * sizeof(wchar_t)); #else { -- cgit v1.2.1 From f17ef6a9fef81af89357db6d6dbd8d1d8b9666d0 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 25 Aug 2010 23:13:17 +0000 Subject: basicsize and itemsize are Py_ssize_t #9688 --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1babcb605c..8b74e1e076 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -189,8 +189,8 @@ assign_version_tag(PyTypeObject *type) static PyMemberDef type_members[] = { - {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, - {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, + {"__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}, -- cgit v1.2.1 From 22e40d400bdd8191ae91ecac5a8b50a1e18d9193 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 28 Aug 2010 18:17:03 +0000 Subject: Issue #1868: Eliminate subtle timing issues in thread-local objects by getting rid of the cached copy of thread-local attribute dictionary. --- Objects/object.c | 113 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 48 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index ef23ac194a..3bde659c39 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -954,7 +954,7 @@ _PyObject_NextNotImplemented(PyObject *self) /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ PyObject * -PyObject_GenericGetAttr(PyObject *obj, PyObject *name) +_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) { PyTypeObject *tp = Py_TYPE(obj); PyObject *descr = NULL; @@ -990,36 +990,37 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) } } - /* Inline _PyObject_GetDictPtr */ - dictoffset = tp->tp_dictoffset; - if (dictoffset != 0) { - PyObject *dict; - 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; + 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) { @@ -1042,8 +1043,15 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) return res; } +PyObject * +PyObject_GenericGetAttr(PyObject *obj, PyObject *name) +{ + return _PyObject_GenericGetAttrWithDict(obj, name, NULL); +} + int -PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) +_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, + PyObject *value, PyObject *dict) { PyTypeObject *tp = Py_TYPE(obj); PyObject *descr; @@ -1075,27 +1083,29 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) } } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL) { - PyObject *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 (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); @@ -1117,6 +1127,13 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) 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 */ -- cgit v1.2.1 From 287b0f40521c46d392fc97e74b78270180d5b7e2 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 1 Sep 2010 12:58:21 +0000 Subject: Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become _Py_add_one_to_C() and _Py_add_one_to_F(), respectively. --- Objects/abstract.c | 18 +++++++++--------- Objects/memoryobject.c | 7 ++----- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index d5a5d3c129..612271da2e 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -413,7 +413,7 @@ PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) void -_add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape) +_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape) { int k; @@ -429,7 +429,7 @@ _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape) } void -_add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape) +_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) { int k; @@ -453,7 +453,7 @@ int PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort) { int k; - void (*addone)(int, Py_ssize_t *, Py_ssize_t *); + void (*addone)(int, Py_ssize_t *, const Py_ssize_t *); Py_ssize_t *indices, elements; char *dest, *ptr; @@ -480,10 +480,10 @@ PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort) } if (fort == 'F') { - addone = _add_one_to_index_F; + addone = _Py_add_one_to_index_F; } else { - addone = _add_one_to_index_C; + addone = _Py_add_one_to_index_C; } dest = buf; /* XXX : This is not going to be the fastest code in the world @@ -504,7 +504,7 @@ int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) { int k; - void (*addone)(int, Py_ssize_t *, Py_ssize_t *); + void (*addone)(int, Py_ssize_t *, const Py_ssize_t *); Py_ssize_t *indices, elements; char *src, *ptr; @@ -531,10 +531,10 @@ PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) } if (fort == 'F') { - addone = _add_one_to_index_F; + addone = _Py_add_one_to_index_F; } else { - addone = _add_one_to_index_C; + addone = _Py_add_one_to_index_C; } src = buf; /* XXX : This is not going to be the fastest code in the world @@ -611,7 +611,7 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) elements *= view_src.shape[k]; } while (elements--) { - _add_one_to_index_C(view_src.ndim, indices, view_src.shape); + _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); diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 70ae6ccea0..9a62dd84bd 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -172,9 +172,6 @@ _strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape, return; } -void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape); -void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape); - static int _indirect_copy_nd(char *dest, Py_buffer *view, char fort) { @@ -203,10 +200,10 @@ _indirect_copy_nd(char *dest, Py_buffer *view, char fort) elements *= view->shape[k]; } if (fort == 'F') { - func = _add_one_to_index_F; + func = _Py_add_one_to_index_F; } else { - func = _add_one_to_index_C; + func = _Py_add_one_to_index_C; } while (elements--) { func(view->ndim, indices, view->shape); -- cgit v1.2.1 From a3e883f7819ba7b5e87d176f1fd4ccab09416b3a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 1 Sep 2010 15:10:12 +0000 Subject: Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API properly. Patch by Stefan Behnel. --- Objects/unicodeobject.c | 53 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4c4b43c0e1..753b46515c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1234,8 +1234,7 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj, const char *encoding, const char *errors) { - const char *s = NULL; - Py_ssize_t len; + Py_buffer buffer; PyObject *v; if (obj == NULL) { @@ -1243,44 +1242,44 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj, return NULL; } + /* Decoding bytes objects is the most common case and should be fast */ + if (PyBytes_Check(obj)) { + if (PyBytes_GET_SIZE(obj) == 0) { + Py_INCREF(unicode_empty); + v = (PyObject *) unicode_empty; + } + else { + v = PyUnicode_Decode( + PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), + encoding, errors); + } + return v; + } + if (PyUnicode_Check(obj)) { PyErr_SetString(PyExc_TypeError, "decoding str is not supported"); return NULL; } - /* Coerce object */ - if (PyBytes_Check(obj)) { - s = PyBytes_AS_STRING(obj); - len = PyBytes_GET_SIZE(obj); - } - else if (PyByteArray_Check(obj)) { - s = PyByteArray_AS_STRING(obj); - len = PyByteArray_GET_SIZE(obj); - } - 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 str: need bytes, bytearray or char buffer, " - "%.80s found", - Py_TYPE(obj)->tp_name); - goto onError; + /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */ + if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) { + PyErr_Format(PyExc_TypeError, + "coercing to str: need bytes, bytearray " + "or buffer-like object, %.80s found", + Py_TYPE(obj)->tp_name); + return NULL; } - /* Convert to Unicode */ - if (len == 0) { + if (buffer.len == 0) { Py_INCREF(unicode_empty); - v = (PyObject *)unicode_empty; + v = (PyObject *) unicode_empty; } else - v = PyUnicode_Decode(s, len, encoding, errors); + v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors); + PyBuffer_Release(&buffer); return v; - - onError: - return NULL; } /* Convert encoding to lower case and replace '_' with '-' in order to -- cgit v1.2.1 From dbbf653e5e7d790fce009f7c31b6ebbdc408b938 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 1 Sep 2010 18:54:56 +0000 Subject: Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding() are now removed, since their effect was inexistent in 3.x (the default encoding is hardcoded to utf-8 and cannot be changed). --- Objects/unicodeobject.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 753b46515c..60124929cb 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1784,17 +1784,6 @@ const char *PyUnicode_GetDefaultEncoding(void) return unicode_default_encoding; } -int PyUnicode_SetDefaultEncoding(const char *encoding) -{ - if (strcmp(encoding, unicode_default_encoding) != 0) { - PyErr_Format(PyExc_ValueError, - "Can only set default encoding to %s", - unicode_default_encoding); - return -1; - } - return 0; -} - /* create or adjust a UnicodeDecodeError */ static void make_decode_exception(PyObject **exceptionObject, -- cgit v1.2.1 From eda3e00d6d7cb3f5c11948611586bd5a3ccf94da Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Sep 2010 19:39:01 +0000 Subject: Remove unicode_default_encoding constant Inline its value in PyUnicode_GetDefaultEncoding(). The comment is now outdated (we will not change its value anymore). --- Objects/unicodeobject.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 60124929cb..9cabd117ed 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -114,15 +114,6 @@ static PyUnicodeObject *unicode_empty; shared as well. */ static PyUnicodeObject *unicode_latin1[256]; -/* Default encoding to use and assume when NULL is passed as encoding - parameter; it is fixed to "utf-8". Always use the - PyUnicode_GetDefaultEncoding() API to access this global. - - Don't forget to alter Py_FileSystemDefaultEncoding if you change the - hard coded default! -*/ -static const char unicode_default_encoding[] = "utf-8"; - /* Fast detection of the most frequent whitespace characters */ const unsigned char _Py_ascii_whitespace[] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -1781,7 +1772,7 @@ Py_ssize_t PyUnicode_GetSize(PyObject *unicode) const char *PyUnicode_GetDefaultEncoding(void) { - return unicode_default_encoding; + return "utf-8"; } /* create or adjust a UnicodeDecodeError */ -- cgit v1.2.1 From f2d610050aff0cf73b103dc730f24a871decd346 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 1 Sep 2010 21:14:16 +0000 Subject: Issue #9737: Fix a crash when trying to delete a slice or an item from a memoryview object. --- Objects/memoryobject.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 9a62dd84bd..3f203920c7 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -631,6 +631,11 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) "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; -- cgit v1.2.1 From 2086d8e6fe0bc65a56c6a33e232d0866cabfd9bb Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 1 Sep 2010 21:14:46 +0000 Subject: Fix a compilation warning --- Objects/memoryobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 3f203920c7..802a92293d 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -179,7 +179,7 @@ _indirect_copy_nd(char *dest, Py_buffer *view, char fort) int k; Py_ssize_t elements; char *ptr; - void (*func)(int, Py_ssize_t *, Py_ssize_t *); + void (*func)(int, Py_ssize_t *, const Py_ssize_t *); if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) { PyErr_NoMemory(); -- cgit v1.2.1 From 74676426cc57705194c012f3a1836ed8a6073cd7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Sep 2010 23:43:50 +0000 Subject: Create Py_UNICODE_strcat() function --- Objects/unicodeobject.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9cabd117ed..95823ad827 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9951,6 +9951,15 @@ Py_UNICODE_strncpy(Py_UNICODE *s1, const Py_UNICODE *s2, size_t n) return s1; } +Py_UNICODE* +Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2) +{ + Py_UNICODE *u1 = s1; + u1 += Py_UNICODE_strlen(u1); + Py_UNICODE_strcpy(u1, s2); + return s1; +} + int Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2) { -- cgit v1.2.1 From 60fbac95c44b5aa6c5d8b847e8e45359bf021cc9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Sep 2010 23:43:53 +0000 Subject: Create PyUnicode_strdup() function --- Objects/unicodeobject.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 95823ad827..80e2e63fce 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10014,6 +10014,28 @@ Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) return NULL; } +Py_UNICODE* +PyUnicode_strdup(PyObject *object) +{ + PyUnicodeObject *unicode = (PyUnicodeObject *)object; + Py_UNICODE *copy; + Py_ssize_t size; + + /* Ensure we won't overflow the size. */ + if (PyUnicode_GET_SIZE(unicode) > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + PyErr_NoMemory(); + return NULL; + } + size = PyUnicode_GET_SIZE(unicode) + 1; /* copy the nul character */ + size *= sizeof(Py_UNICODE); + copy = PyMem_Malloc(size); + if (copy == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(copy, PyUnicode_AS_UNICODE(unicode), size); + return copy; +} #ifdef __cplusplus } -- cgit v1.2.1 From c104a3ec84b40f4f4c2b28c0932f68845bfcff6f Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Thu, 2 Sep 2010 15:06:03 +0000 Subject: Removed an extraneous semicolon --- Objects/setobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index e275bcc9d4..a99beec36c 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1439,7 +1439,7 @@ set_isdisjoint(PySetObject *so, PyObject *other) while ((key = PyIter_Next(it)) != NULL) { int rv; setentry entry; - long hash = PyObject_Hash(key);; + long hash = PyObject_Hash(key); if (hash == -1) { Py_DECREF(key); -- cgit v1.2.1 From 917c0a6fbd2611d906956098ca478b1b2b5f1342 Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Thu, 2 Sep 2010 15:06:06 +0000 Subject: Issue #9212: Added the missing isdisjoint method to the dict_keys and dict_items views. The method is required by the collections.Set ABC, which the views register as supporting. --- Objects/dictobject.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 745e2dc9fe..241790ceba 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2807,7 +2807,63 @@ static PyNumberMethods dictviews_as_number = { (binaryfunc)dictviews_or, /*nb_or*/ }; +static PyObject* +dictviews_isdisjoint(PyObject *self, PyObject *other) +{ + PyObject *it; + PyObject *item = NULL; + + if (self == other) { + if (dictview_len((dictviewobject *)self) == 0) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + /* Iterate over the shorter object (only if other is a set, + * because PySequence_Contains may be expensive otherwise): */ + if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) { + Py_ssize_t len_self = dictview_len((dictviewobject *)self); + Py_ssize_t len_other = PyObject_Size(other); + if (len_other == -1) + return NULL; + + if ((len_other > len_self)) { + PyObject *tmp = other; + other = self; + self = tmp; + } + } + + it = PyObject_GetIter(other); + if (it == NULL) + return NULL; + + while ((item = PyIter_Next(it)) != NULL) { + int contains = PySequence_Contains(self, item); + Py_DECREF(item); + if (contains == -1) { + Py_DECREF(it); + return NULL; + } + + if (contains) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) + return NULL; /* PyIter_Next raised an exception. */ + Py_RETURN_TRUE; +} + +PyDoc_STRVAR(isdisjoint_doc, +"Return True if the view and the given iterable have a null intersection."); + static PyMethodDef dictkeys_methods[] = { + {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O, + isdisjoint_doc}, {NULL, NULL} /* sentinel */ }; @@ -2892,6 +2948,8 @@ static PySequenceMethods dictitems_as_sequence = { }; static PyMethodDef dictitems_methods[] = { + {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O, + isdisjoint_doc}, {NULL, NULL} /* sentinel */ }; -- cgit v1.2.1 From 7df774e34462269c4c2368f3b1d8b8b33cff2232 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 3 Sep 2010 10:00:50 +0000 Subject: Issue 8420: Fix obscure set crashers. --- Objects/setobject.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index a99beec36c..6cd90b1f16 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -364,12 +364,13 @@ static int set_add_entry(register PySetObject *so, setentry *entry) { register Py_ssize_t n_used; + PyObject *key = entry->key; assert(so->fill <= so->mask); /* at least one empty slot */ n_used = so->used; - Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, (long) entry->hash) == -1) { - Py_DECREF(entry->key); + Py_INCREF(key); + if (set_insert_key(so, key, (long) entry->hash) == -1) { + Py_DECREF(key); return -1; } if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2)) @@ -637,6 +638,7 @@ static int set_merge(PySetObject *so, PyObject *otherset) { PySetObject *other; + PyObject *key; register Py_ssize_t i; register setentry *entry; @@ -657,11 +659,12 @@ set_merge(PySetObject *so, PyObject *otherset) } for (i = 0; i <= other->mask; i++) { entry = &other->table[i]; - if (entry->key != NULL && - entry->key != dummy) { - Py_INCREF(entry->key); - if (set_insert_key(so, entry->key, (long) entry->hash) == -1) { - Py_DECREF(entry->key); + key = entry->key; + if (key != NULL && + key != dummy) { + Py_INCREF(key); + if (set_insert_key(so, key, (long) entry->hash) == -1) { + Py_DECREF(key); return -1; } } @@ -1642,15 +1645,22 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) 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) + if (rv == -1) { + Py_DECREF(key); return NULL; + } if (rv == DISCARD_NOTFOUND) { - if (set_add_entry(so, &an_entry) == -1) + if (set_add_entry(so, &an_entry) == -1) { + Py_DECREF(key); return NULL; + } } + Py_DECREF(key); } Py_RETURN_NONE; } -- cgit v1.2.1 From 65e6d56ee7085ba1600b7deac8f424d095124beb Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 3 Sep 2010 10:52:55 +0000 Subject: Reindent. --- Objects/setobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 6cd90b1f16..7eac1aa9c1 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1650,7 +1650,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) an_entry.key = key; rv = set_discard_entry(so, &an_entry); - if (rv == -1) { + if (rv == -1) { Py_DECREF(key); return NULL; } @@ -1660,7 +1660,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) return NULL; } } - Py_DECREF(key); + Py_DECREF(key); } Py_RETURN_NONE; } -- cgit v1.2.1 From 30af7c33ab12e752b644fa95fb304f8e445978e8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 3 Sep 2010 16:18:00 +0000 Subject: Rename PyUnicode_strdup() to PyUnicode_AsUnicodeCopy() --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 80e2e63fce..9cdf90d159 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10015,7 +10015,7 @@ Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) } Py_UNICODE* -PyUnicode_strdup(PyObject *object) +PyUnicode_AsUnicodeCopy(PyObject *object) { PyUnicodeObject *unicode = (PyUnicodeObject *)object; Py_UNICODE *copy; -- cgit v1.2.1 From adfa4c26a8cdf51677b954bfcb267e8269166ddb Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Wed, 8 Sep 2010 12:50:29 +0000 Subject: Revert the doc change done in r83880. str.replace with negative count value is not a feature. --- Objects/bytesobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 77f193cf45..fc644f24c0 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2131,8 +2131,7 @@ PyDoc_STRVAR(replace__doc__, \n\ Return a copy of B with all occurrences of subsection\n\ old replaced by new. If the optional argument count is\n\ -positive, only the first count occurrences are replaced. A\n\ -negative value of count replaces all occurrences"); +given, only first count occurances are replaced."); static PyObject * bytes_replace(PyBytesObject *self, PyObject *args) -- cgit v1.2.1 From 90886a7b13c3c1d3db908402397904a0d8a9a592 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 9 Sep 2010 12:59:39 +0000 Subject: Issue #9757: memoryview objects get a release() method to release the underlying buffer (previously this was only done when deallocating the memoryview), and gain support for the context management protocol. --- Objects/memoryobject.c | 85 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 802a92293d..36626b2cdd 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -3,6 +3,23 @@ #include "Python.h" +#define IS_RELEASED(memobj) \ + (((PyMemoryViewObject *) memobj)->view.buf == NULL) + +#define CHECK_RELEASED(memobj) \ + if (IS_RELEASED(memobj)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return NULL; \ + } + +#define CHECK_RELEASED_INT(memobj) \ + if (IS_RELEASED(memobj)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return -1; \ + } + static Py_ssize_t get_shape0(Py_buffer *buf) { @@ -34,6 +51,7 @@ static int memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) { int res = 0; + CHECK_RELEASED_INT(self); /* XXX for whatever reason fixing the flags seems necessary */ if (self->view.readonly) flags &= ~PyBUF_WRITABLE; @@ -330,12 +348,14 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) static PyObject * memory_format_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return PyUnicode_FromString(self->view.format); } static PyObject * memory_itemsize_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return PyLong_FromSsize_t(self->view.itemsize); } @@ -366,30 +386,35 @@ _IntTupleFromSsizet(int len, Py_ssize_t *vals) static PyObject * memory_shape_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.shape); } static PyObject * memory_strides_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.strides); } static PyObject * memory_suboffsets_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); } static PyObject * memory_readonly_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return PyBool_FromLong(self->view.readonly); } static PyObject * memory_ndim_get(PyMemoryViewObject *self) { + CHECK_RELEASED(self); return PyLong_FromLong(self->view.ndim); } @@ -408,6 +433,7 @@ static PyGetSetDef memory_getsetlist[] ={ static PyObject * memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs) { + CHECK_RELEASED(mem); return PyObject_CallFunctionObjArgs( (PyObject *) &PyBytes_Type, mem, NULL); } @@ -423,6 +449,7 @@ memory_tolist(PyMemoryViewObject *mem, PyObject *noargs) PyObject *res, *item; char *buf; + CHECK_RELEASED(mem); if (strcmp(view->format, "B") || view->itemsize != 1) { PyErr_SetString(PyExc_NotImplementedError, "tolist() only supports byte views"); @@ -449,17 +476,9 @@ memory_tolist(PyMemoryViewObject *mem, PyObject *noargs) 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) +do_release(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 @@ -484,19 +503,57 @@ memory_dealloc(PyMemoryViewObject *self) } Py_CLEAR(self->base); } + self->view.obj = NULL; + self->view.buf = NULL; +} + +static PyObject * +memory_enter(PyObject *self, PyObject *args) +{ + CHECK_RELEASED(self); + Py_INCREF(self); + return self; +} + +static PyObject * +memory_exit(PyObject *self, PyObject *args) +{ + do_release((PyMemoryViewObject *) self); + Py_RETURN_NONE; +} + +static PyMethodDef memory_methods[] = { + {"release", memory_exit, METH_NOARGS}, + {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL}, + {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL}, + {"__enter__", memory_enter, METH_NOARGS}, + {"__exit__", memory_exit, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +static void +memory_dealloc(PyMemoryViewObject *self) +{ + _PyObject_GC_UNTRACK(self); + do_release(self); PyObject_GC_Del(self); } static PyObject * memory_repr(PyMemoryViewObject *self) { - return PyUnicode_FromFormat("", self); + if (IS_RELEASED(self)) + return PyUnicode_FromFormat("", self); + else + return PyUnicode_FromFormat("", self); } /* Sequence methods */ static Py_ssize_t memory_length(PyMemoryViewObject *self) { + CHECK_RELEASED_INT(self); return get_shape0(&self->view); } @@ -508,6 +565,7 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t result) { Py_buffer *view = &(self->view); + CHECK_RELEASED(self); if (view->ndim == 0) { PyErr_SetString(PyExc_IndexError, "invalid indexing of 0-dim memory"); @@ -557,6 +615,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) Py_buffer *view; view = &(self->view); + CHECK_RELEASED(self); if (view->ndim == 0) { if (key == Py_Ellipsis || (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) { @@ -626,6 +685,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) Py_buffer *view = &(self->view); char *srcbuf, *destbuf; + CHECK_RELEASED_INT(self); if (view->readonly) { PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory"); @@ -718,6 +778,11 @@ memory_richcompare(PyObject *v, PyObject *w, int op) ww.obj = NULL; if (op != Py_EQ && op != Py_NE) goto _notimpl; + if ((PyMemoryView_Check(v) && IS_RELEASED(v)) || + (PyMemoryView_Check(w) && IS_RELEASED(w))) { + equal = (v == w); + goto _end; + } if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) { PyErr_Clear(); goto _notimpl; -- cgit v1.2.1 From cf4091139cd70f1bf67321574114c2f0ed60862a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 11 Sep 2010 00:54:47 +0000 Subject: Issue #9738: PyUnicode_FromFormat() and PyErr_Format() raise an error on a non-ASCII byte in the format string. Document also the encoding. --- Objects/unicodeobject.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9cdf90d159..c010b1b246 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1102,7 +1102,15 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) appendstring(p); goto end; } - } else + } + else if (128 <= (unsigned char)*f) { + PyErr_Format(PyExc_ValueError, + "PyUnicode_FromFormatV() expects an ASCII-encoded format " + "string, got a non-ascii byte: 0x%02x", + (unsigned char)*f); + goto fail; + } + else *s++ = *f; } -- cgit v1.2.1 From aefd18d8c7ef226f88fae735a155f400895460b7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Sep 2010 16:02:03 +0000 Subject: check for NULL tp_as_mapping in PySequence_(Get/Set/Del)Slice #9834 --- Objects/abstract.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 612271da2e..4eb33d3bc5 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1612,7 +1612,7 @@ PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) if (!s) return null_error(); mp = s->ob_type->tp_as_mapping; - if (mp->mp_subscript) { + if (mp && mp->mp_subscript) { PyObject *res; PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) @@ -1690,7 +1690,7 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) } mp = s->ob_type->tp_as_mapping; - if (mp->mp_ass_subscript) { + if (mp && mp->mp_ass_subscript) { int res; PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) @@ -1715,7 +1715,7 @@ PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) } mp = s->ob_type->tp_as_mapping; - if (mp->mp_ass_subscript) { + if (mp && mp->mp_ass_subscript) { int res; PyObject *slice = _PySlice_FromIndices(i1, i2); if (!slice) -- cgit v1.2.1 From 1debd90f6a895bf77d1e0876b019c859c231dfb3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 11 Sep 2010 16:39:57 +0000 Subject: fix formatting --- Objects/object.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 3bde659c39..ff3363f432 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -479,13 +479,13 @@ PyObject_Bytes(PyObject *v) result = PyObject_CallFunctionObjArgs(func, NULL); Py_DECREF(func); if (result == NULL) - return NULL; + return NULL; if (!PyBytes_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__bytes__ returned non-bytes (type %.200s)", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; } return result; } -- cgit v1.2.1 From f96ec53b90967720a6de4387d8985481599af668 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Sep 2010 03:40:54 +0000 Subject: detect non-ascii characters much earlier (plugs ref leak) --- Objects/unicodeobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c010b1b246..3b0a66ae74 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -764,6 +764,13 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) if (*f == 's') ++callcount; } + else if (128 <= (unsigned char)*f) { + PyErr_Format(PyExc_ValueError, + "PyUnicode_FromFormatV() expects an ASCII-encoded format " + "string, got a non-ascii byte: 0x%02x", + (unsigned char)*f); + return NULL; + } } /* step 2: allocate memory for the results of * PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() calls */ @@ -1103,13 +1110,6 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) goto end; } } - else if (128 <= (unsigned char)*f) { - PyErr_Format(PyExc_ValueError, - "PyUnicode_FromFormatV() expects an ASCII-encoded format " - "string, got a non-ascii byte: 0x%02x", - (unsigned char)*f); - goto fail; - } else *s++ = *f; } -- cgit v1.2.1 From 8630ada725289da82ce737a3e12db207d1ed28bd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 12 Sep 2010 07:51:18 +0000 Subject: Issue #9738, #9836: Fix refleak introduced by r84704 --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 3b0a66ae74..92df1ce900 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -767,9 +767,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) else if (128 <= (unsigned char)*f) { PyErr_Format(PyExc_ValueError, "PyUnicode_FromFormatV() expects an ASCII-encoded format " - "string, got a non-ascii byte: 0x%02x", + "string, got a non-ASCII byte: 0x%02x", (unsigned char)*f); - return NULL; + goto fail; } } /* step 2: allocate memory for the results of -- cgit v1.2.1 From 2f15b108c8c6a496d9e6e22f6f108647686a7df2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Sep 2010 16:40:53 +0000 Subject: use return NULL; it's just as correct --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 92df1ce900..489c98cd83 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -769,7 +769,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) "PyUnicode_FromFormatV() expects an ASCII-encoded format " "string, got a non-ASCII byte: 0x%02x", (unsigned char)*f); - goto fail; + return NULL; } } /* step 2: allocate memory for the results of -- cgit v1.2.1 From a5a69257afc890a81bea93671da162bc0a34d38d Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Sun, 12 Sep 2010 22:42:57 +0000 Subject: #9210: remove --with-wctype-functions configure option. The internal unicode database is now always used. (after 5 years: see http://mail.python.org/pipermail/python-dev/2004-December/050193.html ) --- Objects/unicodectype.c | 33 --------------------------------- Objects/unicodetype_db.h | 4 ---- 2 files changed, 37 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index f6e3250824..a41ceb8240 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -163,8 +163,6 @@ int _PyUnicode_IsPrintable(Py_UCS4 ch) return (ctype->flags & PRINTABLE_MASK) != 0; } -#ifndef WANT_WCTYPE_FUNCTIONS - /* Returns 1 for Unicode characters having the category 'Ll', 0 otherwise. */ @@ -223,34 +221,3 @@ int _PyUnicode_IsAlpha(Py_UCS4 ch) return (ctype->flags & ALPHA_MASK) != 0; } -#else - -/* Export the interfaces using the wchar_t type for portability - reasons: */ - -int _PyUnicode_IsLowercase(Py_UCS4 ch) -{ - return iswlower(ch); -} - -int _PyUnicode_IsUppercase(Py_UCS4 ch) -{ - return iswupper(ch); -} - -Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch) -{ - return towlower(ch); -} - -Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch) -{ - return towupper(ch); -} - -int _PyUnicode_IsAlpha(Py_UCS4 ch) -{ - return iswalpha(ch); -} - -#endif diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 637f6298cd..ef18b95cf3 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -3247,9 +3247,6 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) */ int _PyUnicode_IsWhitespace(register const Py_UCS4 ch) { -#ifdef WANT_WCTYPE_FUNCTIONS - return iswspace(ch); -#else switch (ch) { case 0x0009: case 0x000A: @@ -3284,7 +3281,6 @@ int _PyUnicode_IsWhitespace(register const Py_UCS4 ch) return 1; } return 0; -#endif } /* Returns 1 for Unicode characters having the line break -- cgit v1.2.1 From a347f170b1c6131776293b277c03123d1ee1272b Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Mon, 13 Sep 2010 20:48:43 +0000 Subject: Issue 7994: Make object.__format__() raise a PendingDeprecationWarning if the format string is not empty. Manually merge r79596 and r84772 from 2.x. Also, apparently test_format() from test_builtin never made it into 3.x. I've added it as well. It tests the basic format() infrastructure. --- Objects/typeobject.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8b74e1e076..897374d487 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3315,9 +3315,26 @@ object_format(PyObject *self, PyObject *args) return NULL; self_as_str = PyObject_Str(self); - if (self_as_str != NULL) - result = PyObject_Format(self_as_str, format_spec); - + if (self_as_str != NULL) { + /* Issue 7994: If we're converting to a string, we + should reject format specifications */ + if (PyUnicode_GET_SIZE(format_spec) > 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; -- cgit v1.2.1 From 8ee11f7e599b2c5b4de39047bf11bde2246e968f Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Mon, 13 Sep 2010 21:16:29 +0000 Subject: Issue #9213: Add index and count methods to range objects, needed to meet the API of the collections.Sequence ABC. --- Objects/rangeobject.c | 181 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 132 insertions(+), 49 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index e36469cd01..965038635c 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -273,58 +273,133 @@ range_reduce(rangeobject *r, PyObject *args) r->start, r->stop, r->step); } +/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ +static int +range_contains_long(rangeobject *r, PyObject *ob) +{ + int cmp1, cmp2, cmp3; + PyObject *tmp1 = NULL; + PyObject *tmp2 = NULL; + PyObject *zero = NULL; + int result = -1; + + zero = PyLong_FromLong(0); + if (zero == NULL) /* MemoryError in int(0) */ + goto end; + + /* Check if the value can possibly be in the range. */ + + cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT); + if (cmp1 == -1) + goto end; + if (cmp1 == 1) { /* positive steps: start <= ob < stop */ + cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE); + cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT); + } + else { /* negative steps: stop < ob <= start */ + cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE); + cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT); + } + + if (cmp2 == -1 || cmp3 == -1) /* TypeError */ + goto end; + if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */ + result = 0; + goto end; + } + + /* Check that the stride does not invalidate ob's membership. */ + tmp1 = PyNumber_Subtract(ob, r->start); + if (tmp1 == NULL) + goto end; + tmp2 = PyNumber_Remainder(tmp1, r->step); + if (tmp2 == NULL) + goto end; + /* result = (int(ob) - start % step) == 0 */ + result = PyObject_RichCompareBool(tmp2, zero, Py_EQ); + end: + Py_XDECREF(tmp1); + Py_XDECREF(tmp2); + Py_XDECREF(zero); + return result; +} + static int range_contains(rangeobject *r, PyObject *ob) { + if (PyLong_CheckExact(ob) || PyBool_Check(ob)) + return range_contains_long(r, ob); + + return (int)_PySequence_IterSearch((PyObject*)r, ob, + PY_ITERSEARCH_CONTAINS); +} + +static PyObject * +range_count(rangeobject *r, PyObject *ob) +{ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { - int cmp1, cmp2, cmp3; - PyObject *tmp1 = NULL; - PyObject *tmp2 = NULL; - PyObject *zero = NULL; - int result = -1; - - zero = PyLong_FromLong(0); - if (zero == NULL) /* MemoryError in int(0) */ - goto end; - - /* Check if the value can possibly be in the range. */ - - cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT); - if (cmp1 == -1) - goto end; - if (cmp1 == 1) { /* positive steps: start <= ob < stop */ - cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE); - cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT); - } - else { /* negative steps: stop < ob <= start */ - cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE); - cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT); - } + if (range_contains_long(r, ob)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } else { + Py_ssize_t count; + count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT); + if (count == -1) + return NULL; + return PyLong_FromSsize_t(count); + } +} - if (cmp2 == -1 || cmp3 == -1) /* TypeError */ - goto end; - if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */ - result = 0; - goto end; - } +static PyObject * +range_index(rangeobject *r, PyObject *ob) +{ + PyObject *idx, *tmp; + int contains; + PyObject *format_tuple, *err_string; + static PyObject *err_format = NULL; + + if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) { + Py_ssize_t index; + index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX); + if (index == -1) + return NULL; + return PyLong_FromSsize_t(index); + } + + contains = range_contains_long(r, ob); + if (contains == -1) + return NULL; + + if (!contains) + goto value_error; + + tmp = PyNumber_Subtract(ob, r->start); + if (tmp == NULL) + return NULL; + + /* idx = (ob - r.start) // r.step */ + idx = PyNumber_FloorDivide(tmp, r->step); + Py_DECREF(tmp); + return idx; + +value_error: - /* Check that the stride does not invalidate ob's membership. */ - tmp1 = PyNumber_Subtract(ob, r->start); - if (tmp1 == NULL) - goto end; - tmp2 = PyNumber_Remainder(tmp1, r->step); - if (tmp2 == NULL) - goto end; - /* result = (int(ob) - start % step) == 0 */ - result = PyObject_RichCompareBool(tmp2, zero, Py_EQ); - end: - Py_XDECREF(tmp1); - Py_XDECREF(tmp2); - Py_XDECREF(zero); - return result; + /* object is not in the range */ + if (err_format == NULL) { + err_format = PyUnicode_FromString("%r is not in range"); + if (err_format == NULL) + return NULL; } - /* Fall back to iterative search. */ - return (int)_PySequence_IterSearch((PyObject*)r, ob, - PY_ITERSEARCH_CONTAINS); + format_tuple = PyTuple_Pack(1, ob); + if (format_tuple == NULL) + return NULL; + err_string = PyUnicode_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 PySequenceMethods range_as_sequence = { @@ -344,10 +419,18 @@ static PyObject * range_reverse(PyObject *seq); PyDoc_STRVAR(reverse_doc, "Returns a reverse iterator."); +PyDoc_STRVAR(count_doc, +"rangeobject.count(value) -> integer -- return number of occurrences of value"); + +PyDoc_STRVAR(index_doc, +"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n" +"Raises ValueError if the value is not present."); + static PyMethodDef range_methods[] = { - {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, - reverse_doc}, - {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS}, + {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc}, + {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS}, + {"count", (PyCFunction)range_count, METH_O, count_doc}, + {"index", (PyCFunction)range_index, METH_O, index_doc}, {NULL, NULL} /* sentinel */ }; -- cgit v1.2.1 From 7ffacfc6660dfe007614ed86257fe657518d120f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Thu, 23 Sep 2010 20:11:19 +0000 Subject: Issue #9930: Remove an unnecessary type check in wrap_binaryfunc_r; this was causing reversed method calls like float.__radd__(3.0, 1) to return NotImplemented instead of the expected numeric value. --- Objects/typeobject.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 897374d487..7bdcb1233c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4063,10 +4063,6 @@ wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) if (!check_num_args(args, 1)) return NULL; other = PyTuple_GET_ITEM(args, 0); - if (!PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } return (*func)(other, self); } -- cgit v1.2.1 From b876f4df5fbcd9130f38dbcd0d2c9c0496f7cae9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 Sep 2010 10:25:54 +0000 Subject: Issue #9979: Create function PyUnicode_AsWideCharString(). --- Objects/unicodeobject.c | 62 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 14 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 489c98cd83..527e219896 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1153,9 +1153,26 @@ PyUnicode_FromFormat(const char *format, ...) return ret; } -Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, - wchar_t *w, - Py_ssize_t size) +static void +unicode_aswidechar(PyUnicodeObject *unicode, + wchar_t *w, + Py_ssize_t size) +{ +#if Py_UNICODE_SIZE == SIZEOF_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 +} + +Py_ssize_t +PyUnicode_AsWideChar(PyUnicodeObject *unicode, + wchar_t *w, + Py_ssize_t size) { if (unicode == NULL) { PyErr_BadInternalCall(); @@ -1166,17 +1183,7 @@ Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, if (size > PyUnicode_GET_SIZE(unicode)) size = PyUnicode_GET_SIZE(unicode) + 1; -#if Py_UNICODE_SIZE == SIZEOF_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 + unicode_aswidechar(unicode, w, size); if (size > PyUnicode_GET_SIZE(unicode)) return PyUnicode_GET_SIZE(unicode); @@ -1184,6 +1191,33 @@ Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, return size; } +wchar_t* +PyUnicode_AsWideCharString(PyUnicodeObject *unicode, + Py_ssize_t *size) +{ + wchar_t* buffer; + Py_ssize_t buflen; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + if ((PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) < PyUnicode_GET_SIZE(unicode)) { + PyErr_NoMemory(); + return NULL; + } + + buflen = PyUnicode_GET_SIZE(unicode) + 1; /* copy L'\0' */ + buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + unicode_aswidechar(unicode, buffer, buflen); + return buffer; +} + #endif PyObject *PyUnicode_FromOrdinal(int ordinal) -- cgit v1.2.1 From 82deba1f06f5dedc64fab78febbed063b4b8f85d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 Sep 2010 16:35:47 +0000 Subject: Issue #9630: Redecode filenames when setting the filesystem encoding Redecode the filenames of: - all modules: __file__ and __path__ attributes - all code objects: co_filename attribute - sys.path - sys.meta_path - sys.executable - sys.path_importer_cache (keys) Keep weak references to all code objects until initfsencoding() is called, to be able to redecode co_filename attribute of all code objects. --- Objects/codeobject.c | 17 +++++++++++++++++ Objects/object.c | 4 ++++ Objects/unicodeobject.c | 8 +++++++- 3 files changed, 28 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index da5c09ac8d..470bf56150 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -5,6 +5,8 @@ #define NAME_CHARS \ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" +PyObject *_Py_code_object_list = NULL; + /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ static int @@ -109,8 +111,23 @@ PyCode_New(int argcount, int kwonlyargcount, co->co_lnotab = lnotab; co->co_zombieframe = NULL; co->co_weakreflist = NULL; + + if (_Py_code_object_list != NULL) { + int err; + PyObject *ref = PyWeakref_NewRef((PyObject*)co, NULL); + if (ref == NULL) + goto error; + err = PyList_Append(_Py_code_object_list, ref); + Py_DECREF(ref); + if (err) + goto error; + } } return co; + +error: + Py_DECREF(co); + return NULL; } PyCodeObject * diff --git a/Objects/object.c b/Objects/object.c index ff3363f432..e322e53103 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1604,6 +1604,10 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyCode_Type) < 0) Py_FatalError("Can't initialize code type"); + _Py_code_object_list = PyList_New(0); + if (_Py_code_object_list == NULL) + Py_FatalError("Can't initialize code type"); + if (PyType_Ready(&PyFrame_Type) < 0) Py_FatalError("Can't initialize frame type"); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 527e219896..8ceb3f32b8 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1510,10 +1510,14 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); - } else + } + else { + /* if you change the default encoding, update also + PyUnicode_DecodeFSDefaultAndSize() and redecode_filenames() */ return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), "surrogateescape"); + } } PyObject *PyUnicode_AsEncodedString(PyObject *unicode, @@ -1680,6 +1684,8 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) "surrogateescape"); } else { + /* if you change the default encoding, update also + PyUnicode_EncodeFSDefault() and redecode_filenames() */ return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); } } -- cgit v1.2.1 From 59c973ee51292f87ca845038baa000ebec988c34 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 Sep 2010 17:55:12 +0000 Subject: Fix PyUnicode_AsWideCharString(): set *size if size is not NULL --- Objects/unicodeobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8ceb3f32b8..29404c3c26 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1215,6 +1215,8 @@ PyUnicode_AsWideCharString(PyUnicodeObject *unicode, return NULL; } unicode_aswidechar(unicode, buffer, buflen); + if (size) + *size = buflen; return buffer; } -- cgit v1.2.1 From 0bbdbddb4bf787e83ad85d59b053b2f135c15386 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 2 Oct 2010 00:03:31 +0000 Subject: type.__abstractmethods__ should raise an AttributeError #10006 --- Objects/typeobject.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7bdcb1233c..c8c198df3f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -320,8 +320,11 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context) static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { - PyObject *mod = PyDict_GetItemString(type->tp_dict, - "__abstractmethods__"); + PyObject *mod = NULL; + /* type its self has an __abstractmethods__ descriptor (this). Don't + return that. */ + if (type != &PyType_Type) + mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); return NULL; -- cgit v1.2.1 From 9622410e0da4b3341afb500e40968d60d734e13a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 2 Oct 2010 11:03:13 +0000 Subject: Issue #8870: PyUnicode_AsWideCharString() doesn't count the trailing nul character And write unit tests for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 29404c3c26..1c083b2f6f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1216,7 +1216,7 @@ PyUnicode_AsWideCharString(PyUnicodeObject *unicode, } unicode_aswidechar(unicode, buffer, buflen); if (size) - *size = buflen; + *size = buflen - 1; return buffer; } -- cgit v1.2.1 From 51eca407608609c879654c3078b8208076e116de Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 2 Oct 2010 11:11:27 +0000 Subject: Issue #8670: PyUnicode_AsWideChar() and PyUnicode_AsWideCharString() replace UTF-16 surrogate pairs by single non-BMP characters for 16 bits Py_UNICODE and 32 bits wchar_t (eg. Linux in narrow build). --- Objects/unicodeobject.c | 127 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 22 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 1c083b2f6f..3fd22a3097 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1153,19 +1153,112 @@ PyUnicode_FromFormat(const char *format, ...) return ret; } -static void +/* Helper function for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(): + convert a Unicode object to a wide character string. + + - If w is NULL: return the number of wide characters (including the nul + character) required to convert the unicode object. Ignore size argument. + + - Otherwise: return the number of wide characters (excluding the nul + character) written into w. Write at most size wide characters (including + the nul character). */ +static Py_ssize_t unicode_aswidechar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) { #if Py_UNICODE_SIZE == SIZEOF_WCHAR_T - memcpy(w, unicode->str, size * sizeof(wchar_t)); -#else - register Py_UNICODE *u; + Py_ssize_t res; + if (w != NULL) { + res = PyUnicode_GET_SIZE(unicode); + if (size > res) + size = res + 1; + else + res = size; + memcpy(w, unicode->str, size * sizeof(wchar_t)); + return res; + } + else + return PyUnicode_GET_SIZE(unicode) + 1; +#elif Py_UNICODE_SIZE == 2 && SIZEOF_WCHAR_T == 4 + register const Py_UNICODE *u; + const Py_UNICODE *uend; + const wchar_t *worig, *wend; + Py_ssize_t nchar; + + u = PyUnicode_AS_UNICODE(unicode); + uend = u + PyUnicode_GET_SIZE(unicode); + if (w != NULL) { + worig = w; + wend = w + size; + while (u != uend && w != wend) { + if (0xD800 <= u[0] && u[0] <= 0xDBFF + && 0xDC00 <= u[1] && u[1] <= 0xDFFF) + { + *w = (((u[0] & 0x3FF) << 10) | (u[1] & 0x3FF)) + 0x10000; + u += 2; + } + else { + *w = *u; + u++; + } + w++; + } + if (w != wend) + *w = L'\0'; + return w - worig; + } + else { + nchar = 1; /* nul character at the end */ + while (u != uend) { + if (0xD800 <= u[0] && u[0] <= 0xDBFF + && 0xDC00 <= u[1] && u[1] <= 0xDFFF) + u += 2; + else + u++; + nchar++; + } + } + return nchar; +#elif Py_UNICODE_SIZE == 4 && SIZEOF_WCHAR_T == 2 + register Py_UNICODE *u, *uend, ordinal; register Py_ssize_t i; + wchar_t *worig, *wend; + Py_ssize_t nchar; + u = PyUnicode_AS_UNICODE(unicode); - for (i = size; i > 0; i--) - *w++ = *u++; + uend = u + PyUnicode_GET_SIZE(u); + if (w != NULL) { + worig = w; + wend = w + size; + while (u != uend && w != wend) { + ordinal = *u; + if (ordinal > 0xffff) { + ordinal -= 0x10000; + *w++ = 0xD800 | (ordinal >> 10); + *w++ = 0xDC00 | (ordinal & 0x3FF); + } + else + *w++ = ordinal; + u++; + } + if (w != wend) + *w = 0; + return w - worig; + } + else { + nchar = 1; /* nul character */ + while (u != uend) { + if (*u > 0xffff) + nchar += 2; + else + nchar++; + u++; + } + return nchar; + } +#else +# error "unsupported wchar_t and Py_UNICODE sizes, see issue #8670" #endif } @@ -1178,17 +1271,7 @@ PyUnicode_AsWideChar(PyUnicodeObject *unicode, 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; - - unicode_aswidechar(unicode, w, size); - - if (size > PyUnicode_GET_SIZE(unicode)) - return PyUnicode_GET_SIZE(unicode); - else - return size; + return unicode_aswidechar(unicode, w, size); } wchar_t* @@ -1203,20 +1286,20 @@ PyUnicode_AsWideCharString(PyUnicodeObject *unicode, return NULL; } - if ((PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) < PyUnicode_GET_SIZE(unicode)) { + buflen = unicode_aswidechar(unicode, NULL, 0); + if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { PyErr_NoMemory(); return NULL; } - buflen = PyUnicode_GET_SIZE(unicode) + 1; /* copy L'\0' */ buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; } - unicode_aswidechar(unicode, buffer, buflen); - if (size) - *size = buflen - 1; + buflen = unicode_aswidechar(unicode, buffer, buflen); + if (size != NULL) + *size = buflen; return buffer; } -- cgit v1.2.1 From 841bf47d30329a74731c8b1ab8717f30b453525f Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 3 Oct 2010 02:13:39 +0000 Subject: typo --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c8c198df3f..faa03df603 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -321,8 +321,8 @@ static PyObject * type_abstractmethods(PyTypeObject *type, void *context) { PyObject *mod = NULL; - /* type its self has an __abstractmethods__ descriptor (this). Don't - return that. */ + /* type itself has an __abstractmethods__ descriptor (this). Don't return + that. */ if (type != &PyType_Type) mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { -- cgit v1.2.1 From 90fd877049b4be1465843f00506d923e39bd4224 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 7 Oct 2010 01:02:42 +0000 Subject: PyUnicode_AsWideCharString() takes a PyObject*, not a PyUnicodeObject* All unicode functions uses PyObject* except PyUnicode_AsWideChar(). Fix the prototype for the new function PyUnicode_AsWideCharString(). --- Objects/unicodeobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 3fd22a3097..37a9070e2f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1275,7 +1275,7 @@ PyUnicode_AsWideChar(PyUnicodeObject *unicode, } wchar_t* -PyUnicode_AsWideCharString(PyUnicodeObject *unicode, +PyUnicode_AsWideCharString(PyObject *unicode, Py_ssize_t *size) { wchar_t* buffer; @@ -1286,7 +1286,7 @@ PyUnicode_AsWideCharString(PyUnicodeObject *unicode, return NULL; } - buflen = unicode_aswidechar(unicode, NULL, 0); + buflen = unicode_aswidechar((PyUnicodeObject *)unicode, NULL, 0); if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { PyErr_NoMemory(); return NULL; @@ -1297,7 +1297,7 @@ PyUnicode_AsWideCharString(PyUnicodeObject *unicode, PyErr_NoMemory(); return NULL; } - buflen = unicode_aswidechar(unicode, buffer, buflen); + buflen = unicode_aswidechar((PyUnicodeObject *)unicode, buffer, buflen); if (size != NULL) *size = buflen; return buffer; -- cgit v1.2.1 From 6eb8e698e7c5280aea41630c67f05638461378b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Mon, 11 Oct 2010 22:42:28 +0000 Subject: Upgrade to Unicode 6.0.0. makeunicodedata.py: download all data files from unicode.org, switch to extracting Unihan data from zip file. Read linebreakprops and derivednormalizationprops even for old versions, even though they are not used in delta records. test:unicode.py: U+11000 is now assigned, use U+14000 instead. --- Objects/unicodetype_db.h | 1506 +++++++++++++++++++++++++--------------------- 1 file changed, 804 insertions(+), 702 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index ef18b95cf3..88a7912227 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -1,4 +1,4 @@ -/* this file was generated by Tools/unicode/makeunicodedata.py 2.6 */ +/* this file was generated by Tools/unicode/makeunicodedata.py 3.2 */ /* a list of unique character type descriptors */ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { @@ -77,6 +77,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {65334, 0, 65334, 0, 0, 1801}, {65333, 0, 65333, 0, 0, 1801}, {65329, 0, 65329, 0, 0, 1801}, + {42893, 613, 42893, 0, 0, 3849}, {65327, 0, 65327, 0, 0, 1801}, {65325, 0, 65325, 0, 0, 1801}, {10743, 0, 10743, 0, 0, 1801}, @@ -182,6 +183,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {58272, 0, 58272, 0, 0, 1801}, {0, 0, 0, 0, 0, 5889}, {42877, 7545, 42877, 0, 0, 3969}, + {42893, 613, 42893, 0, 0, 3969}, {0, 40, 0, 0, 0, 1921}, {65496, 0, 65496, 0, 0, 1801}, }; @@ -193,43 +195,44 @@ static unsigned char index1[] = { 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, + 64, 64, 64, 68, 69, 64, 64, 64, 64, 64, 64, 70, 17, 71, 72, 73, 74, 75, + 76, 64, 77, 78, 79, 80, 81, 82, 83, 64, 64, 84, 85, 34, 34, 34, 34, 34, + 34, 86, 34, 34, 34, 34, 34, 87, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 88, 89, 90, 91, 34, 34, 34, 92, 34, 34, + 34, 93, 94, 34, 34, 34, 34, 34, 95, 34, 34, 34, 96, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 97, 98, 99, 34, 34, 34, 34, 34, 34, 100, 101, 34, 34, + 34, 34, 34, 34, 34, 34, 102, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 104, 34, 34, 34, 34, + 100, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 106, 107, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 108, 109, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 110, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 111, 34, 34, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 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, - 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 34, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 17, 143, 144, 145, 146, 147, 17, 17, 17, 17, 17, 17, 148, 17, 149, 17, - 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 17, 154, 17, 17, 17, + 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 154, 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, 34, 34, 34, 34, 34, 34, 155, 17, 156, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 156, 17, 157, 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, 157, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 159, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -237,28 +240,27 @@ static unsigned char index1[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 160, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 161, 162, 163, 164, 17, 165, 17, 166, 167, 168, 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, 17, 17, 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, 158, 159, 160, 161, 17, 162, 17, 163, 164, 165, 166, 167, 168, - 169, 170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 171, 172, 173, - 174, 175, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 176, 177, 178, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 179, 34, 180, 181, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 174, 175, 176, + 177, 178, 17, 179, 180, 181, 182, 183, 184, 185, 186, 65, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 187, 188, 189, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 86, 190, 34, 191, + 192, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 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, 193, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 194, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 195, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 196, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, @@ -266,16 +268,16 @@ static unsigned char index1[] = { 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 186, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 197, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 187, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 34, 34, 198, 34, 199, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 182, 34, 34, 188, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 34, 193, 34, 34, 199, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -589,7 +591,7 @@ static unsigned char index1[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 189, 17, 190, 191, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 200, 17, 201, 202, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -617,7 +619,7 @@ static unsigned char index1[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -654,7 +656,7 @@ static unsigned char index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 192, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 203, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -690,7 +692,7 @@ static unsigned char index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 192, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 203, }; static unsigned char index2[] = { @@ -726,9 +728,9 @@ static unsigned char index2[] = { 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26, 27, 60, 61, 62, 62, 26, 27, 63, 64, 65, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 66, 67, 68, 69, 70, 19, 71, 71, 19, 72, 19, 73, 19, 19, 19, 19, - 71, 19, 19, 74, 19, 19, 19, 19, 75, 76, 19, 77, 19, 19, 19, 76, 19, 78, - 79, 19, 19, 80, 19, 19, 19, 19, 19, 19, 19, 81, 19, 19, 82, 19, 19, 82, - 19, 19, 19, 19, 82, 83, 84, 84, 85, 19, 19, 19, 19, 19, 86, 19, 50, 19, + 71, 19, 19, 74, 19, 75, 19, 19, 76, 77, 19, 78, 19, 19, 19, 77, 19, 79, + 80, 19, 19, 81, 19, 19, 19, 19, 19, 19, 19, 82, 19, 19, 83, 19, 19, 83, + 19, 19, 19, 19, 83, 84, 85, 85, 86, 19, 19, 19, 19, 19, 87, 19, 50, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, @@ -738,189 +740,189 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 87, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 88, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 88, - 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 89, 17, 90, 90, 90, 0, 91, 0, 92, 92, + 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 89, + 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 90, 17, 91, 91, 91, 0, 92, 0, 93, 93, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 93, 94, 94, 94, 19, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 95, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 96, 97, 97, 98, 99, 100, 101, 101, 101, 102, 103, - 104, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 105, 106, 107, 19, 108, 109, 5, 26, 27, 110, - 26, 27, 19, 58, 58, 58, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 95, 95, 95, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 96, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 97, 98, 98, 99, 100, 101, 102, 102, 102, 103, + 104, 105, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 106, 107, 108, 19, 109, 110, 5, 26, 27, + 111, 26, 27, 19, 58, 58, 58, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 5, - 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 112, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 115, 115, 115, 115, 115, 115, + 5, 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 114, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, + 115, 115, 115, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 0, 0, 5, 5, 0, + 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, - 5, 5, 5, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 5, 5, 5, 5, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 17, 17, - 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 50, 50, 17, 17, 5, 17, - 17, 17, 17, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 5, 5, - 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 50, 17, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 17, + 17, 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 50, 50, 17, 17, 5, + 17, 17, 17, 17, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, + 5, 5, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, + 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, - 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17, 17, - 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, + 17, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17, + 17, 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, - 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 50, 17, 17, 17, 17, 17, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, - 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, - 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 50, 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, - 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, - 0, 50, 50, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, - 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, - 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, + 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 5, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 0, 0, + 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 50, + 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, + 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 0, 0, 17, 0, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, + 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, + 17, 17, 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, - 50, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, - 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 17, 50, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, - 0, 50, 50, 50, 50, 0, 0, 0, 50, 50, 0, 50, 0, 50, 50, 0, 0, 0, 50, 50, 0, - 0, 0, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 0, 0, 0, 17, 17, 17, 17, 17, 0, 0, 0, 17, 17, 17, 0, 17, 17, 17, - 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, - 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, - 0, 0, 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 5, 0, 0, 17, 17, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, - 17, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, - 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 50, 17, 17, 0, - 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, - 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, - 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 0, 0, 0, 0, 17, 17, - 17, 17, 17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, + 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 5, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 50, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 0, 50, 50, 50, + 50, 0, 0, 0, 50, 50, 0, 50, 0, 50, 50, 0, 0, 0, 50, 50, 0, 0, 0, 50, 50, + 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 0, 0, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 50, 0, + 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, + 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, 0, 0, 0, 0, 0, 0, + 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 5, 0, 0, 17, 17, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, + 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, + 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24, + 24, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 116, - 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, - 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, - 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, - 50, 116, 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, - 0, 50, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 5, 17, 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 50, 50, 50, 50, 0, 0, 0, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, + 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 117, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, + 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 0, + 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, 50, 117, + 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, + 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 17, + 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 17, 17, 17, - 17, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, - 17, 17, 17, 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, - 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 5, 17, 17, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 50, 50, + 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -930,33 +932,33 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 118, 119, 120, 121, 122, 123, 124, 125, 126, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 119, 120, 121, 122, 123, 124, 125, 126, 127, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -967,53 +969,54 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 5, 5, 5, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, - 50, 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 5, 5, 5, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, + 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 7, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 13, 14, 15, 119, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1037,87 +1040,88 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, - 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 5, 5, 5, 5, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, 50, 50, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 5, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 50, 128, 19, 19, 19, 129, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 129, + 19, 19, 19, 130, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 130, - 19, 19, 131, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 132, 132, 132, 132, 132, 132, - 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, - 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, 132, 132, 132, 132, - 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, - 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, - 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133, 133, 133, 0, 0, - 19, 132, 19, 132, 19, 132, 19, 132, 0, 133, 0, 133, 0, 133, 0, 133, 132, - 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, - 133, 134, 134, 135, 135, 135, 135, 136, 136, 137, 137, 138, 138, 139, - 139, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, - 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, - 140, 140, 140, 140, 140, 140, 132, 132, 132, 132, 132, 132, 132, 132, - 140, 140, 140, 140, 140, 140, 140, 140, 132, 132, 19, 141, 19, 0, 19, 19, - 133, 133, 142, 142, 143, 5, 144, 5, 5, 5, 19, 141, 19, 0, 19, 19, 145, - 145, 145, 145, 143, 5, 5, 5, 132, 132, 19, 19, 0, 0, 19, 19, 133, 133, - 146, 146, 0, 5, 5, 5, 132, 132, 19, 19, 19, 107, 19, 19, 133, 133, 147, - 147, 110, 5, 5, 5, 0, 0, 19, 141, 19, 0, 19, 19, 148, 148, 149, 149, 143, - 5, 5, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, - 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 150, 50, 0, 0, - 151, 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 50, 150, 23, 20, 21, 151, - 152, 153, 154, 155, 156, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 131, 19, 19, 132, + 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 133, 133, 133, 133, 133, 133, 133, 133, 134, + 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 0, 0, + 134, 134, 134, 134, 134, 134, 0, 0, 133, 133, 133, 133, 133, 133, 133, + 133, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, + 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, + 133, 133, 133, 0, 0, 134, 134, 134, 134, 134, 134, 0, 0, 19, 133, 19, + 133, 19, 133, 19, 133, 0, 134, 0, 134, 0, 134, 0, 134, 133, 133, 133, + 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 135, + 135, 136, 136, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 0, 0, + 133, 133, 133, 133, 133, 133, 133, 133, 141, 141, 141, 141, 141, 141, + 141, 141, 133, 133, 133, 133, 133, 133, 133, 133, 141, 141, 141, 141, + 141, 141, 141, 141, 133, 133, 133, 133, 133, 133, 133, 133, 141, 141, + 141, 141, 141, 141, 141, 141, 133, 133, 19, 142, 19, 0, 19, 19, 134, 134, + 143, 143, 144, 5, 145, 5, 5, 5, 19, 142, 19, 0, 19, 19, 146, 146, 146, + 146, 144, 5, 5, 5, 133, 133, 19, 19, 0, 0, 19, 19, 134, 134, 147, 147, 0, + 5, 5, 5, 133, 133, 19, 19, 19, 108, 19, 19, 134, 134, 148, 148, 111, 5, + 5, 5, 0, 0, 19, 142, 19, 0, 19, 19, 149, 149, 150, 150, 144, 5, 5, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 151, 50, 0, 0, 152, 153, + 154, 155, 156, 157, 5, 5, 5, 5, 5, 50, 151, 23, 20, 21, 152, 153, 154, + 155, 156, 157, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 101, 5, 5, 5, 5, - 101, 5, 5, 19, 101, 101, 101, 19, 19, 101, 101, 101, 19, 5, 101, 5, 5, - 157, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 101, 5, 158, 5, 101, 5, - 159, 160, 101, 101, 157, 19, 101, 101, 161, 101, 19, 50, 50, 50, 50, 19, - 5, 5, 19, 19, 101, 101, 5, 5, 5, 5, 5, 101, 19, 19, 19, 19, 5, 5, 5, 5, - 162, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 127, 127, 127, 26, 27, 127, 127, 127, 127, 24, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 102, 5, 5, 5, 5, 102, + 5, 5, 19, 102, 102, 102, 19, 19, 102, 102, 102, 19, 5, 102, 5, 5, 158, + 102, 102, 102, 102, 102, 5, 5, 5, 5, 5, 5, 102, 5, 159, 5, 102, 5, 160, + 161, 102, 102, 158, 19, 102, 102, 162, 102, 19, 50, 50, 50, 50, 19, 5, 5, + 19, 19, 102, 102, 5, 5, 5, 5, 5, 102, 19, 19, 19, 19, 5, 5, 5, 5, 163, 5, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 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, 128, 128, 128, 26, 27, 128, 128, 128, 128, 24, 0, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1131,135 +1135,129 @@ static unsigned char index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 151, 152, 153, 154, 155, - 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, - 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, - 21, 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 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, 166, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 150, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, - 150, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 152, 153, 154, 155, + 156, 157, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 152, + 153, 154, 155, 156, 157, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, - 20, 21, 151, 152, 153, 154, 155, 156, 24, 23, 20, 21, 151, 152, 153, 154, - 155, 156, 24, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 151, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, + 151, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, + 20, 21, 152, 153, 154, 155, 156, 157, 24, 23, 20, 21, 152, 153, 154, 155, + 156, 157, 24, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 26, 27, 167, 168, - 169, 170, 171, 26, 27, 26, 27, 26, 27, 172, 173, 174, 175, 19, 26, 27, - 19, 26, 27, 19, 19, 19, 19, 19, 19, 50, 176, 176, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 26, 27, 26, 27, 19, 5, 5, 5, 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 24, 5, 5, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 0, 26, 27, 168, 169, 170, 171, 172, 26, 27, 26, + 27, 26, 27, 173, 174, 175, 176, 19, 26, 27, 19, 26, 27, 19, 19, 19, 19, + 19, 19, 50, 177, 177, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 5, 5, 5, + 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 24, + 5, 5, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, + 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, - 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, + 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 88, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 89, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 50, 50, 127, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 17, 17, 17, 17, 17, 17, 5, 50, - 50, 50, 50, 50, 5, 5, 127, 127, 127, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 2, 5, 5, 5, 5, 50, 50, 128, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, 128, 128, + 128, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, - 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 5, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 5, 5, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, 24, 24, 24, 24, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1268,7 +1266,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1277,56 +1275,56 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 178, 50, 50, 178, 50, 50, 50, 178, 50, 178, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 179, 50, 50, 179, + 50, 50, 50, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, + 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 179, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, + 50, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 178, 178, 178, 50, 50, 50, 50, - 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 179, + 179, 179, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 178, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 179, 179, 179, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1334,7 +1332,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1342,23 +1340,23 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, + 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 178, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 178, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 179, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 179, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1371,22 +1369,22 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1394,7 +1392,7 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1402,488 +1400,555 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 178, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 178, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, + 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, - 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 50, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 17, 5, 50, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, + 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 19, 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, - 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 19, 19, 19, 19, 19, 19, - 19, 19, 26, 27, 26, 27, 179, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, - 5, 5, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, 26, 27, 180, 26, 27, + 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 181, 19, 0, 26, 27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27, + 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, - 50, 50, 17, 50, 50, 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 50, 50, 50, 50, 50, 50, 50, 17, 50, 50, + 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 5, 5, + 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, - 50, 5, 5, 5, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, + 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 0, 0, 0, + 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, + 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50, + 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, + 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, - 17, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, - 50, 50, 17, 17, 50, 50, 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, + 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, 50, 50, 17, 17, 50, 50, + 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, - 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 50, 50, 50, 50, 50, 50, 50, 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, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 178, 50, - 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, + 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 178, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 50, 17, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, + 0, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, + 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, - 88, 88, 88, 88, 88, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 89, 89, 89, 89, 89, 89, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 88, 88, 5, 5, - 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, - 0, 0, 88, 50, 88, 50, 88, 0, 88, 50, 88, 50, 88, 50, 88, 50, 88, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 89, 89, 5, 5, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, + 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 5, 5, 5, 5, 0, 0, 0, 0, 89, 50, 89, 50, 89, 0, 89, 50, 89, 50, 89, 50, + 89, 50, 89, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 1, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 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, 5, 5, 5, - 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 50, 50, 50, 0, 0, 1, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 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, 5, 5, 5, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 117, 117, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 116, 116, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, - 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 5, 5, 0, 0, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, + 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 5, 5, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, + 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 24, 24, 24, 24, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 127, 50, 50, 50, 50, 50, 50, 50, 50, 127, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 128, 50, 50, 50, 50, 50, 50, 50, 50, 128, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, - 50, 50, 50, 50, 50, 5, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 5, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, - 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, 50, 0, 0, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 0, 0, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 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, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, - 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, - 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 151, 24, 24, 24, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17, + 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50, 50, 50, 50, + 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 152, 24, 24, 24, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, - 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, - 151, 152, 153, 154, 155, 156, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, - 1, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 1, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 157, 157, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 157, 157, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 158, 158, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 158, 158, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 5, 5, 5, 17, 17, 17, - 17, 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, - 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, + 5, 5, 5, 17, 17, 17, 17, 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, + 17, 17, 17, 17, 5, 5, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, + 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 17, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 0, 101, - 101, 0, 0, 101, 0, 0, 101, 101, 0, 0, 101, 101, 101, 101, 0, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 0, 19, 0, 19, 19, 19, 19, - 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 101, 101, 0, 101, 101, 101, 101, 0, 0, 101, 101, 101, 101, 101, 101, - 101, 101, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, 19, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 101, 101, 0, 101, 101, 101, 101, 0, 101, 101, 101, 101, 101, - 0, 101, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, 0, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 102, 0, 102, 102, 0, 0, 102, 0, 0, 102, 102, 0, 0, + 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, + 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 0, 102, 102, 102, 102, + 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, + 102, 102, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 0, 102, 102, 102, + 102, 0, 102, 102, 102, 102, 102, 0, 102, 0, 0, 0, 102, 102, 102, 102, + 102, 102, 102, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 19, 19, 19, + 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, - 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, 19, 19, + 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, - 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 5, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 101, 19, 0, 0, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 19, 19, 19, 19, 102, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 23, 20, 21, 152, 153, + 154, 155, 156, 157, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 150, 23, 20, 21, 151, 152, 153, 154, 155, 156, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, - 5, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 0, 5, 0, 5, 0, 5, 0, 5, + 5, 5, 0, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 5, 0, 0, 5, 5, 5, 5, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, - 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, + 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1894,31 +1959,31 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, @@ -1930,32 +1995,33 @@ static unsigned char index2[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 178, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -1968,13 +2034,13 @@ static unsigned char index2[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, + 17, 17, 17, 17, 17, 17, 17, 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, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -2033,6 +2099,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xFF10: case 0x1018A: case 0x104A0: + case 0x11066: case 0x1D7CE: case 0x1D7D8: case 0x1D7E2: @@ -2118,6 +2185,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B58: case 0x10B78: case 0x10E60: + case 0x11052: + case 0x11067: case 0x12415: case 0x1241E: case 0x1242C: @@ -2136,9 +2205,11 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2152: return (double) 1.0/10.0; case 0x09F4: + case 0x0B75: case 0xA833: return (double) 1.0/16.0; case 0x00BD: + case 0x0B73: case 0x0D74: case 0x0F2A: case 0x2CFD: @@ -2155,6 +2226,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) return (double) 1.0/3.0; case 0x00BC: case 0x09F7: + case 0x0B72: case 0x0D73: case 0xA830: case 0x10140: @@ -2170,6 +2242,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2150: return (double) 1.0/7.0; case 0x09F5: + case 0x0B76: case 0x215B: case 0xA834: case 0x1245F: @@ -2213,6 +2286,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5C: case 0x10B7C: case 0x10E69: + case 0x1105B: case 0x1D369: return (double) 10.0; case 0x0BF1: @@ -2234,6 +2308,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5E: case 0x10B7E: case 0x10E72: + case 0x11064: return (double) 100.0; case 0x0BF2: case 0x0D72: @@ -2251,6 +2326,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10A47: case 0x10B5F: case 0x10B7F: + case 0x11065: return (double) 1000.0; case 0x137C: case 0x2182: @@ -2405,6 +2481,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B59: case 0x10B79: case 0x10E61: + case 0x11053: + case 0x11068: case 0x12400: case 0x12416: case 0x1241F: @@ -2447,6 +2525,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5D: case 0x10B7D: case 0x10E6A: + case 0x1105C: case 0x1D36A: return (double) 20.0; case 0x1011A: @@ -2545,6 +2624,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5A: case 0x10B7A: case 0x10E62: + case 0x11054: + case 0x11069: case 0x12401: case 0x12408: case 0x12417: @@ -2572,12 +2653,14 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x23B1B: return (double) 3.0; case 0x09F6: + case 0x0B77: case 0xA835: return (double) 3.0/16.0; case 0x0F2B: return (double) 3.0/2.0; case 0x00BE: case 0x09F8: + case 0x0B74: case 0x0D75: case 0xA832: case 0x10178: @@ -2593,6 +2676,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10112: case 0x10165: case 0x10E6B: + case 0x1105D: case 0x1D36B: case 0x20983: return (double) 30.0; @@ -2684,6 +2768,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5B: case 0x10B7B: case 0x10E63: + case 0x11055: + case 0x1106A: case 0x12402: case 0x12409: case 0x1240F: @@ -2717,6 +2803,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x534C: case 0x10113: case 0x10E6C: + case 0x1105E: case 0x1D36C: case 0x2098C: case 0x2099C: @@ -2811,6 +2898,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10321: case 0x104A5: case 0x10E64: + case 0x11056: + case 0x1106B: case 0x12403: case 0x1240A: case 0x12410: @@ -2855,6 +2944,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10323: case 0x10A7E: case 0x10E6D: + case 0x1105F: case 0x1D36D: return (double) 50.0; case 0x216E: @@ -2942,6 +3032,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1010C: case 0x104A6: case 0x10E65: + case 0x11057: + case 0x1106C: case 0x12404: case 0x1240B: case 0x12411: @@ -2961,6 +3053,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1377: case 0x10115: case 0x10E6E: + case 0x11060: case 0x1D36E: return (double) 60.0; case 0x1011E: @@ -3029,6 +3122,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1010D: case 0x104A7: case 0x10E66: + case 0x11058: + case 0x1106D: case 0x12405: case 0x1240C: case 0x12412: @@ -3053,6 +3148,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1378: case 0x10116: case 0x10E6F: + case 0x11061: case 0x1D36F: return (double) 70.0; case 0x1011F: @@ -3119,6 +3215,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1010E: case 0x104A8: case 0x10E67: + case 0x11059: + case 0x1106E: case 0x12406: case 0x1240D: case 0x12413: @@ -3137,6 +3235,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1379: case 0x10117: case 0x10E70: + case 0x11062: case 0x1D370: return (double) 80.0; case 0x10120: @@ -3204,6 +3303,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1010F: case 0x104A9: case 0x10E68: + case 0x1105A: + case 0x1106F: case 0x12407: case 0x1240E: case 0x12414: @@ -3228,6 +3329,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10118: case 0x10341: case 0x10E71: + case 0x11063: case 0x1D371: return (double) 90.0; case 0x10121: -- cgit v1.2.1 From 2cd87e47e217f9fef48001a49350ffe8de0e9fa0 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 12 Oct 2010 22:57:59 +0000 Subject: prefer clearing global objects to obscure module.__dict__ bugs #10068 --- Objects/moduleobject.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 3a95261028..1e3349d0a3 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -335,10 +335,7 @@ module_dealloc(PyModuleObject *m) if (m->md_def && m->md_def->m_free) m->md_def->m_free(m); if (m->md_dict != NULL) { - /* If we are the only ones holding a reference, we can clear - the dictionary. */ - if (Py_REFCNT(m->md_dict) == 1) - _PyModule_Clear((PyObject *)m); + _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } if (m->md_state != NULL) -- cgit v1.2.1 From e9e78942c7288f040183b6b390ba531d6ce6ec34 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 14 Oct 2010 07:04:07 +0000 Subject: #9418: first step of moving private string methods to _string module. --- Objects/stringlib/string_format.h | 4 ++-- Objects/unicodeobject.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index bc70e97be4..126c870113 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -1180,7 +1180,7 @@ static PyTypeObject PyFormatterIter_Type = { describing the parsed elements. It's a wrapper around stringlib/string_format.h's MarkupIterator */ static PyObject * -formatter_parser(STRINGLIB_OBJECT *self) +formatter_parser(PyObject *ignored, STRINGLIB_OBJECT *self) { formatteriterobject *it; @@ -1315,7 +1315,7 @@ static PyTypeObject PyFieldNameIter_Type = { field_name_split. The iterator it returns is a FieldNameIterator */ static PyObject * -formatter_field_name_split(STRINGLIB_OBJECT *self) +formatter_field_name_split(PyObject *ignored, STRINGLIB_OBJECT *self) { SubString first; Py_ssize_t first_idx; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 37a9070e2f..a18eeef57a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8968,8 +8968,6 @@ static PyMethodDef unicode_methods[] = { {"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}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__}, @@ -10170,6 +10168,36 @@ PyUnicode_AsUnicodeCopy(PyObject *object) return copy; } +/* A _string module, to export formatter_parser and formatter_field_name_split + to the string.Formatter class implemented in Python. */ + +static PyMethodDef _string_methods[] = { + {"formatter_field_name_split", (PyCFunction) formatter_field_name_split, + METH_O, PyDoc_STR("split the argument as a field name")}, + {"formatter_parser", (PyCFunction) formatter_parser, + METH_O, PyDoc_STR("parse the argument as a format string")}, + {NULL, NULL} +}; + +static struct PyModuleDef _string_module = { + PyModuleDef_HEAD_INIT, + "_string", + PyDoc_STR("string helper module"), + 0, + _string_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__string(void) +{ + return PyModule_Create(&_string_module); +} + + #ifdef __cplusplus } #endif -- cgit v1.2.1 From a47a00d4de1dba7e27eb086e9843d0e1592663ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 15 Oct 2010 12:04:23 +0000 Subject: Use locale encoding if Py_FileSystemDefaultEncoding is not set * PyUnicode_EncodeFSDefault(), PyUnicode_DecodeFSDefaultAndSize() and PyUnicode_DecodeFSDefault() use the locale encoding instead of UTF-8 if Py_FileSystemDefaultEncoding is NULL * redecode_filenames() functions and _Py_code_object_list (issue #9630) are no more needed: remove them --- Objects/codeobject.c | 13 ------------- Objects/object.c | 4 ---- Objects/unicodeobject.c | 40 ++++++++++++++++++++++++++++++++-------- 3 files changed, 32 insertions(+), 25 deletions(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 470bf56150..e24fc8d42b 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -5,8 +5,6 @@ #define NAME_CHARS \ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" -PyObject *_Py_code_object_list = NULL; - /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ static int @@ -111,17 +109,6 @@ PyCode_New(int argcount, int kwonlyargcount, co->co_lnotab = lnotab; co->co_zombieframe = NULL; co->co_weakreflist = NULL; - - if (_Py_code_object_list != NULL) { - int err; - PyObject *ref = PyWeakref_NewRef((PyObject*)co, NULL); - if (ref == NULL) - goto error; - err = PyList_Append(_Py_code_object_list, ref); - Py_DECREF(ref); - if (err) - goto error; - } } return co; diff --git a/Objects/object.c b/Objects/object.c index e322e53103..ff3363f432 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1604,10 +1604,6 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyCode_Type) < 0) Py_FatalError("Can't initialize code type"); - _Py_code_object_list = PyList_New(0); - if (_Py_code_object_list == NULL) - Py_FatalError("Can't initialize code type"); - if (PyType_Ready(&PyFrame_Type) < 0) Py_FatalError("Can't initialize frame type"); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a18eeef57a..98427e3c2c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1597,11 +1597,22 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) "surrogateescape"); } else { - /* if you change the default encoding, update also - PyUnicode_DecodeFSDefaultAndSize() and redecode_filenames() */ - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - "surrogateescape"); + /* locale encoding with surrogateescape */ + wchar_t *wchar; + char *bytes; + PyObject *bytes_obj; + + wchar = PyUnicode_AsWideCharString(unicode, NULL); + if (wchar == NULL) + return NULL; + bytes = _Py_wchar2char(wchar); + PyMem_Free(wchar); + if (bytes == NULL) + return NULL; + + bytes_obj = PyBytes_FromString(bytes); + PyMem_Free(bytes); + return bytes_obj; } } @@ -1769,9 +1780,22 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) "surrogateescape"); } else { - /* if you change the default encoding, update also - PyUnicode_EncodeFSDefault() and redecode_filenames() */ - return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); + /* locale encoding with surrogateescape */ + wchar_t *wchar; + PyObject *unicode; + + if (s[size] != '\0' || size != strlen(s)) { + PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + return NULL; + } + + wchar = _Py_char2wchar(s); + if (wchar == NULL) + return NULL; + + unicode = PyUnicode_FromWideChar(wchar, -1); + PyMem_Free(wchar); + return unicode; } } -- cgit v1.2.1 From 98af9868006b482ece0777952c52fc084b110131 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 15 Oct 2010 16:23:54 +0000 Subject: Remove unused label. --- Objects/codeobject.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index e24fc8d42b..da5c09ac8d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -111,10 +111,6 @@ PyCode_New(int argcount, int kwonlyargcount, co->co_weakreflist = NULL; } return co; - -error: - Py_DECREF(co); - return NULL; } PyCodeObject * -- cgit v1.2.1 From bd3b71a7bb5fcf80de1339fe71c85918a44fb7e3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Oct 2010 23:16:16 +0000 Subject: Add an optional size argument to _Py_char2wchar() _Py_char2wchar() callers usually need the result size in characters. Since it's trivial to compute it in _Py_char2wchar() (O(1) whereas wcslen() is O(n)), add an option to get it. --- Objects/unicodeobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 98427e3c2c..9fe9c42796 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1783,17 +1783,18 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) /* locale encoding with surrogateescape */ wchar_t *wchar; PyObject *unicode; + size_t len; if (s[size] != '\0' || size != strlen(s)) { PyErr_SetString(PyExc_TypeError, "embedded NUL character"); return NULL; } - wchar = _Py_char2wchar(s); + wchar = _Py_char2wchar(s, &len); if (wchar == NULL) return NULL; - unicode = PyUnicode_FromWideChar(wchar, -1); + unicode = PyUnicode_FromWideChar(wchar, len); PyMem_Free(wchar); return unicode; } -- cgit v1.2.1 From 6c3703bb3f3e516ca8e6bb086c122bd937d66b6c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 17 Oct 2010 20:13:05 +0000 Subject: use helper hash unimplemented function --- Objects/sliceobject.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 55fda52987..b617891423 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -344,13 +344,6 @@ slice_richcompare(PyObject *v, PyObject *w, int op) return res; } -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 */ @@ -365,7 +358,7 @@ PyTypeObject PySlice_Type = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - (hashfunc)slice_hash, /* tp_hash */ + PyObject_HashNotImplemented, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ -- cgit v1.2.1 From 8c3324e313c1adb92a1e38bbcbaa494bf97b754d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 17 Oct 2010 20:54:53 +0000 Subject: make hashes always the size of pointers; introduce Py_hash_t #9778 --- Objects/bytesobject.c | 4 ++-- Objects/classobject.c | 4 ++-- Objects/codeobject.c | 4 ++-- Objects/complexobject.c | 4 ++-- Objects/descrobject.c | 4 ++-- Objects/dictobject.c | 49 ++++++++++++++++++++++++------------------------- Objects/floatobject.c | 2 +- Objects/longobject.c | 4 ++-- Objects/methodobject.c | 4 ++-- Objects/object.c | 14 +++++++------- Objects/setobject.c | 42 +++++++++++++++++++++--------------------- Objects/tupleobject.c | 4 ++-- Objects/typeobject.c | 25 ++++++++++++------------- Objects/unicodeobject.c | 4 ++-- Objects/weakrefobject.c | 2 +- 15 files changed, 84 insertions(+), 86 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fc644f24c0..2b965c37ae 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -868,12 +868,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) return result; } -static long +static Py_hash_t bytes_hash(PyBytesObject *a) { register Py_ssize_t len; register unsigned char *p; - register long x; + register Py_hash_t x; if (a->ob_shash != -1) return a->ob_shash; diff --git a/Objects/classobject.c b/Objects/classobject.c index afd4ec3dc6..6df930fdcf 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -263,10 +263,10 @@ method_repr(PyMethodObject *a) return result; } -static long +static Py_hash_t method_hash(PyMethodObject *a) { - long x, y; + Py_hash_t x, y; if (a->im_self == NULL) x = PyObject_Hash(Py_None); else diff --git a/Objects/codeobject.c b/Objects/codeobject.c index da5c09ac8d..54c23aec36 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -417,10 +417,10 @@ code_richcompare(PyObject *self, PyObject *other, int op) return res; } -static long +static Py_hash_t code_hash(PyCodeObject *co) { - long h, h0, h1, h2, h3, h4, h5, h6; + Py_hash_t 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); diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 674362f9eb..c4ced31cb9 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -394,7 +394,7 @@ complex_repr(PyComplexObject *v) return complex_format(v, 0, 'r'); } -static long +static Py_hash_t complex_hash(PyComplexObject *v) { unsigned long hashreal, hashimag, combined; @@ -413,7 +413,7 @@ complex_hash(PyComplexObject *v) combined = hashreal + _PyHASH_IMAG * hashimag; if (combined == (unsigned long)-1) combined = (unsigned long)-2; - return (long)combined; + return (Py_hash_t)combined; } /* This macro may return! */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 8a2ddfd8a8..11418d19e5 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -916,10 +916,10 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op) return v; } -static long +static Py_hash_t wrapper_hash(wrapperobject *wp) { - int x, y; + Py_hash_t x, y; x = _Py_HashPointer(wp->descr); if (x == -1) return -1; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 241790ceba..7fd586b3d9 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -318,7 +318,7 @@ the caller can (if it wishes) add the pair to the returned PyDictEntry*. */ static PyDictEntry * -lookdict(PyDictObject *mp, PyObject *key, register long hash) +lookdict(PyDictObject *mp, PyObject *key, register Py_hash_t hash) { register size_t i; register size_t perturb; @@ -407,7 +407,7 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash) * This is valuable because dicts with only unicode keys are very common. */ static PyDictEntry * -lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash) +lookdict_unicode(PyDictObject *mp, PyObject *key, register Py_hash_t hash) { register size_t i; register size_t perturb; @@ -527,7 +527,7 @@ 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) +insertdict(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; register PyDictEntry *ep; @@ -555,7 +555,7 @@ insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value) Py_DECREF(dummy); } ep->me_key = key; - ep->me_hash = (Py_ssize_t)hash; + ep->me_hash = hash; ep->me_value = value; mp->ma_used++; } @@ -571,7 +571,7 @@ 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, +insertdict_clean(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { register size_t i; @@ -590,7 +590,7 @@ insertdict_clean(register PyDictObject *mp, PyObject *key, long hash, assert(ep->me_value == NULL); mp->ma_fill++; ep->me_key = key; - ep->me_hash = (Py_ssize_t)hash; + ep->me_hash = hash; ep->me_value = value; mp->ma_used++; } @@ -667,8 +667,7 @@ dictresize(PyDictObject *mp, Py_ssize_t minused) 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); + insertdict_clean(mp, ep->me_key, ep->me_hash, ep->me_value); } else if (ep->me_key != NULL) { /* dummy entry */ --i; @@ -713,7 +712,7 @@ _PyDict_NewPresized(Py_ssize_t minused) PyObject * PyDict_GetItem(PyObject *op, PyObject *key) { - long hash; + Py_hash_t hash; PyDictObject *mp = (PyDictObject *)op; PyDictEntry *ep; PyThreadState *tstate; @@ -763,7 +762,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) PyObject * PyDict_GetItemWithError(PyObject *op, PyObject *key) { - long hash; + Py_hash_t hash; PyDictObject*mp = (PyDictObject *)op; PyDictEntry *ep; @@ -796,7 +795,7 @@ int PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value) { register PyDictObject *mp; - register long hash; + register Py_hash_t hash; register Py_ssize_t n_used; if (!PyDict_Check(op)) { @@ -842,7 +841,7 @@ int PyDict_DelItem(PyObject *op, PyObject *key) { register PyDictObject *mp; - register long hash; + register Py_hash_t hash; register PyDictEntry *ep; PyObject *old_value, *old_key; @@ -988,7 +987,7 @@ PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) /* 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) +_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, Py_hash_t *phash) { register Py_ssize_t i; register Py_ssize_t mask; @@ -1006,7 +1005,7 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, *ppos = i+1; if (i > mask) return 0; - *phash = (long)(ep[i].me_hash); + *phash = ep[i].me_hash; if (pkey) *pkey = ep[i].me_key; if (pvalue) @@ -1128,7 +1127,7 @@ static PyObject * dict_subscript(PyDictObject *mp, register PyObject *key) { PyObject *v; - long hash; + Py_hash_t hash; PyDictEntry *ep; assert(mp->ma_table != NULL); if (!PyUnicode_CheckExact(key) || @@ -1322,7 +1321,7 @@ dict_fromkeys(PyObject *cls, PyObject *args) PyObject *oldvalue; Py_ssize_t pos = 0; PyObject *key; - long hash; + Py_hash_t hash; if (dictresize(mp, Py_SIZE(seq))) return NULL; @@ -1340,7 +1339,7 @@ dict_fromkeys(PyObject *cls, PyObject *args) PyDictObject *mp = (PyDictObject *)d; Py_ssize_t pos = 0; PyObject *key; - long hash; + Py_hash_t hash; if (dictresize(mp, PySet_GET_SIZE(seq))) return NULL; @@ -1549,7 +1548,7 @@ PyDict_Merge(PyObject *a, PyObject *b, int override) Py_INCREF(entry->me_key); Py_INCREF(entry->me_value); if (insertdict(mp, entry->me_key, - (long)entry->me_hash, + entry->me_hash, entry->me_value) != 0) return -1; } @@ -1732,7 +1731,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) static PyObject * dict_contains(register PyDictObject *mp, PyObject *key) { - long hash; + Py_hash_t hash; PyDictEntry *ep; if (!PyUnicode_CheckExact(key) || @@ -1753,7 +1752,7 @@ dict_get(register PyDictObject *mp, PyObject *args) PyObject *key; PyObject *failobj = Py_None; PyObject *val = NULL; - long hash; + Py_hash_t hash; PyDictEntry *ep; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) @@ -1782,7 +1781,7 @@ dict_setdefault(register PyDictObject *mp, PyObject *args) PyObject *key; PyObject *failobj = Py_None; PyObject *val = NULL; - long hash; + Py_hash_t hash; PyDictEntry *ep; if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj)) @@ -1818,7 +1817,7 @@ dict_clear(register PyDictObject *mp) static PyObject * dict_pop(PyDictObject *mp, PyObject *args) { - long hash; + Py_hash_t hash; PyDictEntry *ep; PyObject *old_value, *old_key; PyObject *key, *deflt = NULL; @@ -1864,7 +1863,7 @@ dict_pop(PyDictObject *mp, PyObject *args) static PyObject * dict_popitem(PyDictObject *mp) { - Py_ssize_t i = 0; + Py_hash_t i = 0; PyDictEntry *ep; PyObject *res; @@ -2039,7 +2038,7 @@ static PyMethodDef mapp_methods[] = { int PyDict_Contains(PyObject *op, PyObject *key) { - long hash; + Py_hash_t hash; PyDictObject *mp = (PyDictObject *)op; PyDictEntry *ep; @@ -2055,7 +2054,7 @@ PyDict_Contains(PyObject *op, PyObject *key) /* Internal version of PyDict_Contains used when the hash value is already known */ int -_PyDict_Contains(PyObject *op, PyObject *key, long hash) +_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash) { PyDictObject *mp = (PyDictObject *)op; PyDictEntry *ep; diff --git a/Objects/floatobject.c b/Objects/floatobject.c index b792c196e2..d0173e8d13 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -522,7 +522,7 @@ float_richcompare(PyObject *v, PyObject *w, int op) return Py_NotImplemented; } -static long +static Py_hash_t float_hash(PyFloatObject *v) { return _Py_HashDouble(v->ob_fval); diff --git a/Objects/longobject.c b/Objects/longobject.c index c9c9817f12..cf7eb2c2b3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2552,7 +2552,7 @@ long_richcompare(PyObject *self, PyObject *other, int op) return v; } -static long +static Py_hash_t long_hash(PyLongObject *v) { unsigned long x; @@ -2606,7 +2606,7 @@ long_hash(PyLongObject *v) x = x * sign; if (x == (unsigned long)-1) x = (unsigned long)-2; - return (long)x; + return (Py_hash_t)x; } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 356d161842..f1a9f4b702 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -224,10 +224,10 @@ meth_richcompare(PyObject *self, PyObject *other, int op) return res; } -static long +static Py_hash_t meth_hash(PyCFunctionObject *a) { - long x,y; + Py_hash_t x, y; if (a->m_self == NULL) x = 0; else { diff --git a/Objects/object.c b/Objects/object.c index ff3363f432..2f544ba67e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -687,7 +687,7 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op) */ -long +Py_hash_t _Py_HashDouble(double v) { int e, sign; @@ -730,24 +730,24 @@ _Py_HashDouble(double v) x = x * sign; if (x == (unsigned long)-1) x = (unsigned long)-2; - return (long)x; + return (Py_hash_t)x; } -long +Py_hash_t _Py_HashPointer(void *p) { - long x; + Py_hash_t 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; + x = (Py_hash_t)y; if (x == -1) x = -2; return x; } -long +Py_hash_t PyObject_HashNotImplemented(PyObject *v) { PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", @@ -755,7 +755,7 @@ PyObject_HashNotImplemented(PyObject *v) return -1; } -long +Py_hash_t PyObject_Hash(PyObject *v) { PyTypeObject *tp = Py_TYPE(v); diff --git a/Objects/setobject.c b/Objects/setobject.c index 7eac1aa9c1..54b14da21c 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -75,7 +75,7 @@ NULL if the rich comparison returns an error. */ static setentry * -set_lookkey(PySetObject *so, PyObject *key, register long hash) +set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash) { register Py_ssize_t i; register size_t perturb; @@ -157,7 +157,7 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash) * see if the comparison altered the table. */ static setentry * -set_lookkey_unicode(PySetObject *so, PyObject *key, register long hash) +set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash) { register Py_ssize_t i; register size_t perturb; @@ -211,7 +211,7 @@ Used by the public insert routine. Eats a reference to key. */ static int -set_insert_key(register PySetObject *so, PyObject *key, long hash) +set_insert_key(register PySetObject *so, PyObject *key, Py_hash_t hash) { register setentry *entry; typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long); @@ -248,7 +248,7 @@ 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) +set_insert_clean(register PySetObject *so, PyObject *key, Py_hash_t hash) { register size_t i; register size_t perturb; @@ -349,7 +349,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) } else { /* ACTIVE */ --i; - set_insert_clean(so, entry->key, (long) entry->hash); + set_insert_clean(so, entry->key, entry->hash); } } @@ -369,7 +369,7 @@ set_add_entry(register PySetObject *so, setentry *entry) assert(so->fill <= so->mask); /* at least one empty slot */ n_used = so->used; Py_INCREF(key); - if (set_insert_key(so, key, (long) entry->hash) == -1) { + if (set_insert_key(so, key, entry->hash) == -1) { Py_DECREF(key); return -1; } @@ -381,7 +381,7 @@ set_add_entry(register PySetObject *so, setentry *entry) static int set_add_key(register PySetObject *so, PyObject *key) { - register long hash; + register Py_hash_t hash; register Py_ssize_t n_used; if (!PyUnicode_CheckExact(key) || @@ -410,7 +410,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry) { register setentry *entry; PyObject *old_key; - entry = (so->lookup)(so, oldentry->key, (long) oldentry->hash); + entry = (so->lookup)(so, oldentry->key, oldentry->hash); if (entry == NULL) return -1; if (entry->key == NULL || entry->key == dummy) @@ -426,7 +426,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry) static int set_discard_key(PySetObject *so, PyObject *key) { - register long hash; + register Py_hash_t hash; register setentry *entry; PyObject *old_key; @@ -675,7 +675,7 @@ set_merge(PySetObject *so, PyObject *otherset) static int set_contains_key(PySetObject *so, PyObject *key) { - long hash; + Py_hash_t hash; setentry *entry; if (!PyUnicode_CheckExact(key) || @@ -697,7 +697,7 @@ set_contains_entry(PySetObject *so, setentry *entry) PyObject *key; setentry *lu_entry; - lu_entry = (so->lookup)(so, entry->key, (long) entry->hash); + lu_entry = (so->lookup)(so, entry->key, entry->hash); if (lu_entry == NULL) return -1; key = lu_entry->key; @@ -761,11 +761,11 @@ set_traverse(PySetObject *so, visitproc visit, void *arg) return 0; } -static long +static Py_hash_t frozenset_hash(PyObject *self) { PySetObject *so = (PySetObject *)self; - long h, hash = 1927868237L; + Py_hash_t h, hash = 1927868237L; setentry *entry; Py_ssize_t pos = 0; @@ -926,7 +926,7 @@ set_update_internal(PySetObject *so, PyObject *other) if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; - long hash; + Py_hash_t hash; Py_ssize_t dictsize = PyDict_Size(other); /* Do one big resize at the start, rather than @@ -1114,7 +1114,7 @@ set_swap_bodies(PySetObject *a, PySetObject *b) { Py_ssize_t t; setentry *u; - setentry *(*f)(PySetObject *so, PyObject *key, long hash); + setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash); setentry tab[PySet_MINSIZE]; long h; @@ -1285,7 +1285,7 @@ set_intersection(PySetObject *so, PyObject *other) while ((key = PyIter_Next(it)) != NULL) { int rv; setentry entry; - long hash = PyObject_Hash(key); + Py_hash_t hash = PyObject_Hash(key); if (hash == -1) { Py_DECREF(it); @@ -1442,7 +1442,7 @@ set_isdisjoint(PySetObject *so, PyObject *other) while ((key = PyIter_Next(it)) != NULL) { int rv; setentry entry; - long hash = PyObject_Hash(key); + Py_hash_t hash = PyObject_Hash(key); if (hash == -1) { Py_DECREF(key); @@ -1641,7 +1641,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) if (PyDict_CheckExact(other)) { PyObject *value; int rv; - long hash; + Py_hash_t hash; while (_PyDict_Next(other, &pos, &key, &value, &hash)) { setentry an_entry; @@ -2308,7 +2308,7 @@ PySet_Add(PyObject *anyset, PyObject *key) } int -_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash) +_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash) { setentry *entry; @@ -2319,7 +2319,7 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash) if (set_next((PySetObject *)set, pos, &entry) == 0) return 0; *key = entry->key; - *hash = (long) entry->hash; + *hash = entry->hash; return 1; } @@ -2363,7 +2363,7 @@ test_c_api(PySetObject *so) Py_ssize_t i; PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x; PyObject *ob = (PyObject *)so; - long hash; + Py_hash_t hash; PyObject *str; /* Verify preconditions */ diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index aa3be821bb..c55ad65d95 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -312,10 +312,10 @@ Done: 1330111, 1412633, 1165069, 1247599, 1495177, 1577699 */ -static long +static Py_hash_t tuplehash(PyTupleObject *v) { - register long x, y; + register Py_hash_t x, y; register Py_ssize_t len = Py_SIZE(v); register PyObject **p; long mult = 1000003L; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index faa03df603..a3905d84c7 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4918,13 +4918,12 @@ slot_tp_str(PyObject *self) } } -static long +static Py_hash_t slot_tp_hash(PyObject *self) { PyObject *func, *res; static PyObject *hash_str; - long h; - int overflow; + Py_ssize_t h; func = lookup_method(self, "__hash__", &hash_str); @@ -4947,20 +4946,20 @@ slot_tp_hash(PyObject *self) "__hash__ method should return an integer"); return -1; } - /* Transform the PyLong `res` to a C long `h`. For an existing - hashable Python object x, hash(x) will always lie within the range - of a C long. Therefore our transformation must preserve values - that already lie within this range, to ensure that if x.__hash__() - returns hash(y) then hash(x) == hash(y). */ - h = PyLong_AsLongAndOverflow(res, &overflow); - if (overflow) - /* res was not within the range of a C long, so we're free to + /* Transform the PyLong `res` to a Py_hash_t `h`. For an existing + hashable Python object x, hash(x) will always lie within the range of + Py_hash_t. Therefore our transformation must preserve values that + already lie within this range, to ensure that if x.__hash__() returns + hash(y) then hash(x) == hash(y). */ + h = PyLong_AsSsize_t(res); + if (h == -1 && PyErr_Occurred()) { + /* res was not within the range of a Py_hash_t, so we're free to use any sufficiently bit-mixing transformation; long.__hash__ will do nicely. */ + PyErr_Clear(); h = PyLong_Type.tp_hash(res); + } Py_DECREF(res); - if (h == -1 && !PyErr_Occurred()) - h = -2; return h; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9fe9c42796..0e2f95018a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7444,12 +7444,12 @@ unicode_getitem(PyUnicodeObject *self, Py_ssize_t index) /* Believe it or not, this produces the same value for ASCII strings as string_hash(). */ -static long +static Py_hash_t unicode_hash(PyUnicodeObject *self) { Py_ssize_t len; Py_UNICODE *p; - long x; + Py_hash_t x; if (self->hash != -1) return self->hash; diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index f43b68d607..7a2c1bda32 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -139,7 +139,7 @@ weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw) } -static long +static Py_hash_t weakref_hash(PyWeakReference *self) { if (self->hash != -1) -- cgit v1.2.1 From 526f0e811680e8673054a05b2ab019d33addac83 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 17 Oct 2010 21:20:58 +0000 Subject: fix prototype --- Objects/dictobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 7fd586b3d9..f676aa0dd9 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -148,7 +148,7 @@ _PyDict_Dummy(void) /* forward declarations */ static PyDictEntry * -lookdict_unicode(PyDictObject *mp, PyObject *key, long hash); +lookdict_unicode(PyDictObject *mp, PyObject *key, Py_hash_t hash); #ifdef SHOW_CONVERSION_COUNTS static long created = 0L; -- cgit v1.2.1 From 1151cd4bd98e93491fd283e5f7745e346f993616 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 17 Oct 2010 21:27:01 +0000 Subject: -1 is reserved for errors --- Objects/typeobject.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a3905d84c7..2c1bf88db8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4959,6 +4959,9 @@ slot_tp_hash(PyObject *self) PyErr_Clear(); h = PyLong_Type.tp_hash(res); } + /* -1 is reserved for errors. */ + if (h == -1) + h = -2; Py_DECREF(res); return h; } -- cgit v1.2.1 From 462f09995c13bd0563fa833d75d43ad2a567506d Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Mon, 18 Oct 2010 07:32:48 +0000 Subject: Remove unneeded casts to hashfunc. --- Objects/dictobject.c | 2 +- Objects/listobject.c | 2 +- Objects/setobject.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index f676aa0dd9..c6ca40cdfe 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2143,7 +2143,7 @@ PyTypeObject PyDict_Type = { 0, /* tp_as_number */ &dict_as_sequence, /* tp_as_sequence */ &dict_as_mapping, /* tp_as_mapping */ - (hashfunc)PyObject_HashNotImplemented, /* tp_hash */ + PyObject_HashNotImplemented, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/listobject.c b/Objects/listobject.c index 88478f3db0..0f4552510a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2596,7 +2596,7 @@ PyTypeObject PyList_Type = { 0, /* tp_as_number */ &list_as_sequence, /* tp_as_sequence */ &list_as_mapping, /* tp_as_mapping */ - (hashfunc)PyObject_HashNotImplemented, /* tp_hash */ + PyObject_HashNotImplemented, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/setobject.c b/Objects/setobject.c index 54b14da21c..8d4bcf3c0f 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -2114,7 +2114,7 @@ PyTypeObject PySet_Type = { &set_as_number, /* tp_as_number */ &set_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ - (hashfunc)PyObject_HashNotImplemented, /* tp_hash */ + PyObject_HashNotImplemented, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ @@ -2126,8 +2126,8 @@ PyTypeObject PySet_Type = { (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 */ + offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)set_iter, /* tp_iter */ 0, /* tp_iternext */ set_methods, /* tp_methods */ 0, /* tp_members */ -- cgit v1.2.1 From 5d1e6e0e6f079829f66750fffbc1f8c9fe9cfd9e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 18 Oct 2010 20:59:24 +0000 Subject: PyUnicode_FromFormatV(): Fix %A format It was not completly implemented. Add a test. --- Objects/unicodeobject.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0e2f95018a..7564b67a21 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1074,6 +1074,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) } case 'S': case 'R': + case 'A': { Py_UNICODE *ucopy; Py_ssize_t usize; -- cgit v1.2.1 From babdfda4277515a2333853d65291bf74678e52b4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 20 Oct 2010 22:58:25 +0000 Subject: Issue #4388: On Mac OS X, decode command line arguments from UTF-8, instead of the locale encoding. If the LANG (and LC_ALL and LC_CTYPE) environment variable is not set, the locale encoding is ISO-8859-1, whereas most programs (including Python) expect UTF-8. Python already uses UTF-8 for the filesystem encoding and to encode command line arguments on this OS. --- Objects/unicodeobject.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7564b67a21..f5c09dd7f8 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2716,6 +2716,120 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, #undef ASCII_CHAR_MASK +#ifdef __APPLE__ + +/* Simplified UTF-8 decoder using surrogateescape error handler, + used to decode the command line arguments on Mac OS X. */ + +wchar_t* +_Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size) +{ + int n; + const char *e; + wchar_t *unicode, *p; + + /* Note: size will always be longer than the resulting Unicode + character count */ + if (PY_SSIZE_T_MAX / sizeof(wchar_t) < (size + 1)) { + PyErr_NoMemory(); + return NULL; + } + unicode = PyMem_Malloc((size + 1) * sizeof(wchar_t)); + if (!unicode) + return NULL; + + /* Unpack UTF-8 encoded data */ + p = unicode; + e = s + size; + while (s < e) { + Py_UCS4 ch = (unsigned char)*s; + + if (ch < 0x80) { + *p++ = (wchar_t)ch; + s++; + continue; + } + + n = utf8_code_length[ch]; + if (s + n > e) { + goto surrogateescape; + } + + switch (n) { + case 0: + case 1: + goto surrogateescape; + + case 2: + if ((s[1] & 0xc0) != 0x80) + goto surrogateescape; + ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f); + assert ((ch > 0x007F) && (ch <= 0x07FF)); + *p++ = (wchar_t)ch; + break; + + case 3: + /* Decoding UTF-8 sequences in range \xed\xa0\x80-\xed\xbf\xbf + will result in surrogates in range d800-dfff. Surrogates are + not valid UTF-8 so they are rejected. + See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ + 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)) { + + goto surrogateescape; + } + 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)) { + goto surrogateescape; + } + ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) + + ((s[2] & 0x3f) << 6) + (s[3] & 0x3f); + assert ((ch > 0xFFFF) && (ch <= 0x10ffff)); + +#if SIZEOF_WCHAR_T == 4 + *p++ = (wchar_t)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++ = (wchar_t)(0xD800 + (ch >> 10)); + + /* low surrogate = bottom 10 bits added to DC00 */ + *p++ = (wchar_t)(0xDC00 + (ch & 0x03FF)); +#endif + break; + } + s += n; + continue; + + surrogateescape: + *p++ = 0xDC00 + ch; + s++; + } + *p = L'\0'; + return unicode; +} + +#endif /* __APPLE__ */ /* 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 -- cgit v1.2.1 From 40c56986f7537f51a91e106c499719038edd49ae Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 22 Oct 2010 19:43:59 +0000 Subject: Issue #9935: Speed up pickling of instances of user-defined classes. --- Objects/typeobject.c | 78 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 30 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2c1bf88db8..5302a736f7 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3010,14 +3010,19 @@ static PyObject * import_copyreg(void) { static PyObject *copyreg_str; + static PyObject *mod_copyreg = NULL; if (!copyreg_str) { copyreg_str = PyUnicode_InternFromString("copyreg"); if (copyreg_str == NULL) return NULL; } + if (!mod_copyreg) { + mod_copyreg = PyImport_Import(copyreg_str); + } - return PyImport_Import(copyreg_str); + Py_XINCREF(mod_copyreg); + return mod_copyreg; } static PyObject * @@ -3026,14 +3031,16 @@ slotnames(PyObject *cls) PyObject *clsdict; PyObject *copyreg; PyObject *slotnames; + static PyObject *str_slotnames; - if (!PyType_Check(cls)) { - Py_INCREF(Py_None); - return Py_None; + if (str_slotnames == NULL) { + str_slotnames = PyUnicode_InternFromString("__slotnames__"); + if (str_slotnames == NULL) + return NULL; } clsdict = ((PyTypeObject *)cls)->tp_dict; - slotnames = PyDict_GetItemString(clsdict, "__slotnames__"); + slotnames = PyDict_GetItem(clsdict, str_slotnames); if (slotnames != NULL && PyList_Check(slotnames)) { Py_INCREF(slotnames); return slotnames; @@ -3067,12 +3074,20 @@ reduce_2(PyObject *obj) PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL; PyObject *copyreg = NULL, *newobj = NULL, *res = NULL; Py_ssize_t i, n; + static PyObject *str_getnewargs = NULL, *str_getstate = NULL, + *str_newobj = NULL; + + if (str_getnewargs == NULL) { + str_getnewargs = PyUnicode_InternFromString("__getnewargs__"); + str_getstate = PyUnicode_InternFromString("__getstate__"); + str_newobj = PyUnicode_InternFromString("__newobj__"); + if (!str_getnewargs || !str_getstate || !str_newobj) + return NULL; + } - cls = PyObject_GetAttrString(obj, "__class__"); - if (cls == NULL) - return NULL; + cls = (PyObject *) Py_TYPE(obj); - getnewargs = PyObject_GetAttrString(obj, "__getnewargs__"); + getnewargs = PyObject_GetAttr(obj, str_getnewargs); if (getnewargs != NULL) { args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); @@ -3090,7 +3105,7 @@ reduce_2(PyObject *obj) if (args == NULL) goto end; - getstate = PyObject_GetAttrString(obj, "__getstate__"); + getstate = PyObject_GetAttr(obj, str_getstate); if (getstate != NULL) { state = PyObject_CallObject(getstate, NULL); Py_DECREF(getstate); @@ -3098,17 +3113,18 @@ reduce_2(PyObject *obj) goto end; } else { + PyObject **dict; PyErr_Clear(); - state = PyObject_GetAttrString(obj, "__dict__"); - if (state == NULL) { - PyErr_Clear(); + dict = _PyObject_GetDictPtr(obj); + if (dict && *dict) + state = *dict; + else state = Py_None; - Py_INCREF(state); - } + Py_INCREF(state); names = slotnames(cls); if (names == NULL) goto end; - if (names != Py_None) { + if (names != Py_None && PyList_GET_SIZE(names) > 0) { assert(PyList_Check(names)); slots = PyDict_New(); if (slots == NULL) @@ -3167,7 +3183,7 @@ reduce_2(PyObject *obj) copyreg = import_copyreg(); if (copyreg == NULL) goto end; - newobj = PyObject_GetAttrString(copyreg, "__newobj__"); + newobj = PyObject_GetAttr(copyreg, str_newobj); if (newobj == NULL) goto end; @@ -3175,8 +3191,8 @@ reduce_2(PyObject *obj) args2 = PyTuple_New(n+1); if (args2 == NULL) goto end; + Py_INCREF(cls); PyTuple_SET_ITEM(args2, 0, cls); - cls = NULL; for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); Py_INCREF(v); @@ -3186,7 +3202,6 @@ reduce_2(PyObject *obj) res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems); end: - Py_XDECREF(cls); Py_XDECREF(args); Py_XDECREF(args2); Py_XDECREF(slots); @@ -3246,31 +3261,34 @@ object_reduce(PyObject *self, PyObject *args) static PyObject * object_reduce_ex(PyObject *self, PyObject *args) { + static PyObject *str_reduce = NULL, *objreduce; PyObject *reduce, *res; int proto = 0; if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) return NULL; - reduce = PyObject_GetAttrString(self, "__reduce__"); + if (str_reduce == NULL) { + str_reduce = PyUnicode_InternFromString("__reduce__"); + objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict, + "__reduce__"); + if (str_reduce == NULL || objreduce == NULL) + return NULL; + } + + reduce = PyObject_GetAttr(self, str_reduce); if (reduce == NULL) PyErr_Clear(); else { - PyObject *cls, *clsreduce, *objreduce; + PyObject *cls, *clsreduce; int override; - cls = PyObject_GetAttrString(self, "__class__"); - if (cls == NULL) { - Py_DECREF(reduce); - return NULL; - } - clsreduce = PyObject_GetAttrString(cls, "__reduce__"); - Py_DECREF(cls); + + cls = (PyObject *) Py_TYPE(self); + clsreduce = PyObject_GetAttr(cls, str_reduce); if (clsreduce == NULL) { Py_DECREF(reduce); return NULL; } - objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict, - "__reduce__"); override = (clsreduce != objreduce); Py_DECREF(clsreduce); if (override) { -- cgit v1.2.1 From e5bcca3fea1fab682d5619a14633335c317f51dc Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 22 Oct 2010 21:41:05 +0000 Subject: Revert r85797 (and r85798): it broke the Windows buildbots because of test_multiprocessing's misbehaviour. --- Objects/typeobject.c | 78 ++++++++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 48 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5302a736f7..2c1bf88db8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3010,19 +3010,14 @@ static PyObject * import_copyreg(void) { static PyObject *copyreg_str; - static PyObject *mod_copyreg = NULL; if (!copyreg_str) { copyreg_str = PyUnicode_InternFromString("copyreg"); if (copyreg_str == NULL) return NULL; } - if (!mod_copyreg) { - mod_copyreg = PyImport_Import(copyreg_str); - } - Py_XINCREF(mod_copyreg); - return mod_copyreg; + return PyImport_Import(copyreg_str); } static PyObject * @@ -3031,16 +3026,14 @@ slotnames(PyObject *cls) PyObject *clsdict; PyObject *copyreg; PyObject *slotnames; - static PyObject *str_slotnames; - if (str_slotnames == NULL) { - str_slotnames = PyUnicode_InternFromString("__slotnames__"); - if (str_slotnames == NULL) - return NULL; + if (!PyType_Check(cls)) { + Py_INCREF(Py_None); + return Py_None; } clsdict = ((PyTypeObject *)cls)->tp_dict; - slotnames = PyDict_GetItem(clsdict, str_slotnames); + slotnames = PyDict_GetItemString(clsdict, "__slotnames__"); if (slotnames != NULL && PyList_Check(slotnames)) { Py_INCREF(slotnames); return slotnames; @@ -3074,20 +3067,12 @@ reduce_2(PyObject *obj) PyObject *slots = NULL, *listitems = NULL, *dictitems = NULL; PyObject *copyreg = NULL, *newobj = NULL, *res = NULL; Py_ssize_t i, n; - static PyObject *str_getnewargs = NULL, *str_getstate = NULL, - *str_newobj = NULL; - - if (str_getnewargs == NULL) { - str_getnewargs = PyUnicode_InternFromString("__getnewargs__"); - str_getstate = PyUnicode_InternFromString("__getstate__"); - str_newobj = PyUnicode_InternFromString("__newobj__"); - if (!str_getnewargs || !str_getstate || !str_newobj) - return NULL; - } - cls = (PyObject *) Py_TYPE(obj); + cls = PyObject_GetAttrString(obj, "__class__"); + if (cls == NULL) + return NULL; - getnewargs = PyObject_GetAttr(obj, str_getnewargs); + getnewargs = PyObject_GetAttrString(obj, "__getnewargs__"); if (getnewargs != NULL) { args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); @@ -3105,7 +3090,7 @@ reduce_2(PyObject *obj) if (args == NULL) goto end; - getstate = PyObject_GetAttr(obj, str_getstate); + getstate = PyObject_GetAttrString(obj, "__getstate__"); if (getstate != NULL) { state = PyObject_CallObject(getstate, NULL); Py_DECREF(getstate); @@ -3113,18 +3098,17 @@ reduce_2(PyObject *obj) goto end; } else { - PyObject **dict; PyErr_Clear(); - dict = _PyObject_GetDictPtr(obj); - if (dict && *dict) - state = *dict; - else + state = PyObject_GetAttrString(obj, "__dict__"); + if (state == NULL) { + PyErr_Clear(); state = Py_None; - Py_INCREF(state); + Py_INCREF(state); + } names = slotnames(cls); if (names == NULL) goto end; - if (names != Py_None && PyList_GET_SIZE(names) > 0) { + if (names != Py_None) { assert(PyList_Check(names)); slots = PyDict_New(); if (slots == NULL) @@ -3183,7 +3167,7 @@ reduce_2(PyObject *obj) copyreg = import_copyreg(); if (copyreg == NULL) goto end; - newobj = PyObject_GetAttr(copyreg, str_newobj); + newobj = PyObject_GetAttrString(copyreg, "__newobj__"); if (newobj == NULL) goto end; @@ -3191,8 +3175,8 @@ reduce_2(PyObject *obj) args2 = PyTuple_New(n+1); if (args2 == NULL) goto end; - Py_INCREF(cls); PyTuple_SET_ITEM(args2, 0, cls); + cls = NULL; for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); Py_INCREF(v); @@ -3202,6 +3186,7 @@ reduce_2(PyObject *obj) res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems); end: + Py_XDECREF(cls); Py_XDECREF(args); Py_XDECREF(args2); Py_XDECREF(slots); @@ -3261,34 +3246,31 @@ object_reduce(PyObject *self, PyObject *args) static PyObject * object_reduce_ex(PyObject *self, PyObject *args) { - static PyObject *str_reduce = NULL, *objreduce; PyObject *reduce, *res; int proto = 0; if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) return NULL; - if (str_reduce == NULL) { - str_reduce = PyUnicode_InternFromString("__reduce__"); - objreduce = PyDict_GetItemString(PyBaseObject_Type.tp_dict, - "__reduce__"); - if (str_reduce == NULL || objreduce == NULL) - return NULL; - } - - reduce = PyObject_GetAttr(self, str_reduce); + reduce = PyObject_GetAttrString(self, "__reduce__"); if (reduce == NULL) PyErr_Clear(); else { - PyObject *cls, *clsreduce; + PyObject *cls, *clsreduce, *objreduce; int override; - - cls = (PyObject *) Py_TYPE(self); - clsreduce = PyObject_GetAttr(cls, str_reduce); + 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) { -- cgit v1.2.1 From a7dce1241ca5e5f8a6bcca41a1c2bc01314c16c2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 23 Oct 2010 16:20:50 +0000 Subject: follow up to #9778: define and use an unsigned hash type --- Objects/complexobject.c | 14 +++++++------- Objects/longobject.c | 6 +++--- Objects/object.c | 8 ++++---- Objects/tupleobject.c | 4 ++-- Objects/typeobject.c | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index c4ced31cb9..c47e0d3661 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -397,12 +397,12 @@ complex_repr(PyComplexObject *v) static Py_hash_t complex_hash(PyComplexObject *v) { - unsigned long hashreal, hashimag, combined; - hashreal = (unsigned long)_Py_HashDouble(v->cval.real); - if (hashreal == (unsigned long)-1) + Py_uhash_t hashreal, hashimag, combined; + hashreal = (Py_uhash_t)_Py_HashDouble(v->cval.real); + if (hashreal == (Py_uhash_t)-1) return -1; - hashimag = (unsigned long)_Py_HashDouble(v->cval.imag); - if (hashimag == (unsigned long)-1) + hashimag = (Py_uhash_t)_Py_HashDouble(v->cval.imag); + if (hashimag == (Py_uhash_t)-1) return -1; /* Note: if the imaginary part is 0, hashimag is 0 now, * so the following returns hashreal unchanged. This is @@ -411,8 +411,8 @@ complex_hash(PyComplexObject *v) * hash(x + 0*j) must equal hash(x). */ combined = hashreal + _PyHASH_IMAG * hashimag; - if (combined == (unsigned long)-1) - combined = (unsigned long)-2; + if (combined == (Py_uhash_t)-1) + combined = (Py_uhash_t)-2; return (Py_hash_t)combined; } diff --git a/Objects/longobject.c b/Objects/longobject.c index cf7eb2c2b3..b9ce38808f 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2555,7 +2555,7 @@ long_richcompare(PyObject *self, PyObject *other, int op) static Py_hash_t long_hash(PyLongObject *v) { - unsigned long x; + Py_uhash_t x; Py_ssize_t i; int sign; @@ -2604,8 +2604,8 @@ long_hash(PyLongObject *v) x -= _PyHASH_MODULUS; } x = x * sign; - if (x == (unsigned long)-1) - x = (unsigned long)-2; + if (x == (Py_uhash_t)-1) + x = (Py_uhash_t)-2; return (Py_hash_t)x; } diff --git a/Objects/object.c b/Objects/object.c index 2f544ba67e..723e40eacb 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -692,7 +692,7 @@ _Py_HashDouble(double v) { int e, sign; double m; - unsigned long x, y; + Py_uhash_t x, y; if (!Py_IS_FINITE(v)) { if (Py_IS_INFINITY(v)) @@ -716,7 +716,7 @@ _Py_HashDouble(double v) x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); m *= 268435456.0; /* 2**28 */ e -= 28; - y = (unsigned long)m; /* pull out integer part */ + y = (Py_uhash_t)m; /* pull out integer part */ m -= y; x += y; if (x >= _PyHASH_MODULUS) @@ -728,8 +728,8 @@ _Py_HashDouble(double v) x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); x = x * sign; - if (x == (unsigned long)-1) - x = (unsigned long)-2; + if (x == (Py_uhash_t)-1) + x = (Py_uhash_t)-2; return (Py_hash_t)x; } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index c55ad65d95..390b670f20 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -318,7 +318,7 @@ tuplehash(PyTupleObject *v) register Py_hash_t x, y; register Py_ssize_t len = Py_SIZE(v); register PyObject **p; - long mult = 1000003L; + Py_hash_t mult = 1000003L; x = 0x345678L; p = v->ob_item; while (--len >= 0) { @@ -327,7 +327,7 @@ tuplehash(PyTupleObject *v) return -1; x = (x ^ y) * mult; /* the cast might truncate len; that doesn't change hash stability */ - mult += (long)(82520L + len + len); + mult += (Py_hash_t)(82520L + len + len); } x += 97531L; if (x == -1) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2c1bf88db8..e0001db189 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4314,14 +4314,14 @@ static PyObject * wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) { hashfunc func = (hashfunc)wrapped; - long res; + Py_hash_t res; if (!check_num_args(args, 0)) return NULL; res = (*func)(self); if (res == -1 && PyErr_Occurred()) return NULL; - return PyLong_FromLong(res); + return PyLong_FromSsize_t(res); } static PyObject * -- cgit v1.2.1 From 14377845f0d691fe858cfe37e24cd2b7fc6bcc13 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 23 Oct 2010 17:37:54 +0000 Subject: Follow up to #9778: fix regressions on 64-bit Windows builds --- Objects/dictobject.c | 11 +---------- Objects/setobject.c | 12 ++++++------ 2 files changed, 7 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index c6ca40cdfe..d932ba7723 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -124,15 +124,6 @@ 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 */ @@ -531,7 +522,7 @@ insertdict(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *v { PyObject *old_value; register PyDictEntry *ep; - typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long); + typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, Py_hash_t); assert(mp->ma_lookup != NULL); ep = mp->ma_lookup(mp, key, hash); diff --git a/Objects/setobject.c b/Objects/setobject.c index 8d4bcf3c0f..dfafefd057 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -214,7 +214,7 @@ static int set_insert_key(register PySetObject *so, PyObject *key, Py_hash_t hash) { register setentry *entry; - typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long); + typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, Py_hash_t); assert(so->lookup != NULL); entry = so->lookup(so, key, hash); @@ -663,7 +663,7 @@ set_merge(PySetObject *so, PyObject *otherset) if (key != NULL && key != dummy) { Py_INCREF(key); - if (set_insert_key(so, key, (long) entry->hash) == -1) { + if (set_insert_key(so, key, entry->hash) == -1) { Py_DECREF(key); return -1; } @@ -772,14 +772,14 @@ frozenset_hash(PyObject *self) if (so->hash != -1) return so->hash; - hash *= (long) PySet_GET_SIZE(self) + 1; + 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 = (long) entry->hash; + h = entry->hash; hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u; } hash = hash * 69069L + 907133923L; @@ -1116,7 +1116,7 @@ set_swap_bodies(PySetObject *a, PySetObject *b) setentry *u; setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash); setentry tab[PySet_MINSIZE]; - long h; + Py_hash_t h; t = a->fill; a->fill = b->fill; b->fill = t; t = a->used; a->used = b->used; b->used = t; @@ -1550,7 +1550,7 @@ set_difference(PySetObject *so, PyObject *other) setentry entrycopy; entrycopy.hash = entry->hash; entrycopy.key = entry->key; - if (!_PyDict_Contains(other, entry->key, (long) entry->hash)) { + if (!_PyDict_Contains(other, entry->key, entry->hash)) { if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { Py_DECREF(result); return NULL; -- cgit v1.2.1 From a799acdd559c24056cc846fa65af9b1a250e2f36 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 24 Oct 2010 15:11:22 +0000 Subject: Add a new warning gategory, ResourceWarning, as discussed on python-dev. It is silent by default, except when configured --with-pydebug. Emit this warning from the GC shutdown procedure, rather than just printing to stderr. --- Objects/exceptions.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index b82b6ba87f..5715b26fa7 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1852,6 +1852,7 @@ SimpleExtendsException(PyExc_Warning, UnicodeWarning, "Base class for warnings about Unicode related problems, mostly\n" "related to conversion problems."); + /* * BytesWarning extends Warning */ @@ -1860,6 +1861,13 @@ SimpleExtendsException(PyExc_Warning, BytesWarning, "related to conversion from str or comparing to str."); +/* + * ResourceWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, ResourceWarning, + "Base class for warnings about resource usage."); + + /* Pre-computed MemoryError instance. Best to create this as early as * possible and not wait until a MemoryError is actually raised! @@ -1939,6 +1947,7 @@ _PyExc_Init(void) PRE_INIT(ImportWarning) PRE_INIT(UnicodeWarning) PRE_INIT(BytesWarning) + PRE_INIT(ResourceWarning) bltinmod = PyImport_ImportModule("builtins"); if (bltinmod == NULL) @@ -2001,6 +2010,7 @@ _PyExc_Init(void) POST_INIT(ImportWarning) POST_INIT(UnicodeWarning) POST_INIT(BytesWarning) + POST_INIT(ResourceWarning) PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL); if (!PyExc_MemoryErrorInst) -- cgit v1.2.1 From 9f1fb208c62a2cc8c39f6258f4e1c51d818d3895 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 27 Oct 2010 00:25:46 +0000 Subject: Simplify PyUnicode_Encode/DecodeFSDefault on Windows/Mac OS X * Windows always uses mbcs * Mac OS X always uses utf-8 --- Objects/unicodeobject.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f5c09dd7f8..17dc27e6e9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1584,15 +1584,19 @@ PyObject *PyUnicode_AsEncodedObject(PyObject *unicode, return NULL; } -PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) +PyObject * +PyUnicode_EncodeFSDefault(PyObject *unicode) { - if (Py_FileSystemDefaultEncoding) { #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) - return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), - PyUnicode_GET_SIZE(unicode), - NULL); -#endif + return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + NULL); +#elif defined(__APPLE__) + return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + "surrogateescape"); +#else + if (Py_FileSystemDefaultEncoding) { return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); @@ -1615,6 +1619,7 @@ PyObject *PyUnicode_EncodeFSDefault(PyObject *unicode) PyMem_Free(bytes); return bytes_obj; } +#endif } PyObject *PyUnicode_AsEncodedString(PyObject *unicode, @@ -1761,21 +1766,17 @@ PyUnicode_DecodeFSDefault(const char *s) { PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) { +#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) + return PyUnicode_DecodeMBCS(s, size, NULL); +#elif defined(__APPLE__) + return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); +#else /* During the early bootstrapping process, Py_FileSystemDefaultEncoding can be undefined. If it is case, decode using UTF-8. The following assumes that Py_FileSystemDefaultEncoding is set to a built-in encoding during the bootstrapping process where the codecs aren't ready yet. */ if (Py_FileSystemDefaultEncoding) { -#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) - if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) { - return PyUnicode_DecodeMBCS(s, size, NULL); - } -#elif defined(__APPLE__) - if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) { - return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); - } -#endif return PyUnicode_Decode(s, size, Py_FileSystemDefaultEncoding, "surrogateescape"); @@ -1799,6 +1800,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) PyMem_Free(wchar); return unicode; } +#endif } -- cgit v1.2.1 From a0b3b96364f8ee0e88add47f1497bb2111878039 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 28 Oct 2010 22:56:58 +0000 Subject: Issue #5437: A preallocated MemoryError instance should not hold traceback data (including local variables caught in the stack trace) alive infinitely. --- Objects/exceptions.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 5715b26fa7..0106ba3df5 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1777,7 +1777,91 @@ SimpleExtendsException(PyExc_Exception, ReferenceError, /* * MemoryError extends Exception */ -SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory."); + +#define MEMERRORS_SAVE 16 +static PyBaseExceptionObject *memerrors_freelist = NULL; +static int memerrors_numfree = 0; + +static PyObject * +MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyBaseExceptionObject *self; + + if (type != (PyTypeObject *) PyExc_MemoryError) + return BaseException_new(type, args, kwds); + if (memerrors_freelist == NULL) + return BaseException_new(type, args, kwds); + /* Fetch object from freelist and revive it */ + self = memerrors_freelist; + self->args = PyTuple_New(0); + /* This shouldn't happen since the empty tuple is persistent */ + if (self->args == NULL) + return NULL; + memerrors_freelist = (PyBaseExceptionObject *) self->dict; + memerrors_numfree--; + self->dict = NULL; + _Py_NewReference((PyObject *)self); + _PyObject_GC_TRACK(self); + return (PyObject *)self; +} + +static void +MemoryError_dealloc(PyBaseExceptionObject *self) +{ + _PyObject_GC_UNTRACK(self); + BaseException_clear(self); + if (memerrors_numfree >= MEMERRORS_SAVE) + Py_TYPE(self)->tp_free((PyObject *)self); + else { + self->dict = (PyObject *) memerrors_freelist; + memerrors_freelist = self; + memerrors_numfree++; + } +} + +static void +preallocate_memerrors(void) +{ + /* We create enough MemoryErrors and then decref them, which will fill + up the freelist. */ + int i; + PyObject *errors[MEMERRORS_SAVE]; + for (i = 0; i < MEMERRORS_SAVE; i++) { + errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError, + NULL, NULL); + if (!errors[i]) + Py_FatalError("Could not preallocate MemoryError object"); + } + for (i = 0; i < MEMERRORS_SAVE; i++) { + Py_DECREF(errors[i]); + } +} + +static void +free_preallocated_memerrors(void) +{ + while (memerrors_freelist != NULL) { + PyObject *self = (PyObject *) memerrors_freelist; + memerrors_freelist = (PyBaseExceptionObject *) memerrors_freelist->dict; + Py_TYPE(self)->tp_free((PyObject *)self); + } +} + + +static PyTypeObject _PyExc_MemoryError = { + PyVarObject_HEAD_INIT(NULL, 0) + "MemoryError", + sizeof(PyBaseExceptionObject), + 0, (destructor)MemoryError_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("Out of memory."), (traverseproc)BaseException_traverse, + (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_PyExc_Exception, + 0, 0, 0, offsetof(PyBaseExceptionObject, dict), + (initproc)BaseException_init, 0, MemoryError_new +}; +PyObject *PyExc_MemoryError = (PyObject *) &_PyExc_MemoryError; + /* * BufferError extends Exception @@ -1869,11 +1953,6 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, -/* 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. @@ -2012,9 +2091,7 @@ _PyExc_Init(void) POST_INIT(BytesWarning) POST_INIT(ResourceWarning) - PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL); - if (!PyExc_MemoryErrorInst) - Py_FatalError("Cannot pre-allocate MemoryError instance"); + preallocate_memerrors(); PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); if (!PyExc_RecursionErrorInst) @@ -2045,6 +2122,6 @@ _PyExc_Init(void) void _PyExc_Fini(void) { - Py_CLEAR(PyExc_MemoryErrorInst); Py_CLEAR(PyExc_RecursionErrorInst); + free_preallocated_memerrors(); } -- cgit v1.2.1 From 35f786a30a4ceeb1c905e98dbe3b763be604f418 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 30 Oct 2010 08:10:29 +0000 Subject: Issue 10221: Improve error message for dict.pop(). --- Objects/dictobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index d932ba7723..1015772898 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1820,8 +1820,7 @@ dict_pop(PyDictObject *mp, PyObject *args) Py_INCREF(deflt); return deflt; } - PyErr_SetString(PyExc_KeyError, - "pop(): dictionary is empty"); + set_key_error(key); return NULL; } if (!PyUnicode_CheckExact(key) || -- cgit v1.2.1 From 2f9e0c4e3be492d78da18fc151f4495cb702f879 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 3 Nov 2010 23:11:10 +0000 Subject: deuglify --- Objects/memoryobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 36626b2cdd..432673091d 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -371,8 +371,9 @@ _IntTupleFromSsizet(int len, Py_ssize_t *vals) return Py_None; } intTuple = PyTuple_New(len); - if (!intTuple) return NULL; - for(i=0; i Date: Thu, 4 Nov 2010 17:06:58 +0000 Subject: Issue #6081: Add str.format_map. str.format_map(mapping) is similar to str.format(**mapping), except mapping does not get converted to a dict. --- Objects/stringlib/string_format.h | 11 ++++++++++- Objects/unicodeobject.c | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 126c870113..5205aa9fbc 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -499,7 +499,11 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, PyObject *key = SubString_new_object(&first); if (key == NULL) goto error; - if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) { + + /* Use PyObject_GetItem instead of PyDict_GetItem because this + code is no longer just used with kwargs. It might be passed + a non-dict when called through format_map. */ + if ((kwargs == NULL) || (obj = PyObject_GetItem(kwargs, key)) == NULL) { PyErr_SetObject(PyExc_KeyError, key); Py_DECREF(key); goto error; @@ -1039,6 +1043,11 @@ do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) return build_string(&input, args, kwargs, recursion_depth, &auto_number); } +static PyObject * +do_string_format_map(PyObject *self, PyObject *obj) +{ + return do_string_format(self, NULL, obj); +} /************************************************************************/ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 17dc27e6e9..b67b8f9fb1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9028,6 +9028,11 @@ PyDoc_STRVAR(format__doc__, \n\ "); +PyDoc_STRVAR(format_map__doc__, + "S.format_map(mapping) -> str\n\ +\n\ +"); + static PyObject * unicode__format__(PyObject* self, PyObject* args) { @@ -9109,6 +9114,7 @@ static PyMethodDef unicode_methods[] = { {"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__}, {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__}, {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, + {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__}, {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, -- cgit v1.2.1 From 7c82d310795de34099fc01abba0392a06d32f9f4 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 4 Nov 2010 20:30:33 +0000 Subject: Issue #10293: Remove obsolete field in the PyMemoryView structure, unused undocumented value PyBUF_SHADOW, and strangely-looking code in PyMemoryView_GetContiguous. --- Objects/memoryobject.c | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 432673091d..ba9e08b9ab 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -82,7 +82,6 @@ PyMemoryView_FromBuffer(Py_buffer *info) 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(). */ @@ -112,8 +111,6 @@ PyMemoryView_FromObject(PyObject *base) return NULL; } - mview->base = base; - Py_INCREF(base); return (PyObject *)mview; } @@ -291,8 +288,6 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) if (PyBuffer_IsContiguous(view, fort)) { /* no copy needed */ - Py_INCREF(obj); - mem->base = obj; _PyObject_GC_TRACK(mem); return (PyObject *)mem; } @@ -324,21 +319,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) 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; @@ -481,28 +462,7 @@ static void do_release(PyMemoryViewObject *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); + PyBuffer_Release(&(self->view)); } self->view.obj = NULL; self->view.buf = NULL; @@ -819,8 +779,6 @@ _notimpl: 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; @@ -829,7 +787,6 @@ memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg) static int memory_clear(PyMemoryViewObject *self) { - Py_CLEAR(self->base); PyBuffer_Release(&self->view); return 0; } -- cgit v1.2.1 From 7c27ae73b6e8218aa84c654ed11ce4e5ea7c90d6 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 5 Nov 2010 12:23:55 +0000 Subject: Followup to r86170: fix reference leak in str.format --- Objects/stringlib/string_format.h | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 5205aa9fbc..40535457f3 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -509,7 +509,6 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, goto error; } Py_DECREF(key); - Py_INCREF(obj); } else { /* look up in args */ -- cgit v1.2.1 From e24d58064a6b3b72c8b55336d83a9106cf84c4b6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 5 Nov 2010 17:23:41 +0000 Subject: Issue #10288: The deprecated family of "char"-handling macros (ISLOWER()/ISUPPER()/etc) have now been removed: use Py_ISLOWER() etc instead. --- Objects/bytesobject.c | 28 ++++++++++++++-------------- Objects/unicodeobject.c | 20 ++++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 2b965c37ae..382e911008 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -178,7 +178,7 @@ PyBytes_FromFormatV(const char *format, va_list vargs) for (f = format; *f; f++) { if (*f == '%') { const char* p = f; - while (*++f && *f != '%' && !ISALPHA(*f)) + while (*++f && *f != '%' && !Py_ISALPHA(*f)) ; /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since @@ -247,15 +247,15 @@ PyBytes_FromFormatV(const char *format, va_list vargs) /* parse the width.precision part (we're only interested in the precision value, if any) */ n = 0; - while (ISDIGIT(*f)) + while (Py_ISDIGIT(*f)) n = (n*10) + *f++ - '0'; if (*f == '.') { f++; n = 0; - while (ISDIGIT(*f)) + while (Py_ISDIGIT(*f)) n = (n*10) + *f++ - '0'; } - while (*f && *f != '%' && !ISALPHA(*f)) + while (*f && *f != '%' && !Py_ISALPHA(*f)) f++; /* handle the long flag, but only for %ld and %lu. others can be added when necessary. */ @@ -446,22 +446,22 @@ PyObject *PyBytes_DecodeEscape(const char *s, *p++ = c; break; case 'x': - if (s+1 < end && ISXDIGIT(s[0]) && ISXDIGIT(s[1])) { + if (s+1 < end && Py_ISXDIGIT(s[0]) && Py_ISXDIGIT(s[1])) { unsigned int x = 0; c = Py_CHARMASK(*s); s++; - if (ISDIGIT(c)) + if (Py_ISDIGIT(c)) x = c - '0'; - else if (ISLOWER(c)) + else if (Py_ISLOWER(c)) x = 10 + c - 'a'; else x = 10 + c - 'A'; x = x << 4; c = Py_CHARMASK(*s); s++; - if (ISDIGIT(c)) + if (Py_ISDIGIT(c)) x += c - '0'; - else if (ISLOWER(c)) + else if (Py_ISLOWER(c)) x += 10 + c - 'a'; else x += 10 + c - 'A'; @@ -1406,7 +1406,7 @@ do_strip(PyBytesObject *self, int striptype) i = 0; if (striptype != RIGHTSTRIP) { - while (i < len && ISSPACE(s[i])) { + while (i < len && Py_ISSPACE(s[i])) { i++; } } @@ -1415,7 +1415,7 @@ do_strip(PyBytesObject *self, int striptype) if (striptype != LEFTSTRIP) { do { j--; - } while (j >= i && ISSPACE(s[j])); + } while (j >= i && Py_ISSPACE(s[j])); j++; } @@ -2347,11 +2347,11 @@ hex_digit_to_int(Py_UNICODE c) { if (c >= 128) return -1; - if (ISDIGIT(c)) + if (Py_ISDIGIT(c)) return c - '0'; else { - if (ISUPPER(c)) - c = TOLOWER(c); + if (Py_ISUPPER(c)) + c = Py_TOLOWER(c); if (c >= 'a' && c <= 'f') return c - 'a' + 10; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index b67b8f9fb1..35d86009f1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -757,9 +757,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) continue; if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A') ++callcount; - while (ISDIGIT((unsigned)*f)) + while (Py_ISDIGIT((unsigned)*f)) width = (width*10) + *f++ - '0'; - while (*++f && *f != '%' && !ISALPHA((unsigned)*f)) + while (*++f && *f != '%' && !Py_ISALPHA((unsigned)*f)) ; if (*f == 's') ++callcount; @@ -790,9 +790,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) #endif const char* p = f; width = 0; - while (ISDIGIT((unsigned)*f)) + while (Py_ISDIGIT((unsigned)*f)) width = (width*10) + *f++ - '0'; - while (*++f && *f != '%' && !ISALPHA((unsigned)*f)) + while (*++f && *f != '%' && !Py_ISALPHA((unsigned)*f)) ; /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since @@ -965,12 +965,12 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) zeropad = (*f == '0'); /* parse the width.precision part */ width = 0; - while (ISDIGIT((unsigned)*f)) + while (Py_ISDIGIT((unsigned)*f)) width = (width*10) + *f++ - '0'; precision = 0; if (*f == '.') { f++; - while (ISDIGIT((unsigned)*f)) + while (Py_ISDIGIT((unsigned)*f)) precision = (precision*10) + *f++ - '0'; } /* Handle %ld, %lu, %lld and %llu. */ @@ -1419,8 +1419,8 @@ normalize_encoding(const char *encoding, while (*e) { if (l == l_end) return 0; - if (ISUPPER(*e)) { - *l++ = TOLOWER(*e++); + if (Py_ISUPPER(*e)) { + *l++ = Py_TOLOWER(*e++); } else if (*e == '_') { *l++ = '-'; @@ -3790,7 +3790,7 @@ PyObject *PyUnicode_DecodeUnicodeEscape(const char *s, } for (i = 0; i < digits; ++i) { c = (unsigned char) s[i]; - if (!ISXDIGIT(c)) { + if (!Py_ISXDIGIT(c)) { endinpos = (s+i+1)-starts; if (unicode_decode_call_errorhandler( errors, &errorHandler, @@ -4156,7 +4156,7 @@ PyObject *PyUnicode_DecodeRawUnicodeEscape(const char *s, outpos = p-PyUnicode_AS_UNICODE(v); for (x = 0, i = 0; i < count; ++i, ++s) { c = (unsigned char)*s; - if (!ISXDIGIT(c)) { + if (!Py_ISXDIGIT(c)) { endinpos = s-starts; if (unicode_decode_call_errorhandler( errors, &errorHandler, -- cgit v1.2.1 From 9f33ab04d5442629f33b381d58dc6fa7c17cd275 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Nov 2010 19:27:37 +0000 Subject: Added more to docstrings for str.format, format_map, and __format__. --- Objects/unicodeobject.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 35d86009f1..32bcb344f4 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9026,12 +9026,14 @@ unicode_endswith(PyUnicodeObject *self, PyDoc_STRVAR(format__doc__, "S.format(*args, **kwargs) -> str\n\ \n\ -"); +Return a formatted version of S, using substitutions from args and kwargs.\n\ +The substitutions are identified by braces ('{' and '}')."); PyDoc_STRVAR(format_map__doc__, "S.format_map(mapping) -> str\n\ \n\ -"); +Return a formatted version of S, using substitutions from mapping.\n\ +The substitutions are identified by braces ('{' and '}')."); static PyObject * unicode__format__(PyObject* self, PyObject* args) @@ -9049,7 +9051,7 @@ unicode__format__(PyObject* self, PyObject* args) PyDoc_STRVAR(p_format__doc__, "S.__format__(format_spec) -> str\n\ \n\ -"); +Return a formatted version of S as described by format_spec."); static PyObject * unicode__sizeof__(PyUnicodeObject *v) -- cgit v1.2.1 From 82596a49307c2596866b454d45bee252df56032c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Nov 2010 18:41:46 +0000 Subject: Fix encode/decode method doc of str, bytes, bytearray types * Specify the default encoding: write 'utf-8' instead of sys.getdefaultencoding(), because the default encoding is now constant * Specify the default errors value --- Objects/bytearrayobject.c | 6 +++--- Objects/bytesobject.c | 6 +++--- Objects/unicodeobject.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 283102ae6f..1a50ce3101 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2465,10 +2465,10 @@ bytearray_rstrip(PyByteArrayObject *self, PyObject *args) } PyDoc_STRVAR(decode_doc, -"B.decode([encoding[, errors]]) -> str\n\ +"B.decode([encoding='utf-8'[, errors='strict']]) -> str\n\ \n\ -Decode B using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ +Decode B using the codec registered for encoding. Default encoding\n\ +is 'utf-8'. 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\ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 382e911008..b8fa8ee255 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2289,10 +2289,10 @@ bytes_endswith(PyBytesObject *self, PyObject *args) PyDoc_STRVAR(decode__doc__, -"B.decode([encoding[, errors]]) -> str\n\ +"B.decode([encoding='utf-8'[, errors='strict']]) -> str\n\ \n\ -Decode B using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ +Decode B using the codec registered for encoding. Default encoding\n\ +is 'utf-8'. 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 registerd with codecs.register_error that is\n\ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 32bcb344f4..4be0b17c39 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7393,10 +7393,10 @@ unicode_count(PyUnicodeObject *self, PyObject *args) } PyDoc_STRVAR(encode__doc__, - "S.encode([encoding[, errors]]) -> bytes\n\ + "S.encode([encoding='utf-8'[, errors='strict']]) -> bytes\n\ \n\ -Encode S using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ +Encode S using the codec registered for encoding. Default encoding\n\ +is 'utf-8'. 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\ -- cgit v1.2.1 From 0fc8923ec1da0ef4afb40b83985135ce94dc0cc1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 7 Nov 2010 19:04:46 +0000 Subject: str, bytes, bytearray docstring: remove unnecessary [...] --- Objects/bytearrayobject.c | 2 +- Objects/bytesobject.c | 2 +- Objects/unicodeobject.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 1a50ce3101..f419eee955 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2465,7 +2465,7 @@ bytearray_rstrip(PyByteArrayObject *self, PyObject *args) } PyDoc_STRVAR(decode_doc, -"B.decode([encoding='utf-8'[, errors='strict']]) -> str\n\ +"B.decode(encoding='utf-8', errors='strict') -> str\n\ \n\ Decode B using the codec registered for encoding. Default encoding\n\ is 'utf-8'. errors may be given to set a different error\n\ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index b8fa8ee255..96134a3a3f 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2289,7 +2289,7 @@ bytes_endswith(PyBytesObject *self, PyObject *args) PyDoc_STRVAR(decode__doc__, -"B.decode([encoding='utf-8'[, errors='strict']]) -> str\n\ +"B.decode(encoding='utf-8', errors='strict') -> str\n\ \n\ Decode B using the codec registered for encoding. Default encoding\n\ is 'utf-8'. errors may be given to set a different error\n\ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4be0b17c39..cff756a1ce 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7393,7 +7393,7 @@ unicode_count(PyUnicodeObject *self, PyObject *args) } PyDoc_STRVAR(encode__doc__, - "S.encode([encoding='utf-8'[, errors='strict']]) -> bytes\n\ + "S.encode(encoding='utf-8', errors='strict') -> bytes\n\ \n\ Encode S using the codec registered for encoding. Default encoding\n\ is 'utf-8'. errors may be given to set a different error\n\ -- cgit v1.2.1 From 004b7b95f3ffafabb761f4d3d6d17b67d11e3119 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 8 Nov 2010 22:43:46 +0000 Subject: PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails * Add error_pos optional argument to _Py_wchar2char() * PyUnicode_EncodeFS() raises a UnicodeEncodeError or MemoryError if _Py_wchar2char() fails --- Objects/unicodeobject.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index cff756a1ce..2250f45e9a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1606,14 +1606,31 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) wchar_t *wchar; char *bytes; PyObject *bytes_obj; + size_t error_pos; wchar = PyUnicode_AsWideCharString(unicode, NULL); if (wchar == NULL) return NULL; - bytes = _Py_wchar2char(wchar); - PyMem_Free(wchar); - if (bytes == NULL) + bytes = _Py_wchar2char(wchar, &error_pos); + if (bytes == NULL) { + if (error_pos != (size_t)-1) { + char *errmsg = strerror(errno); + PyObject *exc = NULL; + if (errmsg == NULL) + errmsg = "Py_wchar2char() failed"; + raise_encode_exception(&exc, + "filesystemencoding", + PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), + error_pos, error_pos+1, + errmsg); + Py_XDECREF(exc); + } + else + PyErr_NoMemory(); + PyMem_Free(wchar); return NULL; + } + PyMem_Free(wchar); bytes_obj = PyBytes_FromString(bytes); PyMem_Free(bytes); -- cgit v1.2.1 From 18b7df3d47377a982f150f03104efc13a5cae77b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 8 Nov 2010 23:34:29 +0000 Subject: PyUnicode_DecodeFSDefaultAndSize() raises MemoryError if _Py_char2wchar() fails --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2250f45e9a..d6cc8b5a24 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1811,7 +1811,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) wchar = _Py_char2wchar(s, &len); if (wchar == NULL) - return NULL; + return PyErr_NoMemory(); unicode = PyUnicode_FromWideChar(wchar, len); PyMem_Free(wchar); -- cgit v1.2.1 From f51cc3fcfc4352e6cc8f0e7292594aa5a462c45d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 9 Nov 2010 09:32:19 +0000 Subject: Issue #10359: Remove ";" after function definition, invalid in ISO C --- Objects/weakrefobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 7a2c1bda32..13323cfbcf 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -583,7 +583,7 @@ proxy_iternext(PyWeakReference *proxy) } -WRAP_METHOD(proxy_bytes, "__bytes__"); +WRAP_METHOD(proxy_bytes, "__bytes__") static PyMethodDef proxy_methods[] = { -- cgit v1.2.1 From c6988922ca2c06a951ebe4ea907421105ee96806 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 17 Nov 2010 22:33:12 +0000 Subject: handle dict subclasses gracefully in PyArg_ValidateKeywordArguments --- Objects/dictobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1015772898..df8d77f313 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -454,7 +454,7 @@ _PyDict_HasOnlyStringKeys(PyObject *dict) { Py_ssize_t pos = 0; PyObject *key, *value; - assert(PyDict_CheckExact(dict)); + assert(PyDict_Check(dict)); /* Shortcut */ if (((PyDictObject *)dict)->ma_lookup == lookdict_unicode) return 1; -- cgit v1.2.1 From 638fb32140af1f1bb15c77aaa49dae9f8d45c9fc Mon Sep 17 00:00:00 2001 From: "R. David Murray" Date: Sat, 20 Nov 2010 16:33:30 +0000 Subject: #1574217: only swallow AttributeErrors in isinstance, not everything. Patch and tests by Brian Harring, with improvements by Ralf Schmitt. --- Objects/abstract.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 4eb33d3bc5..d039a9c864 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2500,7 +2500,12 @@ recursive_isinstance(PyObject *inst, PyObject *cls) if (retval == 0) { PyObject *c = PyObject_GetAttr(inst, __class__); if (c == NULL) { - PyErr_Clear(); + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + retval = -1; + } } else { if (c != (PyObject *)(inst->ob_type) && @@ -2518,8 +2523,12 @@ recursive_isinstance(PyObject *inst, PyObject *cls) return -1; icls = PyObject_GetAttr(inst, __class__); if (icls == NULL) { - PyErr_Clear(); - retval = 0; + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + else { + retval = -1; + } } else { retval = abstract_issubclass(icls, cls); -- cgit v1.2.1 From 7b237695d126eb9a09ee9d12bd86055fa90c46c2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 20 Nov 2010 17:21:08 +0000 Subject: code style --- Objects/abstract.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index d039a9c864..2f887aa056 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2500,12 +2500,10 @@ recursive_isinstance(PyObject *inst, PyObject *cls) if (retval == 0) { PyObject *c = PyObject_GetAttr(inst, __class__); if (c == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); - } - else { + else retval = -1; - } } else { if (c != (PyObject *)(inst->ob_type) && @@ -2523,12 +2521,10 @@ recursive_isinstance(PyObject *inst, PyObject *cls) return -1; icls = PyObject_GetAttr(inst, __class__); if (icls == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); - } - else { + else retval = -1; - } } else { retval = abstract_issubclass(icls, cls); -- cgit v1.2.1 From 18533c02ce020f321f3993da901c38f43df80579 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 20 Nov 2010 22:35:41 +0000 Subject: count() should return integers #10474 --- Objects/rangeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 965038635c..2188dfba59 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -338,9 +338,9 @@ range_count(rangeobject *r, PyObject *ob) { if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { if (range_contains_long(r, ob)) - Py_RETURN_TRUE; + return PyLong_FromLong(1); else - Py_RETURN_FALSE; + return PyLong_FromLong(0); } else { Py_ssize_t count; count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT); -- cgit v1.2.1 From 42f560d4478a35604f16f2893de12e7530f57b14 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 20 Nov 2010 22:40:10 +0000 Subject: Add error handling in range_count. --- Objects/rangeobject.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 2188dfba59..d7bf018a1d 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -337,7 +337,10 @@ static PyObject * range_count(rangeobject *r, PyObject *ob) { if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { - if (range_contains_long(r, ob)) + int result = range_contains_long(r, ob); + if (result == -1) + return NULL; + else if (result) return PyLong_FromLong(1); else return PyLong_FromLong(0); -- cgit v1.2.1 From ab4b00b06424960b95258bcaf936130d95b07b29 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 20 Nov 2010 22:44:32 +0000 Subject: code style and simplification --- Objects/rangeobject.c | 103 +++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 72 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index d7bf018a1d..66d743fb9a 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -20,8 +20,7 @@ typedef struct { NULL on error. */ static PyObject * -validate_step(PyObject *step) -{ +validate_step(PyObject *step) { /* No step specified, use a step of 1. */ if (!step) return PyLong_FromLong(1); @@ -49,8 +48,7 @@ validate_step(PyObject *step) range(0, 5, -1) */ static PyObject * -range_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ +range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { rangeobject *obj = NULL; PyObject *start = NULL, *stop = NULL, *step = NULL; @@ -118,8 +116,7 @@ PyDoc_STRVAR(range_doc, Returns an iterator that generates the numbers in the range on demand."); static void -range_dealloc(rangeobject *r) -{ +range_dealloc(rangeobject *r) { Py_DECREF(r->start); Py_DECREF(r->stop); Py_DECREF(r->step); @@ -131,8 +128,7 @@ range_dealloc(rangeobject *r) * PyLong_Check(). Return NULL when there is an error. */ static PyObject* -range_length_obj(rangeobject *r) -{ +range_length_obj(rangeobject *r) { /* ------------------------------------------------------------- Algorithm is equal to that of get_len_of_range(), but it operates on PyObjects (which are assumed to be PyLong objects). @@ -204,8 +200,7 @@ range_length_obj(rangeobject *r) } static Py_ssize_t -range_length(rangeobject *r) -{ +range_length(rangeobject *r) { PyObject *len = range_length_obj(r); Py_ssize_t result = -1; if (len) { @@ -218,8 +213,7 @@ range_length(rangeobject *r) /* range(...)[x] is necessary for: seq[:] = range(...) */ static PyObject * -range_item(rangeobject *r, Py_ssize_t i) -{ +range_item(rangeobject *r, Py_ssize_t i) { Py_ssize_t len = range_length(r); PyObject *rem, *incr, *result; @@ -246,8 +240,7 @@ range_item(rangeobject *r, Py_ssize_t i) } static PyObject * -range_repr(rangeobject *r) -{ +range_repr(rangeobject *r) { Py_ssize_t istep; /* Check for special case values for printing. We don't always @@ -267,16 +260,14 @@ range_repr(rangeobject *r) /* Pickling support */ static PyObject * -range_reduce(rangeobject *r, PyObject *args) -{ +range_reduce(rangeobject *r, PyObject *args) { return Py_BuildValue("(O(OOO))", Py_TYPE(r), r->start, r->stop, r->step); } /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ static int -range_contains_long(rangeobject *r, PyObject *ob) -{ +range_contains_long(rangeobject *r, PyObject *ob) { int cmp1, cmp2, cmp3; PyObject *tmp1 = NULL; PyObject *tmp2 = NULL; @@ -334,8 +325,7 @@ range_contains(rangeobject *r, PyObject *ob) { } static PyObject * -range_count(rangeobject *r, PyObject *ob) -{ +range_count(rangeobject *r, PyObject *ob) { if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { int result = range_contains_long(r, ob); if (result == -1) @@ -354,12 +344,8 @@ range_count(rangeobject *r, PyObject *ob) } static PyObject * -range_index(rangeobject *r, PyObject *ob) -{ - PyObject *idx, *tmp; +range_index(rangeobject *r, PyObject *ob) { int contains; - PyObject *format_tuple, *err_string; - static PyObject *err_format = NULL; if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) { Py_ssize_t index; @@ -373,35 +359,18 @@ range_index(rangeobject *r, PyObject *ob) if (contains == -1) return NULL; - if (!contains) - goto value_error; - - tmp = PyNumber_Subtract(ob, r->start); - if (tmp == NULL) - return NULL; - - /* idx = (ob - r.start) // r.step */ - idx = PyNumber_FloorDivide(tmp, r->step); - Py_DECREF(tmp); - return idx; - -value_error: - - /* object is not in the range */ - if (err_format == NULL) { - err_format = PyUnicode_FromString("%r is not in range"); - if (err_format == NULL) + if (contains) { + PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start); + if (tmp == NULL) return NULL; + /* idx = (ob - r.start) // r.step */ + idx = PyNumber_FloorDivide(tmp, r->step); + Py_DECREF(tmp); + return idx; } - format_tuple = PyTuple_Pack(1, ob); - if (format_tuple == NULL) - return NULL; - err_string = PyUnicode_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); + + /* object is not in the range */ + PyErr_Format(PyExc_ValueError, "%R is not in range", ob); return NULL; } @@ -494,8 +463,7 @@ typedef struct { } rangeiterobject; static PyObject * -rangeiter_next(rangeiterobject *r) -{ +rangeiter_next(rangeiterobject *r) { if (r->index < r->len) /* cast to unsigned to avoid possible signed overflow in intermediate calculations. */ @@ -505,8 +473,7 @@ rangeiter_next(rangeiterobject *r) } static PyObject * -rangeiter_len(rangeiterobject *r) -{ +rangeiter_len(rangeiterobject *r) { return PyLong_FromLong(r->len - r->index); } @@ -519,8 +486,7 @@ typedef struct { } longrangeiterobject; static PyObject * -longrangeiter_len(longrangeiterobject *r, PyObject *no_args) -{ +longrangeiter_len(longrangeiterobject *r, PyObject *no_args) { return PyNumber_Subtract(r->len, r->index); } @@ -581,8 +547,7 @@ PyTypeObject PyRangeIter_Type = { * required. The result always fits in an unsigned long. */ static unsigned long -get_len_of_range(long lo, long hi, long step) -{ +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 @@ -609,8 +574,7 @@ get_len_of_range(long lo, long hi, long step) is not representable as a C long, OverflowError is raised. */ static PyObject * -int_range_iter(long start, long stop, long step) -{ +int_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); unsigned long ulen; if (it == NULL) @@ -630,8 +594,7 @@ int_range_iter(long start, long stop, long step) } static PyObject * -rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ +rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) { long start, stop, step; if (!_PyArg_NoKeywords("rangeiter()", kw)) @@ -651,8 +614,7 @@ static PyMethodDef longrangeiter_methods[] = { }; static void -longrangeiter_dealloc(longrangeiterobject *r) -{ +longrangeiter_dealloc(longrangeiterobject *r) { Py_XDECREF(r->index); Py_XDECREF(r->start); Py_XDECREF(r->step); @@ -661,8 +623,7 @@ longrangeiter_dealloc(longrangeiterobject *r) } static PyObject * -longrangeiter_next(longrangeiterobject *r) -{ +longrangeiter_next(longrangeiterobject *r) { PyObject *one, *product, *new_index, *result; if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) return NULL; @@ -729,8 +690,7 @@ PyTypeObject PyLongRangeIter_Type = { }; static PyObject * -range_iter(PyObject *seq) -{ +range_iter(PyObject *seq) { rangeobject *r = (rangeobject *)seq; longrangeiterobject *it; long lstart, lstop, lstep; @@ -790,8 +750,7 @@ create_failure: } static PyObject * -range_reverse(PyObject *seq) -{ +range_reverse(PyObject *seq) { rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; PyObject *one, *sum, *diff, *len = NULL, *product; -- cgit v1.2.1 From 866eaecdaa81ddf2ad288a5db16ff2db9980edb3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 20 Nov 2010 23:05:39 +0000 Subject: pep 7 actually wants the brace on a new line --- Objects/rangeobject.c | 66 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 66d743fb9a..6ce0187adb 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -20,7 +20,8 @@ typedef struct { NULL on error. */ static PyObject * -validate_step(PyObject *step) { +validate_step(PyObject *step) +{ /* No step specified, use a step of 1. */ if (!step) return PyLong_FromLong(1); @@ -48,7 +49,8 @@ validate_step(PyObject *step) { range(0, 5, -1) */ static PyObject * -range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { +range_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ rangeobject *obj = NULL; PyObject *start = NULL, *stop = NULL, *step = NULL; @@ -116,7 +118,8 @@ PyDoc_STRVAR(range_doc, Returns an iterator that generates the numbers in the range on demand."); static void -range_dealloc(rangeobject *r) { +range_dealloc(rangeobject *r) +{ Py_DECREF(r->start); Py_DECREF(r->stop); Py_DECREF(r->step); @@ -128,7 +131,8 @@ range_dealloc(rangeobject *r) { * PyLong_Check(). Return NULL when there is an error. */ static PyObject* -range_length_obj(rangeobject *r) { +range_length_obj(rangeobject *r) +{ /* ------------------------------------------------------------- Algorithm is equal to that of get_len_of_range(), but it operates on PyObjects (which are assumed to be PyLong objects). @@ -200,7 +204,8 @@ range_length_obj(rangeobject *r) { } static Py_ssize_t -range_length(rangeobject *r) { +range_length(rangeobject *r) +{ PyObject *len = range_length_obj(r); Py_ssize_t result = -1; if (len) { @@ -213,7 +218,8 @@ range_length(rangeobject *r) { /* range(...)[x] is necessary for: seq[:] = range(...) */ static PyObject * -range_item(rangeobject *r, Py_ssize_t i) { +range_item(rangeobject *r, Py_ssize_t i) +{ Py_ssize_t len = range_length(r); PyObject *rem, *incr, *result; @@ -240,7 +246,8 @@ range_item(rangeobject *r, Py_ssize_t i) { } static PyObject * -range_repr(rangeobject *r) { +range_repr(rangeobject *r) +{ Py_ssize_t istep; /* Check for special case values for printing. We don't always @@ -260,14 +267,16 @@ range_repr(rangeobject *r) { /* Pickling support */ static PyObject * -range_reduce(rangeobject *r, PyObject *args) { +range_reduce(rangeobject *r, PyObject *args) +{ return Py_BuildValue("(O(OOO))", Py_TYPE(r), r->start, r->stop, r->step); } /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ static int -range_contains_long(rangeobject *r, PyObject *ob) { +range_contains_long(rangeobject *r, PyObject *ob) +{ int cmp1, cmp2, cmp3; PyObject *tmp1 = NULL; PyObject *tmp2 = NULL; @@ -316,7 +325,8 @@ range_contains_long(rangeobject *r, PyObject *ob) { } static int -range_contains(rangeobject *r, PyObject *ob) { +range_contains(rangeobject *r, PyObject *ob) +{ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) return range_contains_long(r, ob); @@ -325,7 +335,8 @@ range_contains(rangeobject *r, PyObject *ob) { } static PyObject * -range_count(rangeobject *r, PyObject *ob) { +range_count(rangeobject *r, PyObject *ob) +{ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) { int result = range_contains_long(r, ob); if (result == -1) @@ -344,7 +355,8 @@ range_count(rangeobject *r, PyObject *ob) { } static PyObject * -range_index(rangeobject *r, PyObject *ob) { +range_index(rangeobject *r, PyObject *ob) +{ int contains; if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) { @@ -463,7 +475,8 @@ typedef struct { } rangeiterobject; static PyObject * -rangeiter_next(rangeiterobject *r) { +rangeiter_next(rangeiterobject *r) +{ if (r->index < r->len) /* cast to unsigned to avoid possible signed overflow in intermediate calculations. */ @@ -473,7 +486,8 @@ rangeiter_next(rangeiterobject *r) { } static PyObject * -rangeiter_len(rangeiterobject *r) { +rangeiter_len(rangeiterobject *r) +{ return PyLong_FromLong(r->len - r->index); } @@ -486,7 +500,8 @@ typedef struct { } longrangeiterobject; static PyObject * -longrangeiter_len(longrangeiterobject *r, PyObject *no_args) { +longrangeiter_len(longrangeiterobject *r, PyObject *no_args) +{ return PyNumber_Subtract(r->len, r->index); } @@ -547,7 +562,8 @@ PyTypeObject PyRangeIter_Type = { * required. The result always fits in an unsigned long. */ static unsigned long -get_len_of_range(long lo, long hi, long step) { +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 @@ -574,7 +590,8 @@ get_len_of_range(long lo, long hi, long step) { is not representable as a C long, OverflowError is raised. */ static PyObject * -int_range_iter(long start, long stop, long step) { +int_range_iter(long start, long stop, long step) +{ rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); unsigned long ulen; if (it == NULL) @@ -594,7 +611,8 @@ int_range_iter(long start, long stop, long step) { } static PyObject * -rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) { +rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) +{ long start, stop, step; if (!_PyArg_NoKeywords("rangeiter()", kw)) @@ -614,7 +632,8 @@ static PyMethodDef longrangeiter_methods[] = { }; static void -longrangeiter_dealloc(longrangeiterobject *r) { +longrangeiter_dealloc(longrangeiterobject *r) +{ Py_XDECREF(r->index); Py_XDECREF(r->start); Py_XDECREF(r->step); @@ -623,7 +642,8 @@ longrangeiter_dealloc(longrangeiterobject *r) { } static PyObject * -longrangeiter_next(longrangeiterobject *r) { +longrangeiter_next(longrangeiterobject *r) +{ PyObject *one, *product, *new_index, *result; if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) return NULL; @@ -690,7 +710,8 @@ PyTypeObject PyLongRangeIter_Type = { }; static PyObject * -range_iter(PyObject *seq) { +range_iter(PyObject *seq) +{ rangeobject *r = (rangeobject *)seq; longrangeiterobject *it; long lstart, lstop, lstep; @@ -750,7 +771,8 @@ create_failure: } static PyObject * -range_reverse(PyObject *seq) { +range_reverse(PyObject *seq) +{ rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; PyObject *one, *sum, *diff, *len = NULL, *product; -- cgit v1.2.1 From 1bbe14e9ead6274abb61313705e5f90fe15aa5c5 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Thu, 25 Nov 2010 16:08:06 +0000 Subject: Issue #7094: Add alternate ('#') flag to __format__ methods for float, complex and Decimal. Allows greater control over when decimal points appear. Added to make transitioning from %-formatting easier. '#g' still has a problem with Decimal which I'll fix soon. --- Objects/stringlib/formatter.h | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 4fdab06229..4fdc62d650 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -941,13 +941,8 @@ format_float_internal(PyObject *value, from a hard-code pseudo-locale */ LocaleInfo locale; - /* Alternate is not allowed on floats. */ - if (format->alternate) { - PyErr_SetString(PyExc_ValueError, - "Alternate form (#) not allowed in float format " - "specifier"); - goto done; - } + if (format->alternate) + flags |= Py_DTSF_ALT; if (type == '\0') { /* Omitted type specifier. Behaves in the same way as repr(x) @@ -1104,15 +1099,7 @@ format_complex_internal(PyObject *value, from a hard-code pseudo-locale */ LocaleInfo locale; - /* 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. */ + /* Zero padding is not allowed. */ if (format->fill_char == '0') { PyErr_SetString(PyExc_ValueError, "Zero padding is not allowed in complex format " @@ -1135,6 +1122,9 @@ format_complex_internal(PyObject *value, if (im == -1.0 && PyErr_Occurred()) goto done; + if (format->alternate) + flags |= Py_DTSF_ALT; + if (type == '\0') { /* Omitted type specifier. Should be like str(self). */ type = 'r'; -- cgit v1.2.1 From 7bebe477a0f94c56a937dfeb2f5bc2d079151277 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 26 Nov 2010 10:54:09 +0000 Subject: Indentation cleanup. --- Objects/obmalloc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 274f720d3f..bbdc9469b3 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -249,7 +249,7 @@ typedef uchar block; /* Pool for small blocks. */ struct pool_header { union { block *_padding; - uint count; } ref; /* number of allocated blocks */ + 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 "" */ @@ -404,7 +404,7 @@ 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; + uint count; } ref; block *freeblock; each of which consume sizeof(block *) bytes. So what usedpools[i+i] really @@ -709,7 +709,7 @@ extremely desirable that it be this fast. #undef Py_ADDRESS_IN_RANGE #if defined(__GNUC__) && ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) || \ - (__GNUC__ >= 4)) + (__GNUC__ >= 4)) #define Py_NO_INLINE __attribute__((__noinline__)) #else #define Py_NO_INLINE @@ -1514,7 +1514,7 @@ _PyObject_DebugReallocApi(char api, void *p, size_t nbytes) if (nbytes > original_nbytes) { /* growing: mark new extra memory clean */ memset(q + original_nbytes, CLEANBYTE, - nbytes - original_nbytes); + nbytes - original_nbytes); } return q; @@ -1641,11 +1641,11 @@ _PyObject_DebugDumpAddress(const void *p) fputs("FORBIDDENBYTE, as expected.\n", stderr); else { fprintf(stderr, "not all FORBIDDENBYTE (0x%02x):\n", - FORBIDDENBYTE); + FORBIDDENBYTE); for (i = 0; i < SST; ++i) { const uchar byte = tail[i]; fprintf(stderr, " at tail+%d: 0x%02x", - i, byte); + i, byte); if (byte != FORBIDDENBYTE) fputs(" *** OUCH", stderr); fputc('\n', stderr); @@ -1751,7 +1751,7 @@ _PyObject_DebugMallocStats(void) char buf[128]; fprintf(stderr, "Small block threshold = %d, in %u size classes.\n", - SMALL_REQUEST_THRESHOLD, numclasses); + SMALL_REQUEST_THRESHOLD, numclasses); for (i = 0; i < numclasses; ++i) numpools[i] = numblocks[i] = numfreeblocks[i] = 0; @@ -1809,7 +1809,7 @@ _PyObject_DebugMallocStats(void) fputc('\n', stderr); fputs("class size num pools blocks in use avail blocks\n" "----- ---- --------- ------------- ------------\n", - stderr); + stderr); for (i = 0; i < numclasses; ++i) { size_t p = numpools[i]; @@ -1824,7 +1824,7 @@ _PyObject_DebugMallocStats(void) "%11" PY_FORMAT_SIZE_T "u " "%15" PY_FORMAT_SIZE_T "u " "%13" PY_FORMAT_SIZE_T "u\n", - i, size, p, b, f); + i, size, p, b, f); allocated_bytes += b * size; available_bytes += f * size; pool_header_bytes += p * POOL_OVERHEAD; -- cgit v1.2.1 From 6171159a9a7c63538f97307fc00e27618b326a1f Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 30 Nov 2010 09:30:54 +0000 Subject: Include structseq.h in Python.h, and remove now-redundant includes in individual sources. --- Objects/floatobject.c | 1 - Objects/longobject.c | 1 - Objects/structseq.c | 1 - 3 files changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d0173e8d13..4decb0b627 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -5,7 +5,6 @@ for any kind of float exception without losing portability. */ #include "Python.h" -#include "structseq.h" #include #include diff --git a/Objects/longobject.c b/Objects/longobject.c index b9ce38808f..e8a728489b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4,7 +4,6 @@ #include "Python.h" #include "longintrepr.h" -#include "structseq.h" #include #include diff --git a/Objects/structseq.c b/Objects/structseq.c index 52ff301ff6..75e2250bf9 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -3,7 +3,6 @@ #include "Python.h" #include "structmember.h" -#include "structseq.h" static char visible_length_key[] = "n_sequence_fields"; static char real_length_key[] = "n_fields"; -- cgit v1.2.1 From c16ad2eeb23a20667e832e09ad88e012952d8988 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 30 Nov 2010 09:41:01 +0000 Subject: Remove redundant includes of headers that are already included by Python.h. --- Objects/funcobject.c | 1 - Objects/genobject.c | 2 -- Objects/object.c | 1 - Objects/unicodectype.c | 1 - Objects/unicodeobject.c | 1 - 5 files changed, 6 deletions(-) (limited to 'Objects') diff --git a/Objects/funcobject.c b/Objects/funcobject.c index c2ad964e58..221f368ae2 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,7 +3,6 @@ #include "Python.h" #include "code.h" -#include "eval.h" #include "structmember.h" PyObject * diff --git a/Objects/genobject.c b/Objects/genobject.c index 34ee7dcc1f..3fa1b4e726 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -2,8 +2,6 @@ #include "Python.h" #include "frameobject.h" -#include "genobject.h" -#include "ceval.h" #include "structmember.h" #include "opcode.h" diff --git a/Objects/object.c b/Objects/object.c index 723e40eacb..082dd78e95 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2,7 +2,6 @@ /* Generic object operations; and implementation of None (NoObject) */ #include "Python.h" -#include "sliceobject.h" /* For PyEllipsis_Type */ #include "frameobject.h" #ifdef __cplusplus diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index a41ceb8240..9f6ac89b9f 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -9,7 +9,6 @@ */ #include "Python.h" -#include "unicodeobject.h" #define ALPHA_MASK 0x01 #define DECIMAL_MASK 0x02 diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d6cc8b5a24..89e3c8afb9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -43,7 +43,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "bytes_methods.h" -#include "unicodeobject.h" #include "ucnhash.h" #ifdef MS_WINDOWS -- cgit v1.2.1 From 128279a448d52fbf45bfd322fa03560a97a1997d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 30 Nov 2010 22:23:20 +0000 Subject: Issue #8685: Speed up set difference `a - b` when source set `a` is much larger than operand `b`. Patch by Andrew Bennetts. --- Objects/setobject.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index dfafefd057..478b5cb651 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1524,6 +1524,20 @@ set_difference_update(PySetObject *so, PyObject *args) PyDoc_STRVAR(difference_update_doc, "Remove all elements of another set from this set."); +static PyObject * +set_copy_and_difference(PySetObject *so, PyObject *other) +{ + PyObject *result; + + 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; +} + static PyObject * set_difference(PySetObject *so, PyObject *other) { @@ -1532,13 +1546,13 @@ set_difference(PySetObject *so, PyObject *other) 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; + return set_copy_and_difference(so, other); + } + + /* If len(so) much more than len(other), it's more efficient to simply copy + * so and then iterate other looking for common elements. */ + if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) { + return set_copy_and_difference(so, other); } result = make_new_set_basetype(Py_TYPE(so), NULL); @@ -1560,6 +1574,7 @@ set_difference(PySetObject *so, PyObject *other) return result; } + /* Iterate over so, checking for common elements in other. */ while (set_next(so, &pos, &entry)) { int rv = set_contains_entry((PySetObject *)other, entry); if (rv == -1) { -- cgit v1.2.1 From 10033aa0fd308d83c2c90a71951505f8e3134bea Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 2 Dec 2010 18:06:51 +0000 Subject: #7475: add (un)transform method to bytes/bytearray and str, add back codecs that can be used with them from Python 2. --- Objects/bytearrayobject.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ Objects/bytesobject.c | 64 +++++++++++++++++++++++++++++++++++++++++ Objects/unicodeobject.c | 46 ++++++++++++++++++++++++++++- 3 files changed, 182 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index f419eee955..6ca096afd7 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2488,6 +2488,75 @@ bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) return PyUnicode_FromEncodedObject(self, encoding, errors); } +PyDoc_STRVAR(transform__doc__, +"B.transform(encoding, errors='strict') -> bytearray\n\ +\n\ +Transform B using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +bytearray_transform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v, *w; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Encode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "encoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), + PyBytes_GET_SIZE(v)); + Py_DECREF(v); + return w; +} + + +PyDoc_STRVAR(untransform__doc__, +"B.untransform(encoding, errors='strict') -> bytearray\n\ +\n\ +Reverse-transform B using the codec registered for encoding. errors may\n\ +be given to set a different error handling scheme."); + +static PyObject * +bytearray_untransform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v, *w; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Decode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "decoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), + PyBytes_GET_SIZE(v)); + Py_DECREF(v); + return w; +} + PyDoc_STRVAR(alloc_doc, "B.__alloc__() -> int\n\ \n\ @@ -2782,8 +2851,12 @@ bytearray_methods[] = { {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"transform", (PyCFunction)bytearray_transform, METH_VARARGS | METH_KEYWORDS, + transform__doc__}, {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, + {"untransform", (PyCFunction)bytearray_untransform, METH_VARARGS | METH_KEYWORDS, + untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 96134a3a3f..d3b8a4fe80 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2312,6 +2312,68 @@ bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) return PyUnicode_FromEncodedObject(self, encoding, errors); } +PyDoc_STRVAR(transform__doc__, +"B.transform(encoding, errors='strict') -> bytes\n\ +\n\ +Transform B using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +bytes_transform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Encode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "encoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + return v; +} + + +PyDoc_STRVAR(untransform__doc__, +"B.untransform(encoding, errors='strict') -> bytes\n\ +\n\ +Reverse-transform B using the codec registered for encoding. errors may\n\ +be given to set a different error handling scheme."); + +static PyObject * +bytes_untransform(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding = NULL; + const char *errors = NULL; + static char *kwlist[] = {"encoding", "errors", 0}; + PyObject *v; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + + v = PyCodec_Decode(self, encoding, errors); + if (v == NULL) + return NULL; + if (!PyBytes_Check(v)) { + PyErr_Format(PyExc_TypeError, + "decoder did not return a bytes object (type=%.400s)", + Py_TYPE(v)->tp_name); + Py_DECREF(v); + return NULL; + } + return v; +} PyDoc_STRVAR(splitlines__doc__, "B.splitlines([keepends]) -> list of lines\n\ @@ -2475,8 +2537,10 @@ bytes_methods[] = { {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, + {"transform", (PyCFunction)bytes_transform, METH_VARARGS | METH_KEYWORDS, transform__doc__}, {"translate", (PyCFunction)bytes_translate, METH_VARARGS, translate__doc__}, + {"untransform", (PyCFunction)bytes_untransform, METH_VARARGS | METH_KEYWORDS, untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 89e3c8afb9..fd508825ff 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7432,6 +7432,7 @@ unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); if (v == NULL) goto onError; + /* XXX this check is redundant */ if (!PyBytes_Check(v)) { PyErr_Format(PyExc_TypeError, "encoder did not return a bytes object " @@ -7446,6 +7447,44 @@ unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) return NULL; } +PyDoc_STRVAR(transform__doc__, + "S.transform(encoding, errors='strict') -> str\n\ +\n\ +Transform S using the codec registered for encoding. errors may be given\n\ +to set a different error handling scheme."); + +static PyObject * +unicode_transform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", + kwlist, &encoding, &errors)) + return NULL; + return PyUnicode_AsEncodedUnicode((PyObject *)self, encoding, errors); +} + +PyDoc_STRVAR(untransform__doc__, + "S.untransform(encoding, errors='strict') -> str\n\ +\n\ +Reverse-transform S using the codec registered for encoding. errors may be\n\ +given to set a different error handling scheme."); + +static PyObject * +unicode_untransform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"encoding", "errors", 0}; + char *encoding = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", + kwlist, &encoding, &errors)) + return NULL; + return PyUnicode_AsDecodedUnicode((PyObject *)self, encoding, errors); +} + PyDoc_STRVAR(expandtabs__doc__, "S.expandtabs([tabsize]) -> str\n\ \n\ @@ -9091,7 +9130,8 @@ static PyMethodDef unicode_methods[] = { /* Order is according to common usage: often used methods should appear first, since lookup is done sequentially. */ - {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__}, + {"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__}, @@ -9136,6 +9176,10 @@ static PyMethodDef unicode_methods[] = { {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, + {"transform", (PyCFunction) unicode_transform, METH_VARARGS | METH_KEYWORDS, + transform__doc__}, + {"untransform", (PyCFunction) unicode_untransform, METH_VARARGS | METH_KEYWORDS, + untransform__doc__}, {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__}, #if 0 {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__}, -- cgit v1.2.1 From dab9d54bcb197590db08ee1d7412d06c8627d8b8 Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Thu, 2 Dec 2010 21:55:33 +0000 Subject: Issue9915: speeding up sorting with a key --- Objects/listobject.c | 463 ++++++++++++++++++++++++++------------------------- 1 file changed, 238 insertions(+), 225 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 0f4552510a..eafa98c308 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -940,6 +940,66 @@ reverse_slice(PyObject **lo, PyObject **hi) * pieces to this algorithm; read listsort.txt for overviews and details. */ +/* A sortslice contains a pointer to an array of keys and a pointer to + * an array of corresponding values. In other words, keys[i] + * corresponds with values[i]. If values == NULL, then the keys are + * also the values. + * + * Several convenience routines are provided here, so that keys and + * values are always moved in sync. + */ + +typedef struct { + PyObject **keys; + PyObject **values; +} sortslice; + +Py_LOCAL_INLINE(void) +sortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j) +{ + s1->keys[i] = s2->keys[j]; + if (s1->values != NULL) + s1->values[i] = s2->values[j]; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_incr(sortslice *dst, sortslice *src) { + *dst->keys++ = *src->keys++; + if (dst->values != NULL) + *dst->values++ = *src->values++; +} + +Py_LOCAL_INLINE(void) +sortslice_copy_decr(sortslice *dst, sortslice *src) { + *dst->keys-- = *src->keys--; + if (dst->values != NULL) + *dst->values-- = *src->values--; +} + + +Py_LOCAL_INLINE(void) +sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) { + memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, + Py_ssize_t n) { + memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); + if (s1->values != NULL) + memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); +} + +Py_LOCAL_INLINE(void) +sortslice_advance(sortslice *slice, Py_ssize_t n) { + slice->keys += n; + if (slice->values != NULL) + slice->values += n; +} + /* Comparison function: PyObject_RichCompareBool with Py_LT. * Returns -1 on error, 1 if x < y, 0 if x >= y. */ @@ -965,19 +1025,19 @@ reverse_slice(PyObject **lo, PyObject **hi) the input (nothing is lost or duplicated). */ static int -binarysort(PyObject **lo, PyObject **hi, PyObject **start) +binarysort(sortslice lo, PyObject **hi, PyObject **start) { register Py_ssize_t k; register PyObject **l, **p, **r; register PyObject *pivot; - assert(lo <= start && start <= hi); + assert(lo.keys <= start && start <= hi); /* assert [lo, start) is sorted */ - if (lo == start) + if (lo.keys == start) ++start; for (; start < hi; ++start) { /* set l to where *start belongs */ - l = lo; + l = lo.keys; r = start; pivot = *r; /* Invariants: @@ -1004,6 +1064,15 @@ binarysort(PyObject **lo, PyObject **hi, PyObject **start) for (p = start; p > l; --p) *p = *(p-1); *l = pivot; + if (lo.values != NULL) { + Py_ssize_t offset = lo.values - lo.keys; + p = start + offset; + pivot = *p; + l += offset; + for (p = start + offset; p > l; --p) + *p = *(p-1); + *l = pivot; + } } return 0; @@ -1272,7 +1341,7 @@ fail: * a convenient way to pass state around among the helper functions. */ struct s_slice { - PyObject **base; + sortslice base; Py_ssize_t len; }; @@ -1286,7 +1355,7 @@ typedef struct s_MergeState { /* 'a' is temp storage to help with merges. It contains room for * alloced entries. */ - PyObject **a; /* may point to temparray below */ + sortslice a; /* may point to temparray below */ Py_ssize_t alloced; /* A stack of n pending runs yet to be merged. Run #i starts at @@ -1307,11 +1376,29 @@ typedef struct s_MergeState { /* Conceptually a MergeState's constructor. */ static void -merge_init(MergeState *ms) +merge_init(MergeState *ms, int list_size, int has_keyfunc) { assert(ms != NULL); - ms->a = ms->temparray; - ms->alloced = MERGESTATE_TEMP_SIZE; + if (has_keyfunc) { + /* The temporary space for merging will need at most half the list + * size rounded up. Use the minimum possible space so we can use the + * rest of temparray for other things. In particular, if there is + * enough extra space, listsort() will use it to store the keys. + */ + ms->alloced = (list_size + 1) / 2; + + /* ms->alloced describes how many keys will be stored at + ms->temparray, but we also need to store the values. Hence, + ms->alloced is capped at half of MERGESTATE_TEMP_SIZE. */ + if (MERGESTATE_TEMP_SIZE / 2 < ms->alloced) + ms->alloced = MERGESTATE_TEMP_SIZE / 2; + ms->a.values = &ms->temparray[ms->alloced]; + } + else { + ms->alloced = MERGESTATE_TEMP_SIZE; + ms->a.values = NULL; + } + ms->a.keys = ms->temparray; ms->n = 0; ms->min_gallop = MIN_GALLOP; } @@ -1324,10 +1411,8 @@ 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; + if (ms->a.keys != ms->temparray) + PyMem_Free(ms->a.keys); } /* Ensure enough temp memory for 'need' array slots is available. @@ -1336,52 +1421,60 @@ merge_freemem(MergeState *ms) static int merge_getmem(MergeState *ms, Py_ssize_t need) { + int multiplier; + assert(ms != NULL); if (need <= ms->alloced) return 0; + + multiplier = ms->a.values != NULL ? 2 : 1; + /* 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*)) { + if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*) / multiplier) { PyErr_NoMemory(); return -1; } - ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*)); - if (ms->a) { + ms->a.keys = (PyObject**)PyMem_Malloc(multiplier * need + * sizeof(PyObject *)); + if (ms->a.keys != NULL) { ms->alloced = need; + if (ms->a.values != NULL) + ms->a.values = &ms->a.keys[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. +/* Merge the na elements starting at ssa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[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) +merge_lo(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) { Py_ssize_t k; - PyObject **dest; + sortslice dest; int result = -1; /* guilty until proved innocent */ Py_ssize_t min_gallop; - assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb); + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); if (MERGE_GETMEM(ms, na) < 0) return -1; - memcpy(ms->a, pa, na * sizeof(PyObject*)); - dest = pa; - pa = ms->a; + sortslice_memcpy(&ms->a, 0, &ssa, 0, na); + dest = ssa; + ssa = ms->a; - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); --nb; if (nb == 0) goto Succeed; @@ -1398,11 +1491,11 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, */ for (;;) { assert(na > 1 && nb > 0); - k = ISLT(*pb, *pa); + k = ISLT(ssb.keys[0], ssa.keys[0]); if (k) { if (k < 0) goto Fail; - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); ++bcount; acount = 0; --nb; @@ -1412,7 +1505,7 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, break; } else { - *dest++ = *pa++; + sortslice_copy_incr(&dest, &ssa); ++acount; bcount = 0; --na; @@ -1433,14 +1526,14 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, assert(na > 1 && nb > 0); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, pa, na, 0); + k = gallop_right(ssb.keys[0], ssa.keys, na, 0); acount = k; if (k) { if (k < 0) goto Fail; - memcpy(dest, pa, k * sizeof(PyObject *)); - dest += k; - pa += k; + sortslice_memcpy(&dest, 0, &ssa, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssa, k); na -= k; if (na == 1) goto CopyB; @@ -1451,24 +1544,24 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, if (na == 0) goto Succeed; } - *dest++ = *pb++; + sortslice_copy_incr(&dest, &ssb); --nb; if (nb == 0) goto Succeed; - k = gallop_left(*pa, pb, nb, 0); + k = gallop_left(ssa.keys[0], ssb.keys, nb, 0); bcount = k; if (k) { if (k < 0) goto Fail; - memmove(dest, pb, k * sizeof(PyObject *)); - dest += k; - pb += k; + sortslice_memmove(&dest, 0, &ssb, 0, k); + sortslice_advance(&dest, k); + sortslice_advance(&ssb, k); nb -= k; if (nb == 0) goto Succeed; } - *dest++ = *pa++; + sortslice_copy_incr(&dest, &ssa); --na; if (na == 1) goto CopyB; @@ -1480,43 +1573,46 @@ Succeed: result = 0; Fail: if (na) - memcpy(dest, pa, na * sizeof(PyObject*)); + sortslice_memcpy(&dest, 0, &ssa, 0, na); 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; + /* The last element of ssa belongs at the end of the merge. */ + sortslice_memmove(&dest, 0, &ssb, 0, nb); + sortslice_copy(&dest, nb, &ssa, 0); 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. +/* Merge the na elements starting at pa with the nb elements starting at + * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0. + * Must also have that ssa.keys[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) +merge_hi(MergeState *ms, sortslice ssa, Py_ssize_t na, + sortslice ssb, Py_ssize_t nb) { Py_ssize_t k; - PyObject **dest; + sortslice dest, basea, baseb; 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); + assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0); + assert(ssa.keys + na == ssb.keys); if (MERGE_GETMEM(ms, nb) < 0) return -1; - dest = pb + nb - 1; - memcpy(ms->a, pb, nb * sizeof(PyObject*)); - basea = pa; + dest = ssb; + sortslice_advance(&dest, nb-1); + sortslice_memcpy(&ms->a, 0, &ssb, 0, nb); + basea = ssa; baseb = ms->a; - pb = ms->a + nb - 1; - pa += na - 1; + ssb.keys = ms->a.keys + nb - 1; + if (ssb.values != NULL) + ssb.values = ms->a.values + nb - 1; + sortslice_advance(&ssa, na - 1); - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); --na; if (na == 0) goto Succeed; @@ -1533,11 +1629,11 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t */ for (;;) { assert(na > 0 && nb > 1); - k = ISLT(*pb, *pa); + k = ISLT(ssb.keys[0], ssa.keys[0]); if (k) { if (k < 0) goto Fail; - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); ++acount; bcount = 0; --na; @@ -1547,7 +1643,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t break; } else { - *dest-- = *pb--; + sortslice_copy_decr(&dest, &ssb); ++bcount; acount = 0; --nb; @@ -1568,33 +1664,33 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t assert(na > 0 && nb > 1); min_gallop -= min_gallop > 1; ms->min_gallop = min_gallop; - k = gallop_right(*pb, basea, na, na-1); + k = gallop_right(ssb.keys[0], basea.keys, na, na-1); if (k < 0) goto Fail; k = na - k; acount = k; if (k) { - dest -= k; - pa -= k; - memmove(dest+1, pa+1, k * sizeof(PyObject *)); + sortslice_advance(&dest, -k); + sortslice_advance(&ssa, -k); + sortslice_memmove(&dest, 1, &ssa, 1, k); na -= k; if (na == 0) goto Succeed; } - *dest-- = *pb--; + sortslice_copy_decr(&dest, &ssb); --nb; if (nb == 1) goto CopyA; - k = gallop_left(*pa, baseb, nb, nb-1); + k = gallop_left(ssa.keys[0], baseb.keys, nb, nb-1); if (k < 0) goto Fail; k = nb - k; bcount = k; if (k) { - dest -= k; - pb -= k; - memcpy(dest+1, pb+1, k * sizeof(PyObject *)); + sortslice_advance(&dest, -k); + sortslice_advance(&ssb, -k); + sortslice_memcpy(&dest, 1, &ssb, 1, k); nb -= k; if (nb == 1) goto CopyA; @@ -1605,7 +1701,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t if (nb == 0) goto Succeed; } - *dest-- = *pa--; + sortslice_copy_decr(&dest, &ssa); --na; if (na == 0) goto Succeed; @@ -1617,15 +1713,15 @@ Succeed: result = 0; Fail: if (nb) - memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*)); + sortslice_memcpy(&dest, -(nb-1), &baseb, 0, nb); 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; + /* The first element of ssb belongs at the front of the merge. */ + sortslice_memmove(&dest, 1-na, &ssa, 1-na, na); + sortslice_advance(&dest, -na); + sortslice_advance(&ssa, -na); + sortslice_copy(&dest, 0, &ssb, 0); return 0; } @@ -1635,7 +1731,7 @@ CopyA: static Py_ssize_t merge_at(MergeState *ms, Py_ssize_t i) { - PyObject **pa, **pb; + sortslice ssa, ssb; Py_ssize_t na, nb; Py_ssize_t k; @@ -1644,12 +1740,12 @@ merge_at(MergeState *ms, Py_ssize_t i) assert(i >= 0); assert(i == ms->n - 2 || i == ms->n - 3); - pa = ms->pending[i].base; + ssa = ms->pending[i].base; na = ms->pending[i].len; - pb = ms->pending[i+1].base; + ssb = ms->pending[i+1].base; nb = ms->pending[i+1].len; assert(na > 0 && nb > 0); - assert(pa + na == pb); + assert(ssa.keys + na == ssb.keys); /* 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 @@ -1663,10 +1759,10 @@ merge_at(MergeState *ms, Py_ssize_t i) /* Where does b start in a? Elements in a before that can be * ignored (already in place). */ - k = gallop_right(*pb, pa, na, 0); + k = gallop_right(*ssb.keys, ssa.keys, na, 0); if (k < 0) return -1; - pa += k; + sortslice_advance(&ssa, k); na -= k; if (na == 0) return 0; @@ -1674,7 +1770,7 @@ merge_at(MergeState *ms, Py_ssize_t i) /* 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); + nb = gallop_left(ssa.keys[na-1], ssb.keys, nb, nb-1); if (nb <= 0) return nb; @@ -1682,9 +1778,9 @@ merge_at(MergeState *ms, Py_ssize_t i) * min(na, nb) elements. */ if (na <= nb) - return merge_lo(ms, pa, na, pb, nb); + return merge_lo(ms, ssa, na, ssb, nb); else - return merge_hi(ms, pa, na, pb, nb); + return merge_hi(ms, ssa, na, ssb, nb); } /* Examine the stack of runs waiting to be merged, merging adjacent runs @@ -1765,103 +1861,12 @@ merge_compute_minrun(Py_ssize_t n) 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, the comparison function 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 *); - -PyTypeObject PySortWrapper_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_reserved */ - 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 */ - 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, &PySortWrapper_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) +reverse_sortslice(sortslice *s, Py_ssize_t n) { - sortwrapperobject *so; - - so = PyObject_New(sortwrapperobject, &PySortWrapper_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, &PySortWrapper_Type)) { - PyErr_SetString(PyExc_TypeError, - "expected a sortwrapperobject"); - return NULL; - } - value = ((sortwrapperobject *)so)->value; - Py_INCREF(value); - return value; + reverse_slice(s->keys, &s->keys[n]); + if (s->values != NULL) + reverse_slice(s->values, &s->values[n]); } /* An adaptive, stable, natural mergesort. See listsort.txt. @@ -1873,9 +1878,9 @@ static PyObject * listsort(PyListObject *self, PyObject *args, PyObject *kwds) { MergeState ms; - PyObject **lo, **hi; Py_ssize_t nremaining; Py_ssize_t minrun; + sortslice lo; Py_ssize_t saved_ob_size, saved_allocated; PyObject **saved_ob_item; PyObject **final_ob_item; @@ -1883,8 +1888,8 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) int reverse = 0; PyObject *keyfunc = NULL; Py_ssize_t i; - PyObject *key, *value, *kvpair; static char *kwlist[] = {"key", "reverse", 0}; + PyObject **keys; assert(self != NULL); assert (PyList_Check(self)); @@ -1913,28 +1918,36 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) 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; + if (keyfunc == NULL) { + keys = NULL; + lo.keys = saved_ob_item; + lo.values = NULL; + } + else { + if (saved_ob_size < MERGESTATE_TEMP_SIZE/2) + /* Leverage stack space we allocated but won't otherwise use */ + keys = &ms.temparray[saved_ob_size+1]; + else { + keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); + if (keys == NULL) + return NULL; + } + + for (i = 0; i < saved_ob_size ; i++) { + keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i], + NULL); + if (keys[i] == NULL) { + for (i=i-1 ; i>=0 ; i--) + Py_DECREF(keys[i]); + goto keyfunc_fail; } - kvpair = build_sortwrapper(key, value); - if (kvpair == NULL) - goto dsu_fail; - saved_ob_item[i] = kvpair; } + + lo.keys = keys; + lo.values = saved_ob_item; } - merge_init(&ms); + merge_init(&ms, saved_ob_size, keys != NULL); nremaining = saved_ob_size; if (nremaining < 2) @@ -1942,30 +1955,31 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) /* Reverse sort stability achieved by initially reversing the list, applying a stable forward sort, then reversing the final result. */ - if (reverse) - reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size); + if (reverse) { + if (keys != NULL) + reverse_slice(&keys[0], &keys[saved_ob_size]); + reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]); + } /* 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, &descending); + n = count_run(lo.keys, lo.keys + nremaining, &descending); if (n < 0) goto fail; if (descending) - reverse_slice(lo, lo + n); + reverse_sortslice(&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) < 0) + if (binarysort(lo, lo.keys + force, lo.keys + n) < 0) goto fail; n = force; } @@ -1977,27 +1991,27 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (merge_collapse(&ms) < 0) goto fail; /* Advance to find next run. */ - lo += n; + sortslice_advance(&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(keys == NULL + ? ms.pending[0].base.keys == saved_ob_item + : ms.pending[0].base.keys == &keys[0]); assert(ms.pending[0].len == saved_ob_size); + lo = ms.pending[0].base; 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 (keys != NULL) { + for (i = 0; i < saved_ob_size; i++) + Py_DECREF(keys[i]); + if (keys != &ms.temparray[saved_ob_size+1]) + PyMem_FREE(keys); } if (self->allocated != -1 && result != NULL) { @@ -2013,7 +2027,7 @@ fail: merge_freemem(&ms); -dsu_fail: +keyfunc_fail: final_ob_item = self->ob_item; i = Py_SIZE(self); Py_SIZE(self) = saved_ob_size; @@ -2862,4 +2876,3 @@ listreviter_len(listreviterobject *it) len = 0; return PyLong_FromSsize_t(len); } - -- cgit v1.2.1 From 6449c008b9686445974f3363b7c400e80f984652 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 3 Dec 2010 01:44:10 +0000 Subject: code style --- Objects/listobject.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index eafa98c308..fbc05fda4a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -963,14 +963,16 @@ sortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j) } Py_LOCAL_INLINE(void) -sortslice_copy_incr(sortslice *dst, sortslice *src) { +sortslice_copy_incr(sortslice *dst, sortslice *src) +{ *dst->keys++ = *src->keys++; if (dst->values != NULL) *dst->values++ = *src->values++; } Py_LOCAL_INLINE(void) -sortslice_copy_decr(sortslice *dst, sortslice *src) { +sortslice_copy_decr(sortslice *dst, sortslice *src) +{ *dst->keys-- = *src->keys--; if (dst->values != NULL) *dst->values-- = *src->values--; @@ -979,7 +981,8 @@ sortslice_copy_decr(sortslice *dst, sortslice *src) { Py_LOCAL_INLINE(void) sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, - Py_ssize_t n) { + Py_ssize_t n) +{ memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); if (s1->values != NULL) memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); @@ -987,14 +990,16 @@ sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, Py_LOCAL_INLINE(void) sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j, - Py_ssize_t n) { + Py_ssize_t n) +{ memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n); if (s1->values != NULL) memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n); } Py_LOCAL_INLINE(void) -sortslice_advance(sortslice *slice, Py_ssize_t n) { +sortslice_advance(sortslice *slice, Py_ssize_t n) +{ slice->keys += n; if (slice->values != NULL) slice->values += n; -- cgit v1.2.1 From 6fc26dc29ed38412914ef08a701ec6a12d4d2455 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 3 Dec 2010 07:54:09 +0000 Subject: Remove redundant check for PyBytes in unicode_encode. --- Objects/unicodeobject.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fd508825ff..f66773e26a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7424,27 +7424,11 @@ 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_AsEncodedString((PyObject *)self, encoding, errors); - if (v == NULL) - goto onError; - /* XXX this check is redundant */ - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a bytes object " - "(type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - return v; - - onError: - return NULL; + return PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); } PyDoc_STRVAR(transform__doc__, -- cgit v1.2.1 From dbfa00369f96e871f193e89e4d0722bd8c112728 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Fri, 3 Dec 2010 14:26:13 +0000 Subject: Issue 2690: Add support for slicing and negative indices to range objects (includes precalculation and storage of the range length). Refer to the tracker issue for the language moratorium implications of this change --- Objects/rangeobject.c | 284 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 184 insertions(+), 100 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 6ce0187adb..bf42b1e321 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -14,6 +14,7 @@ typedef struct { PyObject *start; PyObject *stop; PyObject *step; + PyObject *length; } rangeobject; /* Helper function for validating step. Always returns a new reference or @@ -43,6 +44,31 @@ validate_step(PyObject *step) return step; } +static PyObject * +compute_range_length(PyObject *start, PyObject *stop, PyObject *step); + +static rangeobject * +make_range_object(PyTypeObject *type, PyObject *start, + PyObject *stop, PyObject *step) +{ + rangeobject *obj = NULL; + PyObject *length; + length = compute_range_length(start, stop, step); + if (length == NULL) { + return NULL; + } + obj = PyObject_New(rangeobject, type); + if (obj == NULL) { + Py_DECREF(length); + return NULL; + } + obj->start = start; + obj->stop = stop; + obj->step = step; + obj->length = length; + return obj; +} + /* XXX(nnorwitz): should we error check if the user passes any empty ranges? range(-10) range(0, -5) @@ -51,7 +77,7 @@ validate_step(PyObject *step) static PyObject * range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - rangeobject *obj = NULL; + rangeobject *obj; PyObject *start = NULL, *stop = NULL, *step = NULL; if (!_PyArg_NoKeywords("range()", kw)) @@ -97,15 +123,11 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw) } } - obj = PyObject_New(rangeobject, &PyRange_Type); - if (obj == NULL) - goto Fail; - obj->start = start; - obj->stop = stop; - obj->step = step; - return (PyObject *) obj; + obj = make_range_object(type, start, stop, step); + if (obj != NULL) + return (PyObject *) obj; -Fail: + /* Failed to create object, release attributes */ Py_XDECREF(start); Py_XDECREF(stop); Py_XDECREF(step); @@ -115,7 +137,7 @@ Fail: PyDoc_STRVAR(range_doc, "range([start,] stop[, step]) -> range object\n\ \n\ -Returns an iterator that generates the numbers in the range on demand."); +Returns a virtual sequence of numbers from start to stop by step."); static void range_dealloc(rangeobject *r) @@ -123,6 +145,7 @@ range_dealloc(rangeobject *r) Py_DECREF(r->start); Py_DECREF(r->stop); Py_DECREF(r->step); + Py_DECREF(r->length); PyObject_Del(r); } @@ -131,7 +154,7 @@ range_dealloc(rangeobject *r) * PyLong_Check(). Return NULL when there is an error. */ static PyObject* -range_length_obj(rangeobject *r) +compute_range_length(PyObject *start, PyObject *stop, PyObject *step) { /* ------------------------------------------------------------- Algorithm is equal to that of get_len_of_range(), but it operates @@ -139,7 +162,6 @@ range_length_obj(rangeobject *r) ---------------------------------------------------------------*/ int cmp_result; PyObject *lo, *hi; - PyObject *step = NULL; PyObject *diff = NULL; PyObject *one = NULL; PyObject *tmp1 = NULL, *tmp2 = NULL, *result; @@ -148,20 +170,19 @@ range_length_obj(rangeobject *r) PyObject *zero = PyLong_FromLong(0); if (zero == NULL) return NULL; - cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT); + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); Py_DECREF(zero); if (cmp_result == -1) return NULL; if (cmp_result == 1) { - lo = r->start; - hi = r->stop; - step = r->step; + lo = start; + hi = stop; Py_INCREF(step); } else { - lo = r->stop; - hi = r->start; - step = PyNumber_Negative(r->step); + lo = stop; + hi = start; + step = PyNumber_Negative(step); if (!step) return NULL; } @@ -206,32 +227,15 @@ range_length_obj(rangeobject *r) static Py_ssize_t range_length(rangeobject *r) { - PyObject *len = range_length_obj(r); - Py_ssize_t result = -1; - if (len) { - result = PyLong_AsSsize_t(len); - Py_DECREF(len); - } - return result; + return PyLong_AsSsize_t(r->length); } /* range(...)[x] is necessary for: seq[:] = range(...) */ - static PyObject * -range_item(rangeobject *r, Py_ssize_t i) +compute_range_item(rangeobject *r, Py_ssize_t i) { - Py_ssize_t len = range_length(r); PyObject *rem, *incr, *result; - /* XXX(nnorwitz): should negative indices be supported? */ - /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */ - if (i < 0 || i >= len) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_IndexError, - "range object index out of range"); - return NULL; - } - /* XXX(nnorwitz): optimize for short ints. */ rem = PyLong_FromSsize_t(i); if (!rem) @@ -246,31 +250,22 @@ range_item(rangeobject *r, Py_ssize_t i) } static PyObject * -range_repr(rangeobject *r) +range_item(rangeobject *r, Py_ssize_t i) { - Py_ssize_t istep; - - /* Check for special case values for printing. We don't always - need the step value. We don't care about errors - (it means overflow), so clear the errors. */ - istep = PyNumber_AsSsize_t(r->step, NULL); - if (istep != 1 || (istep == -1 && PyErr_Occurred())) { - PyErr_Clear(); - } + /* XXX(nnorwitz): should we support range[x] where x > PY_SSIZE_T_MAX? */ + Py_ssize_t len = range_length(r); - if (istep == 1) - return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); - else - return PyUnicode_FromFormat("range(%R, %R, %R)", - r->start, r->stop, r->step); -} + if (i < 0) + i += len; -/* Pickling support */ -static PyObject * -range_reduce(rangeobject *r, PyObject *args) -{ - return Py_BuildValue("(O(OOO))", Py_TYPE(r), - r->start, r->stop, r->step); + if (i < 0 || i >= len) { + /* Also handles case where len < 0 due to (e.g) OverflowError */ + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_IndexError, + "range object index out of range"); + return NULL; + } + return compute_range_item(r, i); } /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ @@ -388,15 +383,111 @@ range_index(rangeobject *r, PyObject *ob) static PySequenceMethods range_as_sequence = { (lenfunc)range_length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)range_item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)range_item, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ (objobjproc)range_contains, /* sq_contains */ }; +static PyObject * +range_repr(rangeobject *r) +{ + Py_ssize_t istep; + + /* Check for special case values for printing. We don't always + need the step value. We don't care about errors + (it means overflow), so clear the errors. */ + istep = PyNumber_AsSsize_t(r->step, NULL); + if (istep != 1 || (istep == -1 && PyErr_Occurred())) { + PyErr_Clear(); + } + + if (istep == 1) + return PyUnicode_FromFormat("range(%R, %R)", r->start, r->stop); + else + return PyUnicode_FromFormat("range(%R, %R, %R)", + r->start, r->stop, r->step); +} + +/* Pickling support */ +static PyObject * +range_reduce(rangeobject *r, PyObject *args) +{ + return Py_BuildValue("(O(OOO))", Py_TYPE(r), + r->start, r->stop, r->step); +} + +static PyObject * +range_subscript(rangeobject* 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; + return range_item(self, i); + } + if (PySlice_Check(item)) { + PySliceObject *slice = (PySliceObject*)item; + Py_ssize_t start, stop, step, len, rlen; + rangeobject *result; + PyObject *substart = NULL, *substep = NULL, *substop = NULL; + + rlen = range_length(self); + if (rlen < 0) { + return NULL; + } + + if (PySlice_GetIndicesEx(slice, rlen, + &start, &stop, &step, &len) < 0) { + return NULL; + } + if (step == 1) { + substep = self->step; + Py_INCREF(substep); + } else { + /* NB: slice step != Py_None here */ + substep = PyNumber_Multiply(self->step, slice->step); + if (substep == NULL) + goto fail; + } + substart = compute_range_item(self, start); + if (substart == NULL) + goto fail; + if (len <= 0) { + substop = substart; + Py_INCREF(substop); + } + else { + substop = compute_range_item(self, stop); + if (substop == NULL) + goto fail; + } + result = make_range_object(Py_TYPE(self), substart, substop, substep); + if (result != NULL) + return (PyObject *) result; + fail: + Py_XDECREF(substart); + Py_XDECREF(substep); + Py_XDECREF(substop); + return NULL; + } + PyErr_Format(PyExc_TypeError, + "range indices must be integers or slices, not %.200s", + item->ob_type->tp_name); + return NULL; +} + + +static PyMappingMethods range_as_mapping = { + (lenfunc)range_length, /* mp_length */ + (binaryfunc)range_subscript, /* mp_subscript */ + (objobjargproc)0, /* mp_ass_subscript */ +}; + static PyObject * range_iter(PyObject *seq); static PyObject * range_reverse(PyObject *seq); @@ -431,7 +522,7 @@ PyTypeObject PyRange_Type = { (reprfunc)range_repr, /* tp_repr */ 0, /* tp_as_number */ &range_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ + &range_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ @@ -491,22 +582,6 @@ rangeiter_len(rangeiterobject *r) return PyLong_FromLong(r->len - r->index); } -typedef struct { - PyObject_HEAD - PyObject *index; - PyObject *start; - PyObject *step; - PyObject *len; -} longrangeiterobject; - -static PyObject * -longrangeiter_len(longrangeiterobject *r, PyObject *no_args) -{ - return PyNumber_Subtract(r->len, r->index); -} - -static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); - PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); @@ -516,6 +591,8 @@ static PyMethodDef rangeiter_methods[] = { {NULL, NULL} /* sentinel */ }; +static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); + PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "range_iterator", /* tp_name */ @@ -590,7 +667,7 @@ get_len_of_range(long lo, long hi, long step) is not representable as a C long, OverflowError is raised. */ static PyObject * -int_range_iter(long start, long stop, long step) +fast_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); unsigned long ulen; @@ -622,7 +699,21 @@ rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) &start, &stop, &step)) return NULL; - return int_range_iter(start, stop, step); + return fast_range_iter(start, stop, step); +} + +typedef struct { + PyObject_HEAD + PyObject *index; + PyObject *start; + PyObject *step; + PyObject *len; +} longrangeiterobject; + +static PyObject * +longrangeiter_len(longrangeiterobject *r, PyObject *no_args) +{ + return PyNumber_Subtract(r->len, r->index); } static PyMethodDef longrangeiter_methods[] = { @@ -736,7 +827,7 @@ range_iter(PyObject *seq) PyErr_Clear(); goto long_range; } - int_it = int_range_iter(lstart, lstop, lstep); + int_it = fast_range_iter(lstart, lstop, lstep); if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); goto long_range; @@ -751,14 +842,11 @@ range_iter(PyObject *seq) /* Do all initialization here, so we can DECREF on failure. */ it->start = r->start; it->step = r->step; + it->len = r->length; Py_INCREF(it->start); Py_INCREF(it->step); + Py_INCREF(it->len); - it->len = it->index = NULL; - - it->len = range_length_obj(r); - if (!it->len) - goto create_failure; it->index = PyLong_FromLong(0); if (!it->index) goto create_failure; @@ -775,7 +863,7 @@ range_reverse(PyObject *seq) { rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; - PyObject *one, *sum, *diff, *len = NULL, *product; + PyObject *one, *sum, *diff, *product; long lstart, lstop, lstep, new_start, new_stop; unsigned long ulen; @@ -838,7 +926,7 @@ range_reverse(PyObject *seq) new_stop = lstart - lstep; new_start = (long)(new_stop + ulen * lstep); - return int_range_iter(new_start, new_stop, -lstep); + return fast_range_iter(new_start, new_stop, -lstep); long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); @@ -846,18 +934,14 @@ long_range: return NULL; /* start + (len - 1) * step */ - len = range_length_obj(range); - if (!len) - goto create_failure; - - /* Steal reference to len. */ - it->len = len; + it->len = range->length; + Py_INCREF(it->len); one = PyLong_FromLong(1); if (!one) goto create_failure; - diff = PyNumber_Subtract(len, one); + diff = PyNumber_Subtract(it->len, one); Py_DECREF(one); if (!diff) goto create_failure; -- cgit v1.2.1 From 393bd6611b784da04a68998f0356c6ddbd5f1862 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 3 Dec 2010 16:51:33 +0000 Subject: #6780: fix complex() constructor TypeError message --- Objects/complexobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index c47e0d3661..59997962ce 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -783,7 +783,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, - "complex() arg is not a string"); + "complex() argument must be a string or a number"); return NULL; } -- cgit v1.2.1 From bbbb00332d45ae20db0b9032efcb3bf397e2df3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Fri, 3 Dec 2010 20:14:31 +0000 Subject: Merge branches/pep-0384. --- Objects/bytearrayobject.c | 4 +-- Objects/bytesobject.c | 2 +- Objects/funcobject.c | 2 +- Objects/listobject.c | 4 +-- Objects/memoryobject.c | 4 +-- Objects/moduleobject.c | 2 +- Objects/object.c | 14 +++++++++- Objects/rangeobject.c | 5 ++-- Objects/sliceobject.c | 8 ++++-- Objects/structseq.c | 20 +++++++++++++ Objects/tupleobject.c | 2 +- Objects/typeobject.c | 38 +++++++++++++++++++++++++ Objects/typeslots.inc | 71 +++++++++++++++++++++++++++++++++++++++++++++++ Objects/typeslots.py | 24 ++++++++++++++++ Objects/unicodeobject.c | 6 ++-- 15 files changed, 186 insertions(+), 20 deletions(-) create mode 100644 Objects/typeslots.inc create mode 100644 Objects/typeslots.py (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 6ca096afd7..32b8bb574b 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -389,7 +389,7 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) } else if (PySlice_Check(index)) { Py_ssize_t start, stop, step, slicelength, cur, i; - if (PySlice_GetIndicesEx((PySliceObject *)index, + if (PySlice_GetIndicesEx(index, PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; @@ -573,7 +573,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } } else if (PySlice_Check(index)) { - if (PySlice_GetIndicesEx((PySliceObject *)index, + if (PySlice_GetIndicesEx(index, PyByteArray_GET_SIZE(self), &start, &stop, &step, &slicelen) < 0) { return -1; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index d3b8a4fe80..4aa0748f09 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -911,7 +911,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) char* result_buf; PyObject* result; - if (PySlice_GetIndicesEx((PySliceObject*)item, + if (PySlice_GetIndicesEx(item, PyBytes_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 221f368ae2..45f9f57578 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -627,7 +627,7 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw) } result = PyEval_EvalCodeEx( - (PyCodeObject *)PyFunction_GET_CODE(func), + PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), (PyObject *)NULL, &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg), k, nk, d, nd, diff --git a/Objects/listobject.c b/Objects/listobject.c index fbc05fda4a..bcc6bc0c9b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2397,7 +2397,7 @@ list_subscript(PyListObject* self, PyObject* item) PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self), + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -2446,7 +2446,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self), + if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return -1; } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index ba9e08b9ab..a05b97b977 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -599,7 +599,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) else if (PySlice_Check(key)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + if (PySlice_GetIndicesEx(key, get_shape0(view), &start, &stop, &step, &slicelength) < 0) { return NULL; } @@ -678,7 +678,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) else if (PySlice_Check(key)) { Py_ssize_t stop, step; - if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + if (PySlice_GetIndicesEx(key, get_shape0(view), &start, &stop, &step, &len) < 0) { return -1; } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 1e3349d0a3..2c095a0968 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -74,7 +74,7 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) module->m_base.m_index = max_module_number; } name = module->m_name; - if (module_api_version != PYTHON_API_VERSION) { + if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { int err; err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "Python C API version mismatch for module %.100s: " diff --git a/Objects/object.c b/Objects/object.c index 082dd78e95..17e5069ef5 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1755,7 +1755,6 @@ _Py_GetObjects(PyObject *self, PyObject *args) #endif - /* Hack to force loading of pycapsule.o */ PyTypeObject *_PyCapsule_hack = &PyCapsule_Type; @@ -1900,6 +1899,19 @@ _PyTrash_destroy_chain(void) } } +#ifndef Py_TRACE_REFS +/* For Py_LIMITED_API, we need an out-of-line version of _Py_Dealloc. + Define this here, so we can undefine the macro. */ +#undef _Py_Dealloc +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +void +_Py_Dealloc(PyObject *op) +{ + _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA + (*Py_TYPE(op)->tp_dealloc)(op); +} +#endif + #ifdef __cplusplus } #endif diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index bf42b1e321..3ac829a6d2 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -431,7 +431,6 @@ range_subscript(rangeobject* self, PyObject* item) return range_item(self, i); } if (PySlice_Check(item)) { - PySliceObject *slice = (PySliceObject*)item; Py_ssize_t start, stop, step, len, rlen; rangeobject *result; PyObject *substart = NULL, *substep = NULL, *substop = NULL; @@ -441,7 +440,7 @@ range_subscript(rangeobject* self, PyObject* item) return NULL; } - if (PySlice_GetIndicesEx(slice, rlen, + if (PySlice_GetIndicesEx(item, rlen, &start, &stop, &step, &len) < 0) { return NULL; } @@ -450,7 +449,7 @@ range_subscript(rangeobject* self, PyObject* item) Py_INCREF(substep); } else { /* NB: slice step != Py_None here */ - substep = PyNumber_Multiply(self->step, slice->step); + substep = PyNumber_Multiply(self->step, ((PySliceObject*)item)->step); if (substep == NULL) goto fail; } diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index b617891423..51c53a8a11 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -99,9 +99,10 @@ _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop) } int -PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, +PySlice_GetIndices(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { + PySliceObject *r = (PySliceObject*)_r; /* XXX support long ints */ if (r->step == Py_None) { *step = 1; @@ -130,10 +131,11 @@ PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, } int -PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, +PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) { + PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ Py_ssize_t defstart, defstop; @@ -256,7 +258,7 @@ slice_indices(PySliceObject* self, PyObject* len) return NULL; } - if (PySlice_GetIndicesEx(self, ilen, &start, &stop, + if (PySlice_GetIndicesEx((PyObject*)self, ilen, &start, &stop, &step, &slicelength) < 0) { return NULL; } diff --git a/Objects/structseq.c b/Objects/structseq.c index 75e2250bf9..ef17f49a31 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -43,6 +43,18 @@ PyStructSequence_New(PyTypeObject *type) return (PyObject*)obj; } +void +PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v) +{ + PyStructSequence_SET_ITEM(op, i, v); +} + +PyObject* +PyStructSequence_GetItem(PyObject* op, Py_ssize_t i) +{ + return PyStructSequence_GET_ITEM(op, i); +} + static void structseq_dealloc(PyStructSequence *obj) { @@ -365,3 +377,11 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) SET_DICT_FROM_INT(real_length_key, n_members); SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); } + +PyTypeObject* +PyStructSequence_NewType(PyStructSequence_Desc *desc) +{ + PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + PyStructSequence_InitType(result, desc); + return result; +} diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 390b670f20..72b79c917a 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -689,7 +689,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx((PySliceObject*)item, + if (PySlice_GetIndicesEx(item, PyTuple_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e0001db189..a5863dd0a4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2304,6 +2304,44 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) return (PyObject *)type; } +static short slotoffsets[] = { + -1, /* invalid slot */ +#include "typeslots.inc" +}; + +PyObject* PyType_FromSpec(PyType_Spec *spec) +{ + PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + char *res_start = (char*)res; + PyType_Slot *slot; + + res->ht_name = PyUnicode_FromString(spec->name); + if (!res->ht_name) + goto fail; + res->ht_type.tp_name = _PyUnicode_AsString(res->ht_name); + if (!res->ht_type.tp_name) + goto fail; + + res->ht_type.tp_basicsize = spec->basicsize; + res->ht_type.tp_itemsize = spec->itemsize; + res->ht_type.tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + + for (slot = spec->slots; slot->slot; slot++) { + if (slot->slot >= sizeof(slotoffsets)/sizeof(slotoffsets[0])) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto fail; + } + *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + } + + return (PyObject*)res; + + fail: + Py_DECREF(res); + return NULL; +} + + /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ PyObject * diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc new file mode 100644 index 0000000000..79e3db8d67 --- /dev/null +++ b/Objects/typeslots.inc @@ -0,0 +1,71 @@ +offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), +offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), +offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), +offsetof(PyHeapTypeObject, as_mapping.mp_length), +offsetof(PyHeapTypeObject, as_mapping.mp_subscript), +offsetof(PyHeapTypeObject, as_number.nb_absolute), +offsetof(PyHeapTypeObject, as_number.nb_add), +offsetof(PyHeapTypeObject, as_number.nb_and), +offsetof(PyHeapTypeObject, as_number.nb_bool), +offsetof(PyHeapTypeObject, as_number.nb_divmod), +offsetof(PyHeapTypeObject, as_number.nb_float), +offsetof(PyHeapTypeObject, as_number.nb_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_index), +offsetof(PyHeapTypeObject, as_number.nb_inplace_add), +offsetof(PyHeapTypeObject, as_number.nb_inplace_and), +offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply), +offsetof(PyHeapTypeObject, as_number.nb_inplace_or), +offsetof(PyHeapTypeObject, as_number.nb_inplace_power), +offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder), +offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift), +offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract), +offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_inplace_xor), +offsetof(PyHeapTypeObject, as_number.nb_int), +offsetof(PyHeapTypeObject, as_number.nb_invert), +offsetof(PyHeapTypeObject, as_number.nb_lshift), +offsetof(PyHeapTypeObject, as_number.nb_multiply), +offsetof(PyHeapTypeObject, as_number.nb_negative), +offsetof(PyHeapTypeObject, as_number.nb_or), +offsetof(PyHeapTypeObject, as_number.nb_positive), +offsetof(PyHeapTypeObject, as_number.nb_power), +offsetof(PyHeapTypeObject, as_number.nb_remainder), +offsetof(PyHeapTypeObject, as_number.nb_rshift), +offsetof(PyHeapTypeObject, as_number.nb_subtract), +offsetof(PyHeapTypeObject, as_number.nb_true_divide), +offsetof(PyHeapTypeObject, as_number.nb_xor), +offsetof(PyHeapTypeObject, as_sequence.sq_ass_item), +offsetof(PyHeapTypeObject, as_sequence.sq_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_contains), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat), +offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat), +offsetof(PyHeapTypeObject, as_sequence.sq_item), +offsetof(PyHeapTypeObject, as_sequence.sq_length), +offsetof(PyHeapTypeObject, as_sequence.sq_repeat), +offsetof(PyHeapTypeObject, ht_type.tp_alloc), +offsetof(PyHeapTypeObject, ht_type.tp_base), +offsetof(PyHeapTypeObject, ht_type.tp_bases), +offsetof(PyHeapTypeObject, ht_type.tp_call), +offsetof(PyHeapTypeObject, ht_type.tp_clear), +offsetof(PyHeapTypeObject, ht_type.tp_dealloc), +offsetof(PyHeapTypeObject, ht_type.tp_del), +offsetof(PyHeapTypeObject, ht_type.tp_descr_get), +offsetof(PyHeapTypeObject, ht_type.tp_descr_set), +offsetof(PyHeapTypeObject, ht_type.tp_doc), +offsetof(PyHeapTypeObject, ht_type.tp_getattr), +offsetof(PyHeapTypeObject, ht_type.tp_getattro), +offsetof(PyHeapTypeObject, ht_type.tp_hash), +offsetof(PyHeapTypeObject, ht_type.tp_init), +offsetof(PyHeapTypeObject, ht_type.tp_is_gc), +offsetof(PyHeapTypeObject, ht_type.tp_iter), +offsetof(PyHeapTypeObject, ht_type.tp_iternext), +offsetof(PyHeapTypeObject, ht_type.tp_methods), +offsetof(PyHeapTypeObject, ht_type.tp_new), +offsetof(PyHeapTypeObject, ht_type.tp_repr), +offsetof(PyHeapTypeObject, ht_type.tp_richcompare), +offsetof(PyHeapTypeObject, ht_type.tp_setattr), +offsetof(PyHeapTypeObject, ht_type.tp_setattro), +offsetof(PyHeapTypeObject, ht_type.tp_str), +offsetof(PyHeapTypeObject, ht_type.tp_traverse), diff --git a/Objects/typeslots.py b/Objects/typeslots.py new file mode 100644 index 0000000000..bcc3196bdf --- /dev/null +++ b/Objects/typeslots.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# Usage: typeslots.py < Include/typeslots.h > typeslots.inc + +import sys, re + +res = {} +for line in sys.stdin: + m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) + member = m.group(1) + if member.startswith("tp_"): + member = "ht_type."+member + elif member.startswith("nb_"): + member = "as_number."+member + elif member.startswith("mp_"): + member = "as_mapping."+member + elif member.startswith("sq_"): + member = "as_sequence."+member + elif member.startswith("bf_"): + member = "as_buffer."+member + res[int(m.group(2))] = member + +M = max(res.keys())+1 +for i in range(1,M): + print "offsetof(PyHeapTypeObject, %s)," % res[i] diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f66773e26a..d3a2d1b715 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1263,7 +1263,7 @@ unicode_aswidechar(PyUnicodeObject *unicode, } Py_ssize_t -PyUnicode_AsWideChar(PyUnicodeObject *unicode, +PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) { @@ -1271,7 +1271,7 @@ PyUnicode_AsWideChar(PyUnicodeObject *unicode, PyErr_BadInternalCall(); return -1; } - return unicode_aswidechar(unicode, w, size); + return unicode_aswidechar((PyUnicodeObject*)unicode, w, size); } wchar_t* @@ -9222,7 +9222,7 @@ unicode_subscript(PyUnicodeObject* self, PyObject* item) Py_UNICODE* result_buf; PyObject* result; - if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self), + if (PySlice_GetIndicesEx(item, PyUnicode_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; } -- cgit v1.2.1 From e74b9d92aa6f78ba0cf928bf257cd3a4f2c02d72 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Sat, 4 Dec 2010 03:38:46 +0000 Subject: Issue #10557: Fixed error messages from float() and other numeric types. Added a new API function, PyUnicode_TransformDecimalToASCII(), which transforms non-ASCII decimal digits in a Unicode string to their ASCII equivalents. --- Objects/complexobject.c | 30 ++++++++++++++----------- Objects/floatobject.c | 58 +++++++++++++++++++++++++++---------------------- Objects/longobject.c | 31 ++++++++++++++++++++------ Objects/unicodeobject.c | 35 +++++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 48 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 59997962ce..ec529d5bbf 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -766,20 +766,26 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) char *end; double x=0.0, y=0.0, z; int got_bracket=0; - char *s_buffer = NULL; + PyObject *s_buffer = NULL; Py_ssize_t len; if (PyUnicode_Check(v)) { - s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v) + 1); + Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v); + Py_UNICODE *bufptr; + s_buffer = PyUnicode_TransformDecimalToASCII( + PyUnicode_AS_UNICODE(v), buflen); if (s_buffer == NULL) - return PyErr_NoMemory(); - if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v), - s_buffer, - NULL)) + return NULL; + /* Replace non-ASCII whitespace with ' ' */ + bufptr = PyUnicode_AS_UNICODE(s_buffer); + for (i = 0; i < buflen; i++) { + Py_UNICODE ch = bufptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + bufptr[i] = ' '; + } + s = _PyUnicode_AsStringAndSize(s_buffer, &len); + if (s == NULL) goto error; - s = s_buffer; - len = strlen(s); } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, @@ -894,16 +900,14 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s-start != len) goto parse_error; - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 4decb0b627..8409f0a13a 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -174,22 +174,30 @@ PyFloat_FromString(PyObject *v) { const char *s, *last, *end; double x; - char buffer[256]; /* for errors */ - char *s_buffer = NULL; + PyObject *s_buffer = NULL; Py_ssize_t len; PyObject *result = NULL; if (PyUnicode_Check(v)) { - s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1); + Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v); + Py_UNICODE *bufptr; + s_buffer = PyUnicode_TransformDecimalToASCII( + PyUnicode_AS_UNICODE(v), buflen); 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); + return NULL; + /* Replace non-ASCII whitespace with ' ' */ + bufptr = PyUnicode_AS_UNICODE(s_buffer); + for (i = 0; i < buflen; i++) { + Py_UNICODE ch = bufptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + bufptr[i] = ' '; + } + s = _PyUnicode_AsStringAndSize(s_buffer, &len); + if (s == NULL) { + Py_DECREF(s_buffer); + return NULL; + } + last = s + len; } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, @@ -197,29 +205,27 @@ PyFloat_FromString(PyObject *v) return NULL; } last = s + len; - - while (Py_ISSPACE(*s)) + /* strip space */ + while (s < last && Py_ISSPACE(*s)) s++; + while (s < last - 1 && Py_ISSPACE(last[-1])) + last--; /* 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); + if (end != last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", v); result = NULL; } + else if (x == -1.0 && PyErr_Occurred()) + result = NULL; + else + result = PyFloat_FromDouble(x); - error: - if (s_buffer) - PyMem_FREE(s_buffer); + Py_XDECREF(s_buffer); return result; } diff --git a/Objects/longobject.c b/Objects/longobject.c index e8a728489b..534e52dfd3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2133,17 +2133,34 @@ PyObject * PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) { PyObject *result; - char *buffer = (char *)PyMem_MALLOC(length+1); + PyObject *asciidig; + char *buffer, *end; + Py_ssize_t i, buflen; + Py_UNICODE *ptr; - if (buffer == NULL) + asciidig = PyUnicode_TransformDecimalToASCII(u, length); + if (asciidig == NULL) return NULL; - - if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) { - PyMem_FREE(buffer); + /* Replace non-ASCII whitespace with ' ' */ + ptr = PyUnicode_AS_UNICODE(asciidig); + for (i = 0; i < length; i++) { + Py_UNICODE ch = ptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + ptr[i] = ' '; + } + buffer = _PyUnicode_AsStringAndSize(asciidig, &buflen); + if (buffer == NULL) { + Py_DECREF(asciidig); return NULL; } - result = PyLong_FromString(buffer, NULL, base); - PyMem_FREE(buffer); + result = PyLong_FromString(buffer, &end, base); + if (result != NULL && end != buffer + buflen) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for int()"); + Py_DECREF(result); + result = NULL; + } + Py_DECREF(asciidig); return result; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d3a2d1b715..751da30e42 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6206,6 +6206,30 @@ PyObject *PyUnicode_Translate(PyObject *str, return NULL; } +PyObject * +PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, + Py_ssize_t length) +{ + PyObject *result; + Py_UNICODE *p; /* write pointer into result */ + Py_ssize_t i; + /* Copy to a new string */ + result = (PyObject *)_PyUnicode_New(length); + Py_UNICODE_COPY(PyUnicode_AS_UNICODE(result), s, length); + if (result == NULL) + return result; + p = PyUnicode_AS_UNICODE(result); + /* Iterate over code points */ + for (i = 0; i < length; i++) { + Py_UNICODE ch =s[i]; + if (ch > 127) { + int decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) + p[i] = '0' + decimal; + } + } + return result; +} /* --- Decimal Encoder ---------------------------------------------------- */ int PyUnicode_EncodeDecimal(Py_UNICODE *s, @@ -8967,6 +8991,13 @@ unicode_freelistsize(PyUnicodeObject *self) { return PyLong_FromLong(numfree); } + +static PyObject * +unicode__decimal2ascii(PyObject *self) +{ + return PyUnicode_TransformDecimalToASCII(PyUnicode_AS_UNICODE(self), + PyUnicode_GET_SIZE(self)); +} #endif PyDoc_STRVAR(startswith__doc__, @@ -9108,7 +9139,6 @@ unicode_getnewargs(PyUnicodeObject *v) return Py_BuildValue("(u#)", v->str, v->length); } - static PyMethodDef unicode_methods[] = { /* Order is according to common usage: often used methods should @@ -9170,8 +9200,9 @@ static PyMethodDef unicode_methods[] = { #endif #if 0 - /* This one is just used for debugging the implementation. */ + /* These methods are just used for debugging the implementation. */ {"freelistsize", (PyCFunction) unicode_freelistsize, METH_NOARGS}, + {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, #endif {"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS}, -- cgit v1.2.1 From 95eb5065f0713b7e0865b63dacbdaa1b7184b14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sat, 4 Dec 2010 09:08:10 +0000 Subject: Make script 2-vs-3-agnostic. --- Objects/typeslots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeslots.py b/Objects/typeslots.py index bcc3196bdf..0e6ef1f9b8 100644 --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -21,4 +21,4 @@ for line in sys.stdin: M = max(res.keys())+1 for i in range(1,M): - print "offsetof(PyHeapTypeObject, %s)," % res[i] + print("offsetof(PyHeapTypeObject, %s)," % res[i]) -- cgit v1.2.1 From 33dc702e125c8417d798ff1d0afdac2e97fa5074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sat, 4 Dec 2010 09:11:41 +0000 Subject: Add Revision keyword. --- Objects/typeslots.py | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/typeslots.py b/Objects/typeslots.py index 0e6ef1f9b8..686fb6fcf6 100644 --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -3,6 +3,7 @@ import sys, re +print("/* Generated by typeslots.py $Revision$ */") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) -- cgit v1.2.1 From 160c43d5eeab924912cb09ecb7c0f885d65be8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sat, 4 Dec 2010 09:12:14 +0000 Subject: Regenerate. --- Objects/typeslots.inc | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index 79e3db8d67..bd20c29349 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -1,3 +1,4 @@ +/* Generated by typeslots.py $Revision: 87011 $ */ offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), -- cgit v1.2.1 From 0e83025a8fbdc17dbf4c97cff3409d00aff506f0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 4 Dec 2010 11:06:25 +0000 Subject: Fix indentation in Objects/longobject.c --- Objects/longobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 534e52dfd3..4737787b87 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2144,9 +2144,9 @@ PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) /* Replace non-ASCII whitespace with ' ' */ ptr = PyUnicode_AS_UNICODE(asciidig); for (i = 0; i < length; i++) { - Py_UNICODE ch = ptr[i]; - if (ch > 127 && Py_UNICODE_ISSPACE(ch)) - ptr[i] = ' '; + Py_UNICODE ch = ptr[i]; + if (ch > 127 && Py_UNICODE_ISSPACE(ch)) + ptr[i] = ' '; } buffer = _PyUnicode_AsStringAndSize(asciidig, &buflen); if (buffer == NULL) { -- cgit v1.2.1 From e81a33864d723aecf9a378d39388d013fec286c2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 4 Dec 2010 11:52:58 +0000 Subject: Remove some unecessary '#ifdef Py_NAN's from floatobject.c --- Objects/floatobject.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 8409f0a13a..d5a3c7ef23 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -575,13 +575,11 @@ 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) @@ -595,13 +593,11 @@ float_rem(PyObject *v, PyObject *w) 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); /* note: checking mod*wx < 0 is incorrect -- underflows to @@ -1492,13 +1488,11 @@ float_as_integer_ratio(PyObject *v, PyObject *unused) "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 */ -- cgit v1.2.1 From 4207299c7b6b530a8d389580020998770573c363 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 4 Dec 2010 12:25:30 +0000 Subject: Issue #10596: Fix float.__mod__ to have the same behaviour as float.__divmod__ with respect to signed zeros. --- Objects/floatobject.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d5a3c7ef23..7cbb240b38 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -600,10 +600,20 @@ float_rem(PyObject *v, PyObject *w) } PyFPE_START_PROTECT("modulo", return 0) mod = fmod(vx, wx); - /* note: checking mod*wx < 0 is incorrect -- underflows to - 0 if wx < sqrt(smallest nonzero double) */ - if (mod && ((wx < 0) != (mod < 0))) { - mod += 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); -- cgit v1.2.1 From 2b4c62e8dc5a32e770e0839c731860b84e171d15 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 4 Dec 2010 13:14:29 +0000 Subject: Use copysign to produce appropriately signed zeros instead of trying to worm around possible compiler optimizations. --- Objects/floatobject.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 7cbb240b38..09c0e961ba 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -609,11 +609,8 @@ float_rem(PyObject *v, PyObject *w) 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; + it has the same sign as the denominator. */ + mod = copysign(0.0, wx); } PyFPE_END_PROTECT(mod) return PyFloat_FromDouble(mod); @@ -649,11 +646,8 @@ float_divmod(PyObject *v, PyObject *w) 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; + it has the same sign as the denominator. */ + mod = copysign(0.0, wx); } /* snap quotient to nearest integral value */ if (div) { @@ -663,8 +657,7 @@ float_divmod(PyObject *v, PyObject *w) } 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 */ + floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */ } PyFPE_END_PROTECT(floordiv) return Py_BuildValue("(dd)", floordiv, mod); -- cgit v1.2.1 From 16ed4907fc5c11b0154727d998ae3c0d373626b3 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 4 Dec 2010 13:27:34 +0000 Subject: Removed static function complex_format, moved it into complex_repr. Modified tests to check both str and repr, which are the same for complex. --- Objects/complexobject.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/complexobject.c b/Objects/complexobject.c index ec529d5bbf..e247ba9ba8 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -324,10 +324,11 @@ complex_dealloc(PyObject *op) op->ob_type->tp_free(op); } - static PyObject * -complex_format(PyComplexObject *v, int precision, char format_code) +complex_repr(PyComplexObject *v) { + int precision = 0; + char format_code = 'r'; PyObject *result = NULL; Py_ssize_t len; @@ -344,6 +345,8 @@ complex_format(PyComplexObject *v, int precision, char format_code) char *tail = ""; if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { + /* Real part is +0: just output the imaginary part and do not + include parens. */ re = ""; im = PyOS_double_to_string(v->cval.imag, format_code, precision, 0, NULL); @@ -352,7 +355,8 @@ complex_format(PyComplexObject *v, int precision, char format_code) goto done; } } else { - /* Format imaginary part with sign, real part without */ + /* Format imaginary part with sign, real part without. Include + parens in the result. */ pre = PyOS_double_to_string(v->cval.real, format_code, precision, 0, NULL); if (!pre) { @@ -371,7 +375,7 @@ complex_format(PyComplexObject *v, int precision, char format_code) tail = ")"; } /* Alloc the final buffer. Add one for the "j" in the format string, - and one for the trailing zero. */ + and one for the trailing zero byte. */ len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; buf = PyMem_Malloc(len); if (!buf) { @@ -388,12 +392,6 @@ complex_format(PyComplexObject *v, int precision, char format_code) return result; } -static PyObject * -complex_repr(PyComplexObject *v) -{ - return complex_format(v, 0, 'r'); -} - static Py_hash_t complex_hash(PyComplexObject *v) { -- cgit v1.2.1 From f9f2b07a48c8e4bc9d3eb3ba74994ea443229f2a Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 4 Dec 2010 17:09:30 +0000 Subject: Fix typo. --- Objects/bytearrayobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 32b8bb574b..ac67d0b1b6 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -589,7 +589,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu needed = 0; } else if (values == (PyObject *)self || !PyByteArray_Check(values)) { - /* Make a copy an call this function recursively */ + /* Make a copy and call this function recursively */ int err; values = PyByteArray_FromObject(values); if (values == NULL) -- cgit v1.2.1 From 15b74fdafcd59c7f76e90c96a0753ec20ca11876 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 7 Dec 2010 03:46:27 +0000 Subject: return views from dict proxy items/values/keys #10630 --- Objects/descrobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 11418d19e5..de065b4331 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -710,19 +710,19 @@ proxy_get(proxyobject *pp, PyObject *args) static PyObject * proxy_keys(proxyobject *pp) { - return PyMapping_Keys(pp->dict); + return PyObject_CallMethod(pp->dict, "keys", NULL); } static PyObject * proxy_values(proxyobject *pp) { - return PyMapping_Values(pp->dict); + return PyObject_CallMethod(pp->dict, "values", NULL); } static PyObject * proxy_items(proxyobject *pp) { - return PyMapping_Items(pp->dict); + return PyObject_CallMethod(pp->dict, "items", NULL); } static PyObject * -- cgit v1.2.1 From 50c6a3f5499bd4a2f15bf38337d7b48a2600e874 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 7 Dec 2010 04:04:02 +0000 Subject: use the more direct API --- Objects/descrobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index de065b4331..967110291d 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1190,7 +1190,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - return PyObject_CallFunction(gs->prop_get, "(O)", obj); + return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL); } static int @@ -1211,9 +1211,9 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) return -1; } if (value == NULL) - res = PyObject_CallFunction(func, "(O)", obj); + res = PyObject_CallFunctionObjArgs(func, obj, NULL); else - res = PyObject_CallFunction(func, "(OO)", obj, value); + res = PyObject_CallFunctionObjArgs(func, obj, value, NULL); if (res == NULL) return -1; Py_DECREF(res); -- cgit v1.2.1 From 69b826e75b31f3b0ed4377f2c39c8202b2e89d40 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Fri, 10 Dec 2010 18:11:24 +0000 Subject: Updated UCD version and unicode.org links to Unicode 6.0.0 --- Objects/moduleobject.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 2c095a0968..8b22b7dc95 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -168,8 +168,8 @@ PyModule_GetDict(PyObject *m) return d; } -const char * -PyModule_GetName(PyObject *m) +PyObject * +PyModule_GetNameObject(PyObject *m) { PyObject *d; PyObject *nameobj; @@ -185,7 +185,21 @@ PyModule_GetName(PyObject *m) PyErr_SetString(PyExc_SystemError, "nameless module"); return NULL; } - return _PyUnicode_AsString(nameobj); + Py_INCREF(nameobj); + return nameobj; +} + +const char * +PyModule_GetName(PyObject *m) +{ + PyObject *nameobj; + char *utf8; + nameobj = PyModule_GetNameObject(m); + if (nameobj == NULL) + return NULL; + utf8 = _PyUnicode_AsString(nameobj); + Py_DECREF(nameobj); + return utf8; } PyObject* -- cgit v1.2.1 From 7cc7575a9cd172f3704e53b59d3b3bc9ec5a09f7 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Fri, 10 Dec 2010 18:14:16 +0000 Subject: Reverted accidental commit (from r87159) --- Objects/moduleobject.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 8b22b7dc95..2c095a0968 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -168,8 +168,8 @@ PyModule_GetDict(PyObject *m) return d; } -PyObject * -PyModule_GetNameObject(PyObject *m) +const char * +PyModule_GetName(PyObject *m) { PyObject *d; PyObject *nameobj; @@ -185,21 +185,7 @@ PyModule_GetNameObject(PyObject *m) PyErr_SetString(PyExc_SystemError, "nameless module"); return NULL; } - Py_INCREF(nameobj); - return nameobj; -} - -const char * -PyModule_GetName(PyObject *m) -{ - PyObject *nameobj; - char *utf8; - nameobj = PyModule_GetNameObject(m); - if (nameobj == NULL) - return NULL; - utf8 = _PyUnicode_AsString(nameobj); - Py_DECREF(nameobj); - return utf8; + return _PyUnicode_AsString(nameobj); } PyObject* -- cgit v1.2.1 From 4c86be149ea7bf9db7f10e186d77063e94a0508e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 12 Dec 2010 01:33:04 +0000 Subject: remove (un)transform methods --- Objects/bytearrayobject.c | 73 ----------------------------------------------- Objects/bytesobject.c | 64 ----------------------------------------- Objects/unicodeobject.c | 45 +---------------------------- 3 files changed, 1 insertion(+), 181 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index ac67d0b1b6..74483544c0 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2488,75 +2488,6 @@ bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) return PyUnicode_FromEncodedObject(self, encoding, errors); } -PyDoc_STRVAR(transform__doc__, -"B.transform(encoding, errors='strict') -> bytearray\n\ -\n\ -Transform B using the codec registered for encoding. errors may be given\n\ -to set a different error handling scheme."); - -static PyObject * -bytearray_transform(PyObject *self, PyObject *args, PyObject *kwargs) -{ - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - PyObject *v, *w; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", - kwlist, &encoding, &errors)) - return NULL; - - v = PyCodec_Encode(self, encoding, errors); - if (v == NULL) - return NULL; - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a bytes object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), - PyBytes_GET_SIZE(v)); - Py_DECREF(v); - return w; -} - - -PyDoc_STRVAR(untransform__doc__, -"B.untransform(encoding, errors='strict') -> bytearray\n\ -\n\ -Reverse-transform B using the codec registered for encoding. errors may\n\ -be given to set a different error handling scheme."); - -static PyObject * -bytearray_untransform(PyObject *self, PyObject *args, PyObject *kwargs) -{ - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - PyObject *v, *w; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", - kwlist, &encoding, &errors)) - return NULL; - - v = PyCodec_Decode(self, encoding, errors); - if (v == NULL) - return NULL; - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a bytes object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - w = PyByteArray_FromStringAndSize(PyBytes_AS_STRING(v), - PyBytes_GET_SIZE(v)); - Py_DECREF(v); - return w; -} - PyDoc_STRVAR(alloc_doc, "B.__alloc__() -> int\n\ \n\ @@ -2851,12 +2782,8 @@ bytearray_methods[] = { {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"transform", (PyCFunction)bytearray_transform, METH_VARARGS | METH_KEYWORDS, - transform__doc__}, {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, - {"untransform", (PyCFunction)bytearray_untransform, METH_VARARGS | METH_KEYWORDS, - untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 4aa0748f09..ba336086f8 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2312,68 +2312,6 @@ bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) return PyUnicode_FromEncodedObject(self, encoding, errors); } -PyDoc_STRVAR(transform__doc__, -"B.transform(encoding, errors='strict') -> bytes\n\ -\n\ -Transform B using the codec registered for encoding. errors may be given\n\ -to set a different error handling scheme."); - -static PyObject * -bytes_transform(PyObject *self, PyObject *args, PyObject *kwargs) -{ - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - PyObject *v; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", - kwlist, &encoding, &errors)) - return NULL; - - v = PyCodec_Encode(self, encoding, errors); - if (v == NULL) - return NULL; - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "encoder did not return a bytes object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - return v; -} - - -PyDoc_STRVAR(untransform__doc__, -"B.untransform(encoding, errors='strict') -> bytes\n\ -\n\ -Reverse-transform B using the codec registered for encoding. errors may\n\ -be given to set a different error handling scheme."); - -static PyObject * -bytes_untransform(PyObject *self, PyObject *args, PyObject *kwargs) -{ - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - PyObject *v; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", - kwlist, &encoding, &errors)) - return NULL; - - v = PyCodec_Decode(self, encoding, errors); - if (v == NULL) - return NULL; - if (!PyBytes_Check(v)) { - PyErr_Format(PyExc_TypeError, - "decoder did not return a bytes object (type=%.400s)", - Py_TYPE(v)->tp_name); - Py_DECREF(v); - return NULL; - } - return v; -} PyDoc_STRVAR(splitlines__doc__, "B.splitlines([keepends]) -> list of lines\n\ @@ -2537,10 +2475,8 @@ bytes_methods[] = { {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"transform", (PyCFunction)bytes_transform, METH_VARARGS | METH_KEYWORDS, transform__doc__}, {"translate", (PyCFunction)bytes_translate, METH_VARARGS, translate__doc__}, - {"untransform", (PyCFunction)bytes_untransform, METH_VARARGS | METH_KEYWORDS, untransform__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 751da30e42..9f109f351c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7455,44 +7455,6 @@ unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) return PyUnicode_AsEncodedString((PyObject *)self, encoding, errors); } -PyDoc_STRVAR(transform__doc__, - "S.transform(encoding, errors='strict') -> str\n\ -\n\ -Transform S using the codec registered for encoding. errors may be given\n\ -to set a different error handling scheme."); - -static PyObject * -unicode_transform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"encoding", "errors", 0}; - char *encoding = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:transform", - kwlist, &encoding, &errors)) - return NULL; - return PyUnicode_AsEncodedUnicode((PyObject *)self, encoding, errors); -} - -PyDoc_STRVAR(untransform__doc__, - "S.untransform(encoding, errors='strict') -> str\n\ -\n\ -Reverse-transform S using the codec registered for encoding. errors may be\n\ -given to set a different error handling scheme."); - -static PyObject * -unicode_untransform(PyUnicodeObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"encoding", "errors", 0}; - char *encoding = NULL; - char *errors = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s:untransform", - kwlist, &encoding, &errors)) - return NULL; - return PyUnicode_AsDecodedUnicode((PyObject *)self, encoding, errors); -} - PyDoc_STRVAR(expandtabs__doc__, "S.expandtabs([tabsize]) -> str\n\ \n\ @@ -9144,8 +9106,7 @@ static PyMethodDef unicode_methods[] = { /* Order is according to common usage: often used methods should appear first, since lookup is done sequentially. */ - {"encode", (PyCFunction) unicode_encode, METH_VARARGS | METH_KEYWORDS, - encode__doc__}, + {"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__}, @@ -9190,10 +9151,6 @@ static PyMethodDef unicode_methods[] = { {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS | METH_STATIC, maketrans__doc__}, - {"transform", (PyCFunction) unicode_transform, METH_VARARGS | METH_KEYWORDS, - transform__doc__}, - {"untransform", (PyCFunction) unicode_untransform, METH_VARARGS | METH_KEYWORDS, - untransform__doc__}, {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__}, #if 0 {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__}, -- cgit v1.2.1 From 1e8ae990fb9151a7ba95f59fd316f230ebf625a1 Mon Sep 17 00:00:00 2001 From: "R. David Murray" Date: Tue, 14 Dec 2010 23:06:25 +0000 Subject: #4236: avoid possible Fatal Error when import is called from __del__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Simon Cross, crasher test code by Martin von Löwis. --- Objects/moduleobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 2c095a0968..f31b5da26d 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -63,8 +63,9 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) PyMethodDef *ml; const char* name; PyModuleObject *m; - if (!Py_IsInitialized()) - Py_FatalError("Interpreter not initialized (version mismatch?)"); + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->modules == NULL) + Py_FatalError("Python import machinery not initialized"); if (PyType_Ready(&moduledef_type) < 0) return NULL; if (module->m_base.m_index == 0) { -- cgit v1.2.1 From a7e3e4fafeaea260464c916c67461d743066fef3 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Sat, 18 Dec 2010 14:59:43 +0000 Subject: #5587: add a repr to dict_proxy objects. Patch by David Stanek and Daniel Urban. --- Objects/descrobject.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 967110291d..11c68d336c 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -766,6 +766,12 @@ proxy_str(proxyobject *pp) return PyObject_Str(pp->dict); } +static PyObject * +proxy_repr(proxyobject *pp) +{ + return PyUnicode_FromFormat("dict_proxy(%R)", pp->dict); +} + static int proxy_traverse(PyObject *self, visitproc visit, void *arg) { @@ -791,7 +797,7 @@ PyTypeObject PyDictProxy_Type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc)proxy_repr, /* tp_repr */ 0, /* tp_as_number */ &proxy_as_sequence, /* tp_as_sequence */ &proxy_as_mapping, /* tp_as_mapping */ -- cgit v1.2.1 From 1cfed0037a5227b953eaef012cf0b5dc3b2590a5 Mon Sep 17 00:00:00 2001 From: Alexander Belopolsky Date: Wed, 22 Dec 2010 02:35:20 +0000 Subject: Removed unneeded #include --- Objects/unicodeobject.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9f109f351c..456719685d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -41,8 +41,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "bytes_methods.h" - #include "ucnhash.h" #ifdef MS_WINDOWS -- cgit v1.2.1 From d4a9fa435abe536522fb0343710feac61914ce00 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jan 2011 12:59:15 +0000 Subject: Issue #9566: use Py_ssize_t instead of int --- Objects/codeobject.c | 5 +++-- Objects/listobject.c | 2 +- Objects/typeobject.c | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 54c23aec36..e9cae134c0 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -492,7 +492,7 @@ PyTypeObject PyCode_Type = { int PyCode_Addr2Line(PyCodeObject *co, int addrq) { - int size = PyBytes_Size(co->co_lnotab) / 2; + Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2; unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab); int line = co->co_firstlineno; int addr = 0; @@ -510,7 +510,8 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) int _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) { - int size, addr, line; + Py_ssize_t size; + int addr, line; unsigned char* p; p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab); diff --git a/Objects/listobject.c b/Objects/listobject.c index bcc6bc0c9b..2e0c8aac0e 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1381,7 +1381,7 @@ typedef struct s_MergeState { /* Conceptually a MergeState's constructor. */ static void -merge_init(MergeState *ms, int list_size, int has_keyfunc) +merge_init(MergeState *ms, Py_ssize_t list_size, int has_keyfunc) { assert(ms != NULL); if (has_keyfunc) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a5863dd0a4..1fefe8414f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2325,7 +2325,7 @@ PyObject* PyType_FromSpec(PyType_Spec *spec) res->ht_type.tp_basicsize = spec->basicsize; res->ht_type.tp_itemsize = spec->itemsize; res->ht_type.tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; - + for (slot = spec->slots; slot->slot; slot++) { if (slot->slot >= sizeof(slotoffsets)/sizeof(slotoffsets[0])) { PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); @@ -2335,7 +2335,7 @@ PyObject* PyType_FromSpec(PyType_Spec *spec) } return (PyObject*)res; - + fail: Py_DECREF(res); return NULL; @@ -6202,7 +6202,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) and first local variable on the stack. */ PyFrameObject *f = PyThreadState_GET()->frame; PyCodeObject *co = f->f_code; - int i, n; + Py_ssize_t i, n; if (co == NULL) { PyErr_SetString(PyExc_SystemError, "super(): no code object"); -- cgit v1.2.1 From 1b4a68adf6b03a9335db0798ab2257cc427f4385 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jan 2011 13:15:39 +0000 Subject: Issue #9015, #9611: stdprinter.write() clamps the length to 2^31-1 on Windows --- Objects/fileobject.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 9288e35b70..d20f196b27 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -344,7 +344,7 @@ stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews) } static int -fileio_init(PyObject *self, PyObject *args, PyObject *kwds) +stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds) { PyErr_SetString(PyExc_TypeError, "cannot create 'stderrprinter' instances"); @@ -390,7 +390,13 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) Py_BEGIN_ALLOW_THREADS errno = 0; +#if defined(MS_WIN64) || defined(MS_WINDOWS) + if (n > INT_MAX) + n = INT_MAX; + n = write(self->fd, c, (int)n); +#else n = write(self->fd, c, n); +#endif Py_END_ALLOW_THREADS if (n < 0) { @@ -509,7 +515,7 @@ PyTypeObject PyStdPrinter_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - fileio_init, /* tp_init */ + stdprinter_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ stdprinter_new, /* tp_new */ PyObject_Del, /* tp_free */ -- cgit v1.2.1 From b3486edd771ae0bcedee3b0a2404488557014a70 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Jan 2011 03:33:26 +0000 Subject: Remove arbitrary string length limits PyUnicode_FromFormat() and PyErr_Format() allocates a buffer of the needed size, it is no more a fixed-buffer of 500 bytes. --- Objects/codeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index e9cae134c0..bb938ea0aa 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -347,11 +347,11 @@ code_repr(PyCodeObject *co) lineno = -1; if (co->co_filename && PyUnicode_Check(co->co_filename)) { return PyUnicode_FromFormat( - "", + "", co->co_name, co, co->co_filename, lineno); } else { return PyUnicode_FromFormat( - "", + "", co->co_name, co, lineno); } } -- cgit v1.2.1 From 54b3eec9de6792b76430c9f6c5377c9417881b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 6 Jan 2011 19:26:21 +0000 Subject: Support comment lines and missing indices in typeslots.h. --- Objects/typeslots.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeslots.py b/Objects/typeslots.py index 686fb6fcf6..2e00c80fbb 100644 --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -7,6 +7,8 @@ print("/* Generated by typeslots.py $Revision$ */") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) + if not m: + continue member = m.group(1) if member.startswith("tp_"): member = "ht_type."+member @@ -22,4 +24,7 @@ for line in sys.stdin: M = max(res.keys())+1 for i in range(1,M): - print("offsetof(PyHeapTypeObject, %s)," % res[i]) + if i in res: + print("offsetof(PyHeapTypeObject, %s)," % res[i]) + else: + print("0,") -- cgit v1.2.1 From 97893ab058111d4c03fd39ca97c31a52ef54350f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 6 Jan 2011 19:28:31 +0000 Subject: Drop bf_getbuffer/bf_releasebuffer from stable ABI, see #10181. --- Objects/typeslots.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index bd20c29349..d4872f6aad 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -1,6 +1,6 @@ -/* Generated by typeslots.py $Revision: 87011 $ */ -offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), -offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), +/* Generated by typeslots.py $Revision: 87806 $ */ +0, +0, offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), offsetof(PyHeapTypeObject, as_mapping.mp_length), offsetof(PyHeapTypeObject, as_mapping.mp_subscript), -- cgit v1.2.1 From 80ec28f460cadd561727a48e59fa302a63ba368a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 7 Jan 2011 21:43:59 +0000 Subject: Issue #8020: Avoid a crash where the small objects allocator would read non-Python managed memory while it is being modified by another thread. Patch by Matt Bandy. --- Objects/obmalloc.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index bbdc9469b3..3916262120 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -682,11 +682,19 @@ 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) \ - ((POOL)->arenaindex < maxarenas && \ - (uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \ - arenas[(POOL)->arenaindex].address != 0) + ((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 @@ -945,6 +953,9 @@ PyObject_Free(void *p) 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; @@ -1167,6 +1178,9 @@ 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); @@ -1867,8 +1881,10 @@ _PyObject_DebugMallocStats(void) int Py_ADDRESS_IN_RANGE(void *P, poolp pool) { - return pool->arenaindex < maxarenas && - (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE && - arenas[pool->arenaindex].address != 0; + uint arenaindex_temp = pool->arenaindex; + + return arenaindex_temp < maxarenas && + (uptr)P - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && + arenas[arenaindex_temp].address != 0; } #endif -- cgit v1.2.1 From e747b27f15bb898c9d84cc692165529d7221093d Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Wed, 12 Jan 2011 03:15:52 +0000 Subject: Issue 10889: Support slicing and indexing of large ranges (no docs changes, since, as far as I know, we never said anywhere that this *didn't* work) --- Objects/rangeobject.c | 373 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 306 insertions(+), 67 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 3ac829a6d2..ee42ba9c9b 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -230,18 +230,14 @@ range_length(rangeobject *r) return PyLong_AsSsize_t(r->length); } -/* range(...)[x] is necessary for: seq[:] = range(...) */ static PyObject * -compute_range_item(rangeobject *r, Py_ssize_t i) +compute_item(rangeobject *r, PyObject *i) { - PyObject *rem, *incr, *result; - - /* XXX(nnorwitz): optimize for short ints. */ - rem = PyLong_FromSsize_t(i); - if (!rem) - return NULL; - incr = PyNumber_Multiply(rem, r->step); - Py_DECREF(rem); + PyObject *incr, *result; + /* PyLong equivalent to: + * return r->start + (i * r->step) + */ + incr = PyNumber_Multiply(i, r->step); if (!incr) return NULL; result = PyNumber_Add(r->start, incr); @@ -250,22 +246,304 @@ compute_range_item(rangeobject *r, Py_ssize_t i) } static PyObject * -range_item(rangeobject *r, Py_ssize_t i) +compute_range_item(rangeobject *r, PyObject *arg) { - /* XXX(nnorwitz): should we support range[x] where x > PY_SSIZE_T_MAX? */ - Py_ssize_t len = range_length(r); + int cmp_result; + PyObject *i, *result; + + PyObject *zero = PyLong_FromLong(0); + if (zero == NULL) + return NULL; + + /* PyLong equivalent to: + * if (arg < 0) { + * i = r->length + arg + * } else { + * i = arg + * } + */ + cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT); + if (cmp_result == -1) { + Py_DECREF(zero); + return NULL; + } + if (cmp_result == 1) { + i = PyNumber_Add(r->length, arg); + if (!i) { + Py_DECREF(zero); + return NULL; + } + } else { + i = arg; + Py_INCREF(i); + } - if (i < 0) - i += len; + /* PyLong equivalent to: + * if (i < 0 || i >= r->length) { + * + * } + */ + cmp_result = PyObject_RichCompareBool(i, zero, Py_LT); + Py_DECREF(zero); + if (cmp_result == 0) { + cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE); + } + if (cmp_result == -1) { + Py_DECREF(i); + return NULL; + } + if (cmp_result == 1) { + Py_DECREF(i); + PyErr_SetString(PyExc_IndexError, + "range object index out of range"); + return NULL; + } + + result = compute_item(r, i); + Py_DECREF(i); + return result; +} - if (i < 0 || i >= len) { - /* Also handles case where len < 0 due to (e.g) OverflowError */ - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_IndexError, - "range object index out of range"); +static PyObject * +range_item(rangeobject *r, Py_ssize_t i) +{ + PyObject *arg = PyLong_FromLong(i); + if (!arg) { return NULL; } - return compute_range_item(r, i); + return compute_range_item(r, arg); +} + +/* Additional helpers, since the standard slice helpers + * all clip to PY_SSIZE_T_MAX + */ + +/* Replace _PyEval_SliceIndex */ +static PyObject * +compute_slice_element(PyObject *obj) +{ + PyObject *result = NULL; + if (obj != NULL) { + if (PyIndex_Check(obj)) { + result = PyNumber_Index(obj); + } + } + if (result == NULL) { + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); + } + return result; +} + +/* Replace PySlice_GetIndicesEx + * Result indicates whether or not the slice is empty + * (-1 = error, 0 = empty slice, 1 = slice contains elements) + */ +int +compute_slice_indices(rangeobject *r, PySliceObject *slice, + PyObject **start, PyObject **stop, PyObject **step) +{ + int cmp_result, has_elements; + Py_ssize_t clamped_step = 0; + PyObject *zero = NULL, *one = NULL, *neg_one = NULL, *candidate = NULL; + PyObject *tmp_start = NULL, *tmp_stop = NULL, *tmp_step = NULL; + zero = PyLong_FromLong(0); + if (zero == NULL) goto Fail; + one = PyLong_FromLong(1); + if (one == NULL) goto Fail; + neg_one = PyLong_FromLong(-1); + if (neg_one == NULL) goto Fail; + + /* Calculate step value */ + if (slice->step == Py_None) { + clamped_step = 1; + tmp_step = one; + Py_INCREF(tmp_step); + } else { + if (!_PyEval_SliceIndex(slice->step, &clamped_step)) goto Fail; + if (clamped_step == 0) { + PyErr_SetString(PyExc_ValueError, + "slice step cannot be zero"); + goto Fail; + } + tmp_step = compute_slice_element(slice->step); + if (tmp_step == NULL) goto Fail; + } + + /* Calculate start value */ + if (slice->start == Py_None) { + if (clamped_step < 0) { + tmp_start = PyNumber_Subtract(r->length, one); + if (tmp_start == NULL) goto Fail; + } else { + tmp_start = zero; + Py_INCREF(tmp_start); + } + } else { + candidate = compute_slice_element(slice->start); + if (candidate == NULL) goto Fail; + cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* candidate < 0 */ + tmp_start = PyNumber_Add(r->length, candidate); + if (tmp_start == NULL) goto Fail; + Py_CLEAR(candidate); + } else { + /* candidate >= 0 */ + tmp_start = candidate; + candidate = NULL; + } + cmp_result = PyObject_RichCompareBool(tmp_start, zero, Py_LT); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* tmp_start < 0 */ + Py_CLEAR(tmp_start); + if (clamped_step < 0) { + tmp_start = neg_one; + } else { + tmp_start = zero; + } + Py_INCREF(tmp_start); + } else { + /* tmp_start >= 0 */ + cmp_result = PyObject_RichCompareBool(tmp_start, r->length, Py_GE); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* tmp_start >= r->length */ + Py_CLEAR(tmp_start); + if (clamped_step < 0) { + tmp_start = PyNumber_Subtract(r->length, one); + if (tmp_start == NULL) goto Fail; + } else { + tmp_start = r->length; + Py_INCREF(tmp_start); + } + } + } + } + + /* Calculate stop value */ + if (slice->stop == Py_None) { + if (clamped_step < 0) { + tmp_stop = neg_one; + } else { + tmp_stop = r->length; + } + Py_INCREF(tmp_stop); + } else { + candidate = compute_slice_element(slice->stop); + if (candidate == NULL) goto Fail; + cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* candidate < 0 */ + tmp_stop = PyNumber_Add(r->length, candidate); + if (tmp_stop == NULL) goto Fail; + Py_CLEAR(candidate); + } else { + /* candidate >= 0 */ + tmp_stop = candidate; + candidate = NULL; + } + cmp_result = PyObject_RichCompareBool(tmp_stop, zero, Py_LT); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* tmp_stop < 0 */ + Py_CLEAR(tmp_stop); + if (clamped_step < 0) { + tmp_stop = neg_one; + } else { + tmp_stop = zero; + } + Py_INCREF(tmp_stop); + } else { + /* tmp_stop >= 0 */ + cmp_result = PyObject_RichCompareBool(tmp_stop, r->length, Py_GE); + if (cmp_result == -1) goto Fail; + if (cmp_result) { + /* tmp_stop >= r->length */ + Py_CLEAR(tmp_stop); + if (clamped_step < 0) { + tmp_stop = PyNumber_Subtract(r->length, one); + if (tmp_stop == NULL) goto Fail; + } else { + tmp_stop = r->length; + Py_INCREF(tmp_start); + } + } + } + } + + /* Check if the slice is empty or not */ + if (clamped_step < 0) { + has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_GT); + } else { + has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_LT); + } + if (has_elements == -1) goto Fail; + + *start = tmp_start; + *stop = tmp_stop; + *step = tmp_step; + Py_DECREF(neg_one); + Py_DECREF(one); + Py_DECREF(zero); + return has_elements; + + Fail: + Py_XDECREF(tmp_start); + Py_XDECREF(tmp_stop); + Py_XDECREF(tmp_step); + Py_XDECREF(candidate); + Py_XDECREF(neg_one); + Py_XDECREF(one); + Py_XDECREF(zero); + return -1; +} + +static PyObject * +compute_slice(rangeobject *r, PyObject *_slice) +{ + PySliceObject *slice = (PySliceObject *) _slice; + rangeobject *result; + PyObject *start = NULL, *stop = NULL, *step = NULL; + PyObject *substart = NULL, *substop = NULL, *substep = NULL; + int has_elements; + + has_elements = compute_slice_indices(r, slice, &start, &stop, &step); + if (has_elements == -1) return NULL; + + substep = PyNumber_Multiply(r->step, step); + if (substep == NULL) goto fail; + Py_CLEAR(step); + + substart = compute_item(r, start); + if (substart == NULL) goto fail; + Py_CLEAR(start); + + if (has_elements) { + substop = compute_item(r, stop); + if (substop == NULL) goto fail; + } else { + substop = substart; + Py_INCREF(substop); + } + Py_CLEAR(stop); + + result = make_range_object(Py_TYPE(r), substart, substop, substep); + if (result != NULL) { + return (PyObject *) result; + } +fail: + Py_XDECREF(start); + Py_XDECREF(stop); + Py_XDECREF(step); + Py_XDECREF(substart); + Py_XDECREF(substop); + Py_XDECREF(substep); + return NULL; } /* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */ @@ -424,55 +702,16 @@ static PyObject * range_subscript(rangeobject* self, PyObject* item) { if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) + PyObject *i, *result; + i = PyNumber_Index(item); + if (!i) return NULL; - return range_item(self, i); + result = compute_range_item(self, i); + Py_DECREF(i); + return result; } if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, len, rlen; - rangeobject *result; - PyObject *substart = NULL, *substep = NULL, *substop = NULL; - - rlen = range_length(self); - if (rlen < 0) { - return NULL; - } - - if (PySlice_GetIndicesEx(item, rlen, - &start, &stop, &step, &len) < 0) { - return NULL; - } - if (step == 1) { - substep = self->step; - Py_INCREF(substep); - } else { - /* NB: slice step != Py_None here */ - substep = PyNumber_Multiply(self->step, ((PySliceObject*)item)->step); - if (substep == NULL) - goto fail; - } - substart = compute_range_item(self, start); - if (substart == NULL) - goto fail; - if (len <= 0) { - substop = substart; - Py_INCREF(substop); - } - else { - substop = compute_range_item(self, stop); - if (substop == NULL) - goto fail; - } - result = make_range_object(Py_TYPE(self), substart, substop, substep); - if (result != NULL) - return (PyObject *) result; - fail: - Py_XDECREF(substart); - Py_XDECREF(substep); - Py_XDECREF(substop); - return NULL; + return compute_slice(self, item); } PyErr_Format(PyExc_TypeError, "range indices must be integers or slices, not %.200s", -- cgit v1.2.1 From 7f7e73724aba96ef80177bdf953224893995612d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 12 Jan 2011 15:34:01 +0000 Subject: don't segfault on deleting __abstractmethods__ #10892 --- Objects/typeobject.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1fefe8414f..930297a7bb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -340,8 +340,17 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) abc.ABCMeta.__new__, so this function doesn't do anything special to update subclasses. */ - int res = PyDict_SetItemString(type->tp_dict, - "__abstractmethods__", value); + int res; + if (value != NULL) { + res = PyDict_SetItemString(type->tp_dict, "__abstractmethods__", value); + } + else { + res = PyDict_DelItemString(type->tp_dict, "__abstractmethods__"); + if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Format(PyExc_AttributeError, "__abstractmethods__", value); + return -1; + } + } if (res == 0) { PyType_Modified(type); if (value && PyObject_IsTrue(value)) { -- cgit v1.2.1 From 4c6ea7bbfd95cf1e16855864c99859cee210fd8c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 12 Jan 2011 18:56:07 +0000 Subject: use PyErr_SetString instead of PyErr_Format --- Objects/typeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 930297a7bb..87c8723ee9 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -326,7 +326,7 @@ type_abstractmethods(PyTypeObject *type, void *context) if (type != &PyType_Type) mod = PyDict_GetItemString(type->tp_dict, "__abstractmethods__"); if (!mod) { - PyErr_Format(PyExc_AttributeError, "__abstractmethods__"); + PyErr_SetString(PyExc_AttributeError, "__abstractmethods__"); return NULL; } Py_XINCREF(mod); @@ -347,7 +347,7 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) else { res = PyDict_DelItemString(type->tp_dict, "__abstractmethods__"); if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Format(PyExc_AttributeError, "__abstractmethods__", value); + PyErr_SetString(PyExc_AttributeError, "__abstractmethods__"); return -1; } } -- cgit v1.2.1 From d9edbad3274d183111cb15847a2f0fe48d34058f Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 13 Jan 2011 04:22:54 +0000 Subject: plug reference leak --- Objects/rangeobject.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index ee42ba9c9b..979a62afdb 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -307,11 +307,13 @@ compute_range_item(rangeobject *r, PyObject *arg) static PyObject * range_item(rangeobject *r, Py_ssize_t i) { - PyObject *arg = PyLong_FromLong(i); + PyObject *res, *arg = PyLong_FromLong(i); if (!arg) { return NULL; } - return compute_range_item(r, arg); + res = compute_range_item(r, arg); + Py_DECREF(arg); + return res; } /* Additional helpers, since the standard slice helpers -- cgit v1.2.1 From 6fc7da8e430baec886c4d1d8176a1e7d954848cb Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Sun, 16 Jan 2011 20:57:01 +0000 Subject: rangeobject.c (compute_slice_indices): Make function static. --- Objects/rangeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 979a62afdb..cff2ce4741 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -342,7 +342,7 @@ compute_slice_element(PyObject *obj) * Result indicates whether or not the slice is empty * (-1 = error, 0 = empty slice, 1 = slice contains elements) */ -int +static int compute_slice_indices(rangeobject *r, PySliceObject *slice, PyObject **start, PyObject **stop, PyObject **step) { -- cgit v1.2.1 From 70eb5a8c14a0cf30f8ba8f6c7abd365df5923d0e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 17 Jan 2011 19:24:34 +0000 Subject: turn some checks into assertions, since they are implied by the caller Reviewed by Georg. --- Objects/typeobject.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 87c8723ee9..325b8254b5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2945,10 +2945,8 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) Py_ssize_t size; PyObject *slots_a, *slots_b; - if (base != b->tp_base) - return 0; - if (equiv_structs(a, base) && equiv_structs(b, base)) - return 1; + assert(base == b->tp_base); + assert(equiv_structs(a, base) && equiv_structs(b, base)); size = base->tp_basicsize; if (a->tp_dictoffset == size && b->tp_dictoffset == size) size += sizeof(PyObject *); -- cgit v1.2.1 From eb91e293dfcf4867a207f786274d6e7dd279007c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 17 Jan 2011 19:44:46 +0000 Subject: correct assertion --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 325b8254b5..03d9134d69 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2946,7 +2946,7 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) PyObject *slots_a, *slots_b; assert(base == b->tp_base); - assert(equiv_structs(a, base) && equiv_structs(b, base)); + assert(!equiv_structs(a, base) && !equiv_structs(b, base)); size = base->tp_basicsize; if (a->tp_dictoffset == size && b->tp_dictoffset == size) size += sizeof(PyObject *); -- cgit v1.2.1 From 4c123bb1463999ddfff17c0d2f92264a8c87df01 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 17 Jan 2011 19:54:55 +0000 Subject: remove unneeded assertion --- Objects/typeobject.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 03d9134d69..db7828a2fc 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2946,7 +2946,6 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) PyObject *slots_a, *slots_b; assert(base == b->tp_base); - assert(!equiv_structs(a, base) && !equiv_structs(b, base)); size = base->tp_basicsize; if (a->tp_dictoffset == size && b->tp_dictoffset == size) size += sizeof(PyObject *); -- cgit v1.2.1 From e4e9817502d68a4747762d674b23d0a173724769 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 18 Jan 2011 18:57:52 +0000 Subject: Issue #10451: memoryview objects could allow to mutate a readable buffer. Initial patch by Ross Lagerwall. --- Objects/memoryobject.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index a05b97b977..7782076a5b 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -52,9 +52,6 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) { int res = 0; CHECK_RELEASED_INT(self); - /* XXX for whatever reason fixing the flags seems necessary */ - if (self->view.readonly) - flags &= ~PyBUF_WRITABLE; if (self->view.obj != NULL) res = PyObject_GetBuffer(self->view.obj, view, flags); if (view) -- cgit v1.2.1 From 9e4e99dd005dbdf7c7b753e6b01037399e859f55 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 29 Jan 2011 11:15:35 +0000 Subject: Issue #11302: missing type check on _string.formatter_field_name_split and _string.formatter_parser caused crash. Originial patch by haypo, reviewed by me, okayed by Georg. --- Objects/stringlib/string_format.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 40535457f3..c1a6d1d531 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -1192,6 +1192,11 @@ formatter_parser(PyObject *ignored, STRINGLIB_OBJECT *self) { formatteriterobject *it; + if (!PyUnicode_Check(self)) { + PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); + return NULL; + } + it = PyObject_New(formatteriterobject, &PyFormatterIter_Type); if (it == NULL) return NULL; @@ -1332,6 +1337,11 @@ formatter_field_name_split(PyObject *ignored, STRINGLIB_OBJECT *self) PyObject *first_obj = NULL; PyObject *result = NULL; + if (!PyUnicode_Check(self)) { + PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); + return NULL; + } + it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type); if (it == NULL) return NULL; -- cgit v1.2.1 From 85c1198c9052c6537f60f6bc629304c10dbbdd50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sat, 5 Feb 2011 20:35:29 +0000 Subject: Issue #11067: Add PyType_GetFlags, to support PyUnicode_Check in the limited ABI --- Objects/typeobject.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index db7828a2fc..e9c7591b81 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1904,6 +1904,12 @@ type_init(PyObject *cls, PyObject *args, PyObject *kwds) return res; } +long +PyType_GetFlags(PyTypeObject *type) +{ + return type->tp_flags; +} + static PyObject * type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { -- cgit v1.2.1 From 7165d8a8955c690083cd25c6836ab9a648872027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Fri, 11 Feb 2011 20:50:24 +0000 Subject: Issue #11134: Add missing fields to typeslots.h. Reviewed by Georg Brandl. --- Objects/typeslots.inc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Objects') diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index d4872f6aad..0494a32aa9 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -70,3 +70,6 @@ offsetof(PyHeapTypeObject, ht_type.tp_setattr), offsetof(PyHeapTypeObject, ht_type.tp_setattro), offsetof(PyHeapTypeObject, ht_type.tp_str), offsetof(PyHeapTypeObject, ht_type.tp_traverse), +offsetof(PyHeapTypeObject, ht_type.tp_members), +offsetof(PyHeapTypeObject, ht_type.tp_getset), +offsetof(PyHeapTypeObject, ht_type.tp_free), -- cgit v1.2.1 From 934616599f5f0bab03e7484e6bb1092ea265e5c5 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 19 Feb 2011 21:47:02 +0000 Subject: #11249: in PyType_FromSpec, copy tp_doc slot since it usually will point to a static string literal which should not be deallocated together with the type. --- Objects/typeobject.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e9c7591b81..b1fe44ebe4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2347,6 +2347,17 @@ PyObject* PyType_FromSpec(PyType_Spec *spec) goto fail; } *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + + /* need to make a copy of the docstring slot, which usually + points to a static string literal */ + if (slot->slot == Py_tp_doc) { + ssize_t len = strlen(slot->pfunc)+1; + char *tp_doc = PyObject_MALLOC(len); + if (tp_doc == NULL) + goto fail; + memcpy(tp_doc, slot->pfunc, len); + res->ht_type.tp_doc = tp_doc; + } } return (PyObject*)res; -- cgit v1.2.1 From a11dd18f2caa2b7ce7a61b73aae1468924357898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Mon, 21 Feb 2011 16:26:47 +0000 Subject: Merged revisions 88456 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88456 | martin.v.loewis | 2011-02-21 17:24:00 +0100 (Mo, 21 Feb 2011) | 2 lines - Check for NULL result in PyType_FromSpec. ........ --- Objects/typeobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b1fe44ebe4..7a1aa77e3f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2330,6 +2330,8 @@ PyObject* PyType_FromSpec(PyType_Spec *spec) char *res_start = (char*)res; PyType_Slot *slot; + if (res == NULL) + return NULL; res->ht_name = PyUnicode_FromString(spec->name); if (!res->ht_name) goto fail; -- cgit v1.2.1 From bebc152955e1fa80e482ab8cb31bcce1a8298c0e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Feb 2011 12:14:22 +0000 Subject: Merged revisions 88481 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r88481 | victor.stinner | 2011-02-21 22:13:44 +0100 (lun., 21 févr. 2011) | 4 lines Fix PyUnicode_FromFormatV("%c") for non-BMP char Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on narrow build. ........ --- Objects/unicodeobject.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 456719685d..423a53383a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -813,8 +813,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) switch (*f) { case 'c': + { +#ifndef Py_UNICODE_WIDE + int ordinal = va_arg(count, int); + if (ordinal > 0xffff) + n += 2; + else + n++; +#else (void)va_arg(count, int); - /* fall through... */ + n++; +#endif + break; + } case '%': n++; break; @@ -992,8 +1003,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) switch (*f) { case 'c': - *s++ = va_arg(vargs, int); + { + int ordinal = va_arg(vargs, int); +#ifndef Py_UNICODE_WIDE + if (ordinal > 0xffff) { + ordinal -= 0x10000; + *s++ = 0xD800 | (ordinal >> 10); + *s++ = 0xDC00 | (ordinal & 0x3FF); + } else +#endif + *s++ = ordinal; break; + } case 'd': makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, width, precision, 'd'); -- cgit v1.2.1 From df3c6cd2ff7f7ce78c54e26bdafb5922901e0be0 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 24 Feb 2011 20:53:48 +0000 Subject: Merged revisions 88550 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ r88550 | antoine.pitrou | 2011-02-24 21:50:49 +0100 (jeu., 24 févr. 2011) | 4 lines Issue #11286: Raise a ValueError from calling PyMemoryView_FromBuffer with a buffer struct having a NULL data pointer. ........ --- Objects/memoryobject.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Objects') diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 7782076a5b..2e32b2a0e9 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -75,6 +75,11 @@ PyMemoryView_FromBuffer(Py_buffer *info) { PyMemoryViewObject *mview; + if (info->buf == NULL) { + PyErr_SetString(PyExc_ValueError, + "cannot make memory view from a buffer with a NULL data pointer"); + return NULL; + } mview = (PyMemoryViewObject *) PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); if (mview == NULL) -- cgit v1.2.1 From 2ccd52a7a533c93353341a3af8855a65ff20f190 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 1 Mar 2011 22:48:49 +0000 Subject: Merged revisions 88697 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88697 | victor.stinner | 2011-03-01 23:46:52 +0100 (mar., 01 mars 2011) | 4 lines Issue #11246: Fix PyUnicode_FromFormat("%V") Decode the byte string from UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). Patch written by Ray Allen. ........ --- Objects/unicodeobject.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 423a53383a..cbda72532d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -752,7 +752,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) if (*f == '%') { if (*(f+1)=='%') continue; - if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A') + if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A' || *(f+1) == 'V') ++callcount; while (Py_ISDIGIT((unsigned)*f)) width = (width*10) + *f++ - '0'; @@ -872,12 +872,20 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) { PyObject *obj = va_arg(count, PyObject *); const char *str = va_arg(count, const char *); + PyObject *str_obj; assert(obj || str); assert(!obj || PyUnicode_Check(obj)); - if (obj) + if (obj) { n += PyUnicode_GET_SIZE(obj); - else - n += strlen(str); + *callresult++ = NULL; + } + else { + str_obj = PyUnicode_DecodeUTF8(str, strlen(str), "replace"); + if (!str_obj) + goto fail; + n += PyUnicode_GET_SIZE(str_obj); + *callresult++ = str_obj; + } break; } case 'S': @@ -1080,14 +1088,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) case 'V': { PyObject *obj = va_arg(vargs, PyObject *); - const char *str = va_arg(vargs, const char *); + 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); + Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(*callresult), + PyUnicode_GET_SIZE(*callresult)); + s += PyUnicode_GET_SIZE(*callresult); + Py_DECREF(*callresult); } + ++callresult; break; } case 'S': @@ -1144,7 +1156,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs) if (callresults) { PyObject **callresult2 = callresults; while (callresult2 < callresult) { - Py_DECREF(*callresult2); + Py_XDECREF(*callresult2); ++callresult2; } PyObject_Free(callresults); -- cgit v1.2.1 From a9a141b4aa3306686385f4d32f2efb31184d68bf Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 4 Mar 2011 05:10:57 +0000 Subject: Merged revisions 88735 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r88735 | eli.bendersky | 2011-03-04 06:55:25 +0200 (Fri, 04 Mar 2011) | 2 lines Issue #11386: Fixed the exception thrown by bytearray.pop() for empty bytearrays ........ --- Objects/bytearrayobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 74483544c0..aefec9425f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2285,8 +2285,8 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args) return NULL; if (n == 0) { - PyErr_SetString(PyExc_OverflowError, - "cannot pop an empty bytearray"); + PyErr_SetString(PyExc_IndexError, + "pop from empty bytearray"); return NULL; } if (where < 0) -- cgit v1.2.1 From 86a82473160b5445dc845d52dc9382c8c03993d9 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Fri, 15 Apr 2011 08:15:40 +0300 Subject: #11845: Fix typo in rangeobject.c that caused a crash in compute_slice_indices. Patch by Daniel Urban. --- Objects/rangeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index cff2ce4741..58d373c0b9 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -472,7 +472,7 @@ compute_slice_indices(rangeobject *r, PySliceObject *slice, if (tmp_stop == NULL) goto Fail; } else { tmp_stop = r->length; - Py_INCREF(tmp_start); + Py_INCREF(tmp_stop); } } } -- cgit v1.2.1 From aa039cee1babca74cc172aae2886c7c2da30ea8d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 27 Apr 2011 00:24:21 +0200 Subject: Issue #10914: Initialize correctly the filesystem codec when creating a new subinterpreter to fix a bootstrap issue with codecs implemented in Python, as the ISO-8859-15 codec. Add fscodec_initialized attribute to the PyInterpreterState structure. --- Objects/unicodeobject.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 1f1fe8e6fa..7a70a5e917 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1626,7 +1626,17 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) PyUnicode_GET_SIZE(unicode), "surrogateescape"); #else - if (Py_FileSystemDefaultEncoding) { + PyInterpreterState *interp = PyThreadState_GET()->interp; + /* Bootstrap check: if the filesystem codec is implemented in Python, we + cannot use it to encode and decode filenames before it is loaded. Load + the Python codec requires to encode at least its own filename. Use the C + version of the locale codec until the codec registry is initialized and + the Python codec is loaded. + + Py_FileSystemDefaultEncoding is shared between all interpreters, we + cannot only rely on it: check also interp->fscodec_initialized for + subinterpreters. */ + if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) { return PyUnicode_AsEncodedString(unicode, Py_FileSystemDefaultEncoding, "surrogateescape"); @@ -1818,12 +1828,17 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) #elif defined(__APPLE__) return PyUnicode_DecodeUTF8(s, size, "surrogateescape"); #else - /* During the early bootstrapping process, Py_FileSystemDefaultEncoding - can be undefined. If it is case, decode using UTF-8. The following assumes - that Py_FileSystemDefaultEncoding is set to a built-in encoding during the - bootstrapping process where the codecs aren't ready yet. - */ - if (Py_FileSystemDefaultEncoding) { + PyInterpreterState *interp = PyThreadState_GET()->interp; + /* Bootstrap check: if the filesystem codec is implemented in Python, we + cannot use it to encode and decode filenames before it is loaded. Load + the Python codec requires to encode at least its own filename. Use the C + version of the locale codec until the codec registry is initialized and + the Python codec is loaded. + + Py_FileSystemDefaultEncoding is shared between all interpreters, we + cannot only rely on it: check also interp->fscodec_initialized for + subinterpreters. */ + if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) { return PyUnicode_Decode(s, size, Py_FileSystemDefaultEncoding, "surrogateescape"); -- cgit v1.2.1 From e7365b89a6a0887d55f214ec60b1ccb657f7c361 Mon Sep 17 00:00:00 2001 From: Daniel Stutzbach Date: Wed, 4 May 2011 12:46:28 -0700 Subject: #11335: Fix memory leak after key function failure in sort --- Objects/listobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 18713abde1..73624f0b74 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1944,6 +1944,8 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (keys[i] == NULL) { for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); + if (keys != &ms.temparray[saved_ob_size+1]) + PyMem_FREE(keys); goto keyfunc_fail; } } -- cgit v1.2.1 From 6e85ed49846d56eac967260e9cfc8b4f5087292e Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 27 Jun 2011 09:06:45 -0700 Subject: Fix closes Issue12385 - Clarify maketrans method docstring for bytes and bytearray object. --- Objects/bytes_methods.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index ef91b7f337..7233cea409 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -366,10 +366,10 @@ _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len) PyDoc_STRVAR_shared(_Py_maketrans__doc__, "B.maketrans(frm, to) -> translation table\n\ \n\ -Return a translation table (a bytes object of length 256)\n\ -suitable for use in bytes.translate where each byte in frm is\n\ -mapped to the byte at the same position in to.\n\ -The strings frm and to must be of the same length."); +Return a translation table (a bytes object of length 256) suitable\n\ +for use in the bytes or bytearray translate method where each byte\n\ +in frm is mapped to the byte at the same position in to.\n\ +The bytes objects frm and to must be of the same length."); static Py_ssize_t _getbuffer(PyObject *obj, Py_buffer *view) -- cgit v1.2.1 From fbb338734d62ac8c6dc72205a9b2d2fcaea6ffc9 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 3 Jul 2011 21:03:16 -0700 Subject: Fix closes issue12471 - wrong TypeError message when '%i' format spec was used. --- Objects/unicodeobject.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7a70a5e917..03807a45b9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9689,8 +9689,6 @@ PyObject *PyUnicode_Format(PyObject *format, case 'o': case 'x': case 'X': - if (c == 'i') - c = 'd'; isnumok = 0; if (PyNumber_Check(v)) { PyObject *iobj=NULL; @@ -9705,7 +9703,7 @@ PyObject *PyUnicode_Format(PyObject *format, if (iobj!=NULL) { if (PyLong_Check(iobj)) { isnumok = 1; - temp = formatlong(iobj, flags, prec, c); + temp = formatlong(iobj, flags, prec, (c == 'i'? 'd': c)); Py_DECREF(iobj); if (!temp) goto onError; -- cgit v1.2.1 From 4fd9d6af13da2a55aa218a3bebcb11af924d79df Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 12 Jul 2011 21:57:15 +0200 Subject: Issue #12149: Update the method cache after a type's dictionnary gets cleared by the garbage collector. This fixes a segfault when an instance and its type get caught in a reference cycle, and the instance's deallocator calls one of the methods on the type (e.g. when subclassing IOBase). Diagnosis and patch by Davide Rizzo. --- Objects/typeobject.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3c724fd7c6..97ccf0118e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -967,6 +967,8 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); + PyType_Modified(type); + /* Can't reference self beyond this point */ Py_DECREF(type); -- cgit v1.2.1 From a3c332a1954a7f13138e7130532a46204c59ea7d Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Mon, 18 Jul 2011 14:03:41 -0400 Subject: Closes #12579. Positional fields with str.format_map() now raise a ValueError instead of SystemError. --- Objects/stringlib/string_format.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Objects') diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 6f10727e24..6c7adcb01e 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -511,6 +511,16 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, Py_DECREF(key); } else { + /* If args is NULL, we have a format string with a positional field + with only kwargs to retrieve it from. This can only happen when + used with format_map(), where positional arguments are not + allowed. */ + if (args == NULL) { + PyErr_SetString(PyExc_ValueError, "Format string contains " + "positional fields"); + goto error; + } + /* look up in args */ obj = PySequence_GetItem(args, index); if (obj == NULL) -- cgit v1.2.1 From 843467b1634c8057d61e362b30f678498fc5b2e9 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Wed, 27 Jul 2011 23:33:54 +0800 Subject: Fix closes Issue12621 - Fix docstrings of find and rfind methods of bytes/bytearry/unicodeobject. --- Objects/bytearrayobject.c | 4 ++-- Objects/bytesobject.c | 4 ++-- Objects/unicodeobject.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 7a7410405e..0b45394a4a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1102,7 +1102,7 @@ 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 s[start,end]. Optional\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."); @@ -1172,7 +1172,7 @@ 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 s[start,end]. Optional\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."); diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 38458ef9a6..8e35fa9276 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1273,7 +1273,7 @@ PyDoc_STRVAR(find__doc__, "B.find(sub[, start[, end]]) -> int\n\ \n\ Return the lowest index in B where substring sub is found,\n\ -such that sub is contained within s[start:end]. Optional\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."); @@ -1312,7 +1312,7 @@ PyDoc_STRVAR(rfind__doc__, "B.rfind(sub[, start[, end]]) -> int\n\ \n\ Return the highest index in B where substring sub is found,\n\ -such that sub is contained within s[start:end]. Optional\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."); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 03807a45b9..75da0e7e8d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7587,7 +7587,7 @@ 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\ +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."); @@ -8513,7 +8513,7 @@ 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\ +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."); -- cgit v1.2.1 From 1d912c419a16c976af2ef2c6722dbab0ad4b3e1b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 29 Jul 2011 22:44:42 -0500 Subject: remove duplicated type ready --- Objects/object.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index a91c46a391..3240bc37be 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1538,9 +1538,6 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyNone_Type) < 0) Py_FatalError("Can't initialize None type"); - if (PyType_Ready(Py_Ellipsis->ob_type) < 0) - Py_FatalError("Can't initialize type(Ellipsis)"); - if (PyType_Ready(&PyNotImplemented_Type) < 0) Py_FatalError("Can't initialize NotImplemented type"); -- cgit v1.2.1 From fe205f2eeb7d9001864bf8754ff18ad34d940976 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 12 Aug 2011 22:17:18 -0500 Subject: in narrow builds, make sure to test codepoints as identifier characters (closes #12732) This fixes the use of Unicode identifiers outside the BMP in narrow builds. --- Objects/unicodeobject.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 75da0e7e8d..a48b8b41b1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7972,14 +7972,30 @@ unicode_isnumeric(PyUnicodeObject *self) return PyBool_FromLong(1); } +static Py_UCS4 +decode_ucs4(const Py_UNICODE *s, Py_ssize_t *i, Py_ssize_t size) +{ + Py_UCS4 ch; + assert(*i < size); + ch = s[(*i)++]; +#ifndef Py_UNICODE_WIDE + if ((ch & 0xfffffc00) == 0xd800 && + *i < size + && (s[*i] & 0xFFFFFC00) == 0xDC00) + ch = ((Py_UCS4)ch << 10UL) + (Py_UCS4)(s[(*i)++]) - 0x35fdc00; +#endif + return ch; +} + int PyUnicode_IsIdentifier(PyObject *self) { - register const Py_UNICODE *p = PyUnicode_AS_UNICODE((PyUnicodeObject*)self); - register const Py_UNICODE *e; + Py_ssize_t i = 0, size = PyUnicode_GET_SIZE(self); + Py_UCS4 first; + const Py_UNICODE *p = PyUnicode_AS_UNICODE((PyUnicodeObject*)self); /* Special case for empty strings */ - if (PyUnicode_GET_SIZE(self) == 0) + if (!size) return 0; /* PEP 3131 says that the first character must be in @@ -7990,14 +8006,13 @@ PyUnicode_IsIdentifier(PyObject *self) definition of XID_Start and XID_Continue, it is sufficient to check just for these, except that _ must be allowed as starting an identifier. */ - if (!_PyUnicode_IsXidStart(*p) && *p != 0x5F /* LOW LINE */) + first = decode_ucs4(p, &i, size); + if (!_PyUnicode_IsXidStart(first) && first != 0x5F /* LOW LINE */) return 0; - e = p + PyUnicode_GET_SIZE(self); - for (p++; p < e; p++) { - if (!_PyUnicode_IsXidContinue(*p)) + while (i < size) + if (!_PyUnicode_IsXidContinue(decode_ucs4(p, &i, size))) return 0; - } return 1; } -- cgit v1.2.1 From cc0799a75e8e10efa4f74a1cfd4b1213e7cd4cfd Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 15 Aug 2011 09:09:57 +0300 Subject: #12266: Fix str.capitalize() to correctly uppercase/lowercase titlecased and cased non-letter characters. --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a48b8b41b1..77f8dd5a81 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6658,13 +6658,13 @@ int fixcapitalize(PyUnicodeObject *self) if (len == 0) return 0; - if (Py_UNICODE_ISLOWER(*s)) { + if (!Py_UNICODE_ISUPPER(*s)) { *s = Py_UNICODE_TOUPPER(*s); status = 1; } s++; while (--len > 0) { - if (Py_UNICODE_ISUPPER(*s)) { + if (!Py_UNICODE_ISLOWER(*s)) { *s = Py_UNICODE_TOLOWER(*s); status = 1; } -- cgit v1.2.1 From 311296162e4c2168ffd3c2fea508b7888f31801e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 16 Aug 2011 22:26:48 -0500 Subject: fix possible refleaks --- Objects/typeobject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 97a94a7640..856a4a5f38 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2093,8 +2093,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) PyUnicode_CompareWithASCIIString(tmp, "__weakref__") == 0)) continue; tmp =_Py_Mangle(name, tmp); - if (!tmp) + if (!tmp) { + Py_DECREF(newslots); goto bad_slots; + } PyList_SET_ITEM(newslots, j, tmp); j++; } -- cgit v1.2.1 From a5ac2384ee1f31b520be29c44d4657a3ca891555 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 18 Aug 2011 10:48:50 -0500 Subject: NUL -> NULL --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 77f8dd5a81..1f2d91913e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1897,7 +1897,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); if (size != strlen(data)) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + PyErr_SetString(PyExc_TypeError, "embedded NULL character"); Py_DECREF(output); return 0; } -- cgit v1.2.1 From eb481531131117efe0aedd8bb246d798b981a9c9 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 18 Aug 2011 13:51:47 -0500 Subject: the named of the character is actually NUL --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 1f2d91913e..77f8dd5a81 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1897,7 +1897,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); if (size != strlen(data)) { - PyErr_SetString(PyExc_TypeError, "embedded NULL character"); + PyErr_SetString(PyExc_TypeError, "embedded NUL character"); Py_DECREF(output); return 0; } -- cgit v1.2.1 From 269eece038113c5fb3888f0eaac8c8da9cfe0f34 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 20 Aug 2011 14:15:03 +0200 Subject: Issue #12791: Break reference cycles early when a generator exits with an exception. --- Objects/genobject.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Objects') diff --git a/Objects/genobject.c b/Objects/genobject.c index 3fa1b4e726..01cd44ae59 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -100,6 +100,17 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) if (!result || f->f_stacktop == NULL) { /* generator can't be rerun, so release the frame */ + /* first clean reference cycle through stored exception traceback */ + PyObject *t, *v, *tb; + t = f->f_exc_type; + v = f->f_exc_value; + tb = f->f_exc_traceback; + f->f_exc_type = NULL; + f->f_exc_value = NULL; + f->f_exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); Py_DECREF(f); gen->gi_frame = NULL; } -- cgit v1.2.1 From e1ab979e3fa635cf61ddce5f0b11809ca8fe79c5 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Mon, 22 Aug 2011 14:08:38 +0300 Subject: #9200: The str.is* methods now work with strings that contain non-BMP characters even in narrow Unicode builds. --- Objects/unicodeobject.c | 101 ++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 41 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 77f8dd5a81..8567a9f2db 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6442,6 +6442,37 @@ int PyUnicode_EncodeDecimal(Py_UNICODE *s, start = 0; \ } +/* _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 + Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, @@ -7705,8 +7736,8 @@ unicode_islower(PyUnicodeObject *self) e = p + PyUnicode_GET_SIZE(self); cased = 0; - for (; p < e; p++) { - register const Py_UNICODE ch = *p; + while (p < e) { + const Py_UCS4 ch = _Py_UNICODE_NEXT(p, e); if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) return PyBool_FromLong(0); @@ -7739,8 +7770,8 @@ unicode_isupper(PyUnicodeObject *self) e = p + PyUnicode_GET_SIZE(self); cased = 0; - for (; p < e; p++) { - register const Py_UNICODE ch = *p; + while (p < e) { + const Py_UCS4 ch = _Py_UNICODE_NEXT(p, e); if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch)) return PyBool_FromLong(0); @@ -7777,8 +7808,8 @@ unicode_istitle(PyUnicodeObject *self) e = p + PyUnicode_GET_SIZE(self); cased = 0; previous_is_cased = 0; - for (; p < e; p++) { - register const Py_UNICODE ch = *p; + while (p < e) { + const Py_UCS4 ch = _Py_UNICODE_NEXT(p, e); if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) { if (previous_is_cased) @@ -7820,8 +7851,9 @@ unicode_isspace(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISSPACE(*p)) + while (p < e) { + const Py_UCS4 ch = _Py_UNICODE_NEXT(p, e); + if (!Py_UNICODE_ISSPACE(ch)) return PyBool_FromLong(0); } return PyBool_FromLong(1); @@ -7849,8 +7881,8 @@ unicode_isalpha(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISALPHA(*p)) + while (p < e) { + if (!Py_UNICODE_ISALPHA(_Py_UNICODE_NEXT(p, e))) return PyBool_FromLong(0); } return PyBool_FromLong(1); @@ -7878,8 +7910,9 @@ unicode_isalnum(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISALNUM(*p)) + while (p < e) { + const Py_UCS4 ch = _Py_UNICODE_NEXT(p, e); + if (!Py_UNICODE_ISALNUM(ch)) return PyBool_FromLong(0); } return PyBool_FromLong(1); @@ -7907,8 +7940,8 @@ unicode_isdecimal(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISDECIMAL(*p)) + while (p < e) { + if (!Py_UNICODE_ISDECIMAL(_Py_UNICODE_NEXT(p, e))) return PyBool_FromLong(0); } return PyBool_FromLong(1); @@ -7936,8 +7969,8 @@ unicode_isdigit(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISDIGIT(*p)) + while (p < e) { + if (!Py_UNICODE_ISDIGIT(_Py_UNICODE_NEXT(p, e))) return PyBool_FromLong(0); } return PyBool_FromLong(1); @@ -7965,37 +7998,22 @@ unicode_isnumeric(PyUnicodeObject *self) return PyBool_FromLong(0); e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISNUMERIC(*p)) + while (p < e) { + if (!Py_UNICODE_ISNUMERIC(_Py_UNICODE_NEXT(p, e))) return PyBool_FromLong(0); } return PyBool_FromLong(1); } -static Py_UCS4 -decode_ucs4(const Py_UNICODE *s, Py_ssize_t *i, Py_ssize_t size) -{ - Py_UCS4 ch; - assert(*i < size); - ch = s[(*i)++]; -#ifndef Py_UNICODE_WIDE - if ((ch & 0xfffffc00) == 0xd800 && - *i < size - && (s[*i] & 0xFFFFFC00) == 0xDC00) - ch = ((Py_UCS4)ch << 10UL) + (Py_UCS4)(s[(*i)++]) - 0x35fdc00; -#endif - return ch; -} - int PyUnicode_IsIdentifier(PyObject *self) { - Py_ssize_t i = 0, size = PyUnicode_GET_SIZE(self); - Py_UCS4 first; const Py_UNICODE *p = PyUnicode_AS_UNICODE((PyUnicodeObject*)self); + const Py_UNICODE *e; + Py_UCS4 first; /* Special case for empty strings */ - if (!size) + if (PyUnicode_GET_SIZE(self) == 0) return 0; /* PEP 3131 says that the first character must be in @@ -8006,12 +8024,13 @@ PyUnicode_IsIdentifier(PyObject *self) definition of XID_Start and XID_Continue, it is sufficient to check just for these, except that _ must be allowed as starting an identifier. */ - first = decode_ucs4(p, &i, size); + e = p + PyUnicode_GET_SIZE(self); + first = _Py_UNICODE_NEXT(p, e); if (!_PyUnicode_IsXidStart(first) && first != 0x5F /* LOW LINE */) return 0; - while (i < size) - if (!_PyUnicode_IsXidContinue(decode_ucs4(p, &i, size))) + while (p < e) + if (!_PyUnicode_IsXidContinue(_Py_UNICODE_NEXT(p, e))) return 0; return 1; } @@ -8046,8 +8065,8 @@ unicode_isprintable(PyObject *self) } e = p + PyUnicode_GET_SIZE(self); - for (; p < e; p++) { - if (!Py_UNICODE_ISPRINTABLE(*p)) { + while (p < e) { + if (!Py_UNICODE_ISPRINTABLE(_Py_UNICODE_NEXT(p, e))) { Py_RETURN_FALSE; } } -- cgit v1.2.1 From ba7060455b47c03ab37b2d116459a1bd1e960314 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 1 Sep 2011 16:32:31 -0400 Subject: make sure to initialize the method wrapper type --- Objects/descrobject.c | 9 +++------ Objects/object.c | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 93daefd75f..a786bae143 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -846,16 +846,13 @@ PyDictProxy_New(PyObject *dict) /* This has no reason to be in this file except that adding new files is a bit of a pain */ -/* forward */ -static PyTypeObject wrappertype; - typedef struct { PyObject_HEAD PyWrapperDescrObject *descr; PyObject *self; } wrapperobject; -#define Wrapper_Check(v) (Py_TYPE(v) == &wrappertype) +#define Wrapper_Check(v) (Py_TYPE(v) == &_PyMethodWrapper_Type) static void wrapper_dealloc(wrapperobject *wp) @@ -1021,7 +1018,7 @@ wrapper_traverse(PyObject *self, visitproc visit, void *arg) return 0; } -static PyTypeObject wrappertype = { +PyTypeObject _PyMethodWrapper_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "method-wrapper", /* tp_name */ sizeof(wrapperobject), /* tp_basicsize */ @@ -1070,7 +1067,7 @@ PyWrapper_New(PyObject *d, PyObject *self) assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), (PyObject *)PyDescr_TYPE(descr))); - wp = PyObject_GC_New(wrapperobject, &wrappertype); + wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); if (wp != NULL) { Py_INCREF(descr); wp->descr = descr; diff --git a/Objects/object.c b/Objects/object.c index 3240bc37be..694e7e719e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1625,6 +1625,9 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyWrapperDescr_Type) < 0) Py_FatalError("Can't initialize wrapper type"); + if (PyType_Ready(&_PyMethodWrapper_Type) < 0) + Py_FatalError("Can't initialize method wrapper type"); + if (PyType_Ready(&PyEllipsis_Type) < 0) Py_FatalError("Can't initialize ellipsis type"); -- cgit v1.2.1 From 4391045b0d22dbe7f58eafd470a0a225112fe43f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 6 Sep 2011 02:00:05 +0200 Subject: Fix PyUnicode_AsWideCharString() doc: size doesn't contain the null character Fix also spelling of the null character. --- Objects/unicodeobject.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8567a9f2db..7316abfc9c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1187,12 +1187,12 @@ PyUnicode_FromFormat(const char *format, ...) /* Helper function for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(): convert a Unicode object to a wide character string. - - If w is NULL: return the number of wide characters (including the nul + - If w is NULL: return the number of wide characters (including the null character) required to convert the unicode object. Ignore size argument. - - Otherwise: return the number of wide characters (excluding the nul + - Otherwise: return the number of wide characters (excluding the null character) written into w. Write at most size wide characters (including - the nul character). */ + the null character). */ static Py_ssize_t unicode_aswidechar(PyUnicodeObject *unicode, wchar_t *w, @@ -1240,7 +1240,7 @@ unicode_aswidechar(PyUnicodeObject *unicode, return w - worig; } else { - nchar = 1; /* nul character at the end */ + nchar = 1; /* null character at the end */ while (u != uend) { if (0xD800 <= u[0] && u[0] <= 0xDBFF && 0xDC00 <= u[1] && u[1] <= 0xDFFF) @@ -1278,7 +1278,7 @@ unicode_aswidechar(PyUnicodeObject *unicode, return w - worig; } else { - nchar = 1; /* nul character */ + nchar = 1; /* null character */ while (u != uend) { if (*u > 0xffff) nchar += 2; -- cgit v1.2.1 From 7349e2245546c3738c2843fe1e9386279b38be6c Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Mon, 12 Sep 2011 16:22:47 +0200 Subject: Issue #12963: PyLong_AsSize_t() now returns (size_t)-1 in all error cases. --- Objects/longobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/longobject.c b/Objects/longobject.c index 552f8f0b89..a0b16a66f2 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -525,8 +525,8 @@ PyLong_AsUnsignedLong(PyObject *vv) return x; } -/* Get a C unsigned long int from a long int object. - Returns -1 and sets an error condition if overflow occurs. */ +/* Get a C size_t from a long int object. Returns (size_t)-1 and sets + an error condition if overflow occurs. */ size_t PyLong_AsSize_t(PyObject *vv) @@ -562,7 +562,7 @@ PyLong_AsSize_t(PyObject *vv) if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C size_t"); - return (unsigned long) -1; + return (size_t) -1; } } return x; -- cgit v1.2.1 From 81876821244ec036452533279d4cd2908a302e4f Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 19 Sep 2011 19:18:37 +0100 Subject: Issue #12973: Fix undefined-behaviour-inducing overflow check in list_repeat. --- Objects/listobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 73624f0b74..36f8b9dc70 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -58,7 +58,7 @@ list_resize(PyListObject *self, Py_ssize_t newsize) if (newsize == 0) new_allocated = 0; items = self->ob_item; - if (new_allocated <= ((~(size_t)0) / sizeof(PyObject *))) + if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *))) PyMem_RESIZE(items, PyObject *, new_allocated); else items = NULL; @@ -510,9 +510,9 @@ list_repeat(PyListObject *a, Py_ssize_t n) PyObject *elem; if (n < 0) n = 0; - size = Py_SIZE(a) * n; - if (n && size/n != Py_SIZE(a)) + 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); -- cgit v1.2.1 From 9bc9113fb211375cdd2c19921fc7d8588a25216a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 6 Oct 2011 18:57:27 +0200 Subject: Issue #12911: Fix memory consumption when calculating the repr() of huge tuples or lists. This introduces a small private API for this common pattern. The issue has been discovered thanks to Martin's huge-mem buildbot. --- Objects/accu.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ Objects/listobject.c | 81 ++++++++++++++++------------------- Objects/tupleobject.c | 75 ++++++++++++++++----------------- 3 files changed, 185 insertions(+), 85 deletions(-) create mode 100644 Objects/accu.c (limited to 'Objects') diff --git a/Objects/accu.c b/Objects/accu.c new file mode 100644 index 0000000000..88e8f08f59 --- /dev/null +++ b/Objects/accu.c @@ -0,0 +1,114 @@ +/* Accumulator struct implementation */ + +#include "Python.h" + +static PyObject * +join_list_unicode(PyObject *lst) +{ + /* return ''.join(lst) */ + PyObject *sep, *ret; + sep = PyUnicode_FromStringAndSize("", 0); + ret = PyUnicode_Join(sep, lst); + Py_DECREF(sep); + return ret; +} + +int +_PyAccu_Init(_PyAccu *acc) +{ + /* Lazily allocated */ + acc->large = NULL; + acc->small = PyList_New(0); + if (acc->small == NULL) + return -1; + return 0; +} + +static int +flush_accumulator(_PyAccu *acc) +{ + Py_ssize_t nsmall = PyList_GET_SIZE(acc->small); + if (nsmall) { + int ret; + PyObject *joined; + if (acc->large == NULL) { + acc->large = PyList_New(0); + if (acc->large == NULL) + return -1; + } + joined = join_list_unicode(acc->small); + if (joined == NULL) + return -1; + if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) { + Py_DECREF(joined); + return -1; + } + ret = PyList_Append(acc->large, joined); + Py_DECREF(joined); + return ret; + } + return 0; +} + +int +_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode) +{ + Py_ssize_t nsmall; + assert(PyUnicode_Check(unicode)); + + if (PyList_Append(acc->small, unicode)) + return -1; + nsmall = PyList_GET_SIZE(acc->small); + /* Each item in a list of unicode objects has an overhead (in 64-bit + * builds) of: + * - 8 bytes for the list slot + * - 56 bytes for the header of the unicode object + * that is, 64 bytes. 100000 such objects waste more than 6MB + * compared to a single concatenated string. + */ + if (nsmall < 100000) + return 0; + return flush_accumulator(acc); +} + +PyObject * +_PyAccu_FinishAsList(_PyAccu *acc) +{ + int ret; + PyObject *res; + + ret = flush_accumulator(acc); + Py_CLEAR(acc->small); + if (ret) { + Py_CLEAR(acc->large); + return NULL; + } + res = acc->large; + acc->large = NULL; + return res; +} + +PyObject * +_PyAccu_Finish(_PyAccu *acc) +{ + PyObject *list, *res; + if (acc->large == NULL) { + list = acc->small; + acc->small = NULL; + } + else { + list = _PyAccu_FinishAsList(acc); + if (!list) + return NULL; + } + res = join_list_unicode(list); + Py_DECREF(list); + return res; +} + +void +_PyAccu_Destroy(_PyAccu *acc) +{ + Py_CLEAR(acc->small); + Py_CLEAR(acc->large); +} diff --git a/Objects/listobject.c b/Objects/listobject.c index 36f8b9dc70..00de597e56 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -321,70 +321,59 @@ static PyObject * list_repr(PyListObject *v) { Py_ssize_t i; - PyObject *s, *temp; - PyObject *pieces = NULL, *result = NULL; + PyObject *s = NULL; + _PyAccu acc; + static PyObject *sep = NULL; + + if (Py_SIZE(v) == 0) { + return PyUnicode_FromString("[]"); + } + + if (sep == NULL) { + sep = PyUnicode_FromString(", "); + if (sep == NULL) + return NULL; + } i = Py_ReprEnter((PyObject*)v); if (i != 0) { return i > 0 ? PyUnicode_FromString("[...]") : NULL; } - if (Py_SIZE(v) == 0) { - result = PyUnicode_FromString("[]"); - goto Done; - } + if (_PyAccu_Init(&acc)) + goto error; - pieces = PyList_New(0); - if (pieces == NULL) - goto Done; + s = PyUnicode_FromString("["); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); /* 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; + goto error; 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; + if (i > 0 && _PyAccu_Accumulate(&acc, sep)) + goto error; + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); } + s = PyUnicode_FromString("]"); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); - /* Add "[]" decorations to the first and last items. */ - assert(PyList_GET_SIZE(pieces) > 0); - s = PyUnicode_FromString("["); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyList_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; + Py_ReprLeave((PyObject *)v); + return _PyAccu_Finish(&acc); - s = PyUnicode_FromString("]"); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); - PyUnicode_AppendAndDel(&temp, s); - PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); - -Done: - Py_XDECREF(pieces); +error: + _PyAccu_Destroy(&acc); + Py_XDECREF(s); Py_ReprLeave((PyObject *)v); - return result; + return NULL; } static Py_ssize_t diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 72b79c917a..8aacd12114 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -240,13 +240,20 @@ static PyObject * tuplerepr(PyTupleObject *v) { Py_ssize_t i, n; - PyObject *s, *temp; - PyObject *pieces, *result = NULL; + PyObject *s = NULL; + _PyAccu acc; + static PyObject *sep = NULL; n = Py_SIZE(v); if (n == 0) return PyUnicode_FromString("()"); + if (sep == NULL) { + sep = PyUnicode_FromString(", "); + if (sep == NULL) + return NULL; + } + /* 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 @@ -256,52 +263,42 @@ tuplerepr(PyTupleObject *v) return i > 0 ? PyUnicode_FromString("(...)") : NULL; } - pieces = PyTuple_New(n); - if (pieces == NULL) - return NULL; + if (_PyAccu_Init(&acc)) + goto error; + + s = PyUnicode_FromString("("); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); /* Do repr() on each element. */ for (i = 0; i < n; ++i) { if (Py_EnterRecursiveCall(" while getting the repr of a tuple")) - goto Done; + goto error; s = PyObject_Repr(v->ob_item[i]); Py_LeaveRecursiveCall(); - if (s == NULL) - goto Done; - PyTuple_SET_ITEM(pieces, i, s); + if (i > 0 && _PyAccu_Accumulate(&acc, sep)) + goto error; + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); } + if (n > 1) + s = PyUnicode_FromString(")"); + else + s = PyUnicode_FromString(",)"); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); - /* Add "()" decorations to the first and last items. */ - assert(n > 0); - s = PyUnicode_FromString("("); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyTuple_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyUnicode_FromString(n == 1 ? ",)" : ")"); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, n-1); - PyUnicode_AppendAndDel(&temp, s); - PyTuple_SET_ITEM(pieces, n-1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); - -Done: - Py_DECREF(pieces); Py_ReprLeave((PyObject *)v); - return result; + return _PyAccu_Finish(&acc); + +error: + _PyAccu_Destroy(&acc); + Py_XDECREF(s); + Py_ReprLeave((PyObject *)v); + return NULL; } /* The addend 82520, was selected from the range(0, 1000000) for -- cgit v1.2.1 From 8d4e597abc999ca6659ba96945e3b7193286ee19 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 17 Oct 2011 13:09:27 -0400 Subject: plug possible refleak (closes #13199) --- Objects/sliceobject.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 51c53a8a11..d7b97c9699 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -320,9 +320,13 @@ slice_richcompare(PyObject *v, PyObject *w, int op) } t1 = PyTuple_New(3); + if (t1 == NULL) + return NULL; t2 = PyTuple_New(3); - if (t1 == NULL || t2 == NULL) + if (t2 == NULL) { + Py_DECREF(t1); return NULL; + } PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start); PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop); -- cgit v1.2.1 From bbb7d6f2449f7896f23883c6dea4175749a28260 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 18 Oct 2011 16:40:50 +0200 Subject: Issue #13188: When called without an explicit traceback argument, generator.throw() now gets the traceback from the passed exception's `__traceback__` attribute. Patch by Petri Lehtinen. --- Objects/genobject.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Objects') diff --git a/Objects/genobject.c b/Objects/genobject.c index 01cd44ae59..49e2adeaa0 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -261,6 +261,11 @@ gen_throw(PyGenObject *gen, PyObject *args) val = typ; typ = PyExceptionInstance_Class(typ); Py_INCREF(typ); + + if (tb == NULL) { + /* Returns NULL if there's no traceback */ + tb = PyException_GetTraceback(val); + } } } else { -- cgit v1.2.1 From fd4eb6bfbcd04a457ef475b22b9129fe81a19026 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 19 Oct 2011 16:57:40 -0400 Subject: adjust braces a bit --- Objects/genobject.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/genobject.c b/Objects/genobject.c index 49e2adeaa0..42608eff36 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -232,8 +232,9 @@ gen_throw(PyGenObject *gen, PyObject *args) /* First, check the traceback argument, replacing None with NULL. */ - if (tb == Py_None) + 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"); @@ -244,9 +245,8 @@ gen_throw(PyGenObject *gen, PyObject *args) Py_XINCREF(val); Py_XINCREF(tb); - if (PyExceptionClass_Check(typ)) { + if (PyExceptionClass_Check(typ)) PyErr_NormalizeException(&typ, &val, &tb); - } else if (PyExceptionInstance_Check(typ)) { /* Raising an instance. The value should be a dummy. */ @@ -262,10 +262,9 @@ gen_throw(PyGenObject *gen, PyObject *args) typ = PyExceptionInstance_Class(typ); Py_INCREF(typ); - if (tb == NULL) { + if (tb == NULL) /* Returns NULL if there's no traceback */ tb = PyException_GetTraceback(val); - } } } else { -- cgit v1.2.1 From 8a6fce2f337b3c623ee3091878fdd06bccc5b3fe Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 23 Oct 2011 22:04:16 +1000 Subject: Issue 1294232: Fix errors in metaclass calculation affecting some cases of metaclass inheritance. Patch by Daniel Urban. --- Objects/typeobject.c | 61 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 20 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 856a4a5f38..9f6240168e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1912,6 +1912,42 @@ PyType_GetFlags(PyTypeObject *type) return type->tp_flags; } +/* Determine the most derived metatype. */ +PyTypeObject * +_PyType_CalculateMetaclass(PyTypeObject *metatype, PyObject *bases) +{ + Py_ssize_t i, nbases; + PyTypeObject *winner; + PyObject *tmp; + PyTypeObject *tmptype; + + /* 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 = Py_TYPE(tmp); + if (PyType_IsSubtype(winner, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, winner)) { + winner = tmptype; + continue; + } + /* else: */ + 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; + } + return winner; +} + static PyObject * type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { @@ -1955,28 +1991,12 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) &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 = Py_TYPE(tmp); - 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"); + /* Determine the proper metatype to deal with this: */ + winner = _PyType_CalculateMetaclass(metatype, bases); + if (winner == NULL) { return NULL; } + if (winner != metatype) { if (winner->tp_new != type_new) /* Pass it to the winner */ return winner->tp_new(winner, args, kwds); @@ -1984,6 +2004,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } /* Adjust for empty tuple bases */ + nbases = PyTuple_GET_SIZE(bases); if (nbases == 0) { bases = PyTuple_Pack(1, &PyBaseObject_Type); if (bases == NULL) -- cgit v1.2.1 From 0a2ba8f6f37da18a6c34b4a7a57027735d97d734 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Mon, 24 Oct 2011 21:12:58 +0300 Subject: Issue #13018: Fix reference leaks in error paths in dictobject.c. Patch by Suman Saha. --- Objects/dictobject.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 3fa5cc4b95..79894e5604 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1314,14 +1314,18 @@ dict_fromkeys(PyObject *cls, PyObject *args) PyObject *key; Py_hash_t hash; - if (dictresize(mp, Py_SIZE(seq))) + 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)) + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); return NULL; + } } return d; } @@ -1332,14 +1336,18 @@ dict_fromkeys(PyObject *cls, PyObject *args) PyObject *key; Py_hash_t hash; - if (dictresize(mp, PySet_GET_SIZE(seq))) + 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)) + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); return NULL; + } } return d; } -- cgit v1.2.1 From 09eb1f607650d33ab7d2ae6efd3ca0b8f6e44d53 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sun, 30 Oct 2011 13:56:41 +0200 Subject: Avoid unnecessary recursive function calls (closes #10519) --- Objects/setobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 48edad8a31..9f39fcbadb 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1877,7 +1877,7 @@ set_contains(PySetObject *so, PyObject *key) tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return -1; - rv = set_contains(so, tmpkey); + rv = set_contains_key(so, tmpkey); Py_DECREF(tmpkey); } return rv; @@ -1942,7 +1942,7 @@ set_discard(PySetObject *so, PyObject *key) tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return NULL; - result = set_discard(so, tmpkey); + result = set_discard_key(so, tmpkey); Py_DECREF(tmpkey); return result; } -- cgit v1.2.1 From 793bc5109e2c4f606939dccdca3f9a6b5f6cbaa4 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sun, 30 Oct 2011 14:31:27 +0200 Subject: Fix the return value of set_discard (issue #10519) --- Objects/setobject.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 9f39fcbadb..69eb88933d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1942,9 +1942,10 @@ set_discard(PySetObject *so, PyObject *key) tmpkey = make_new_set(&PyFrozenSet_Type, key); if (tmpkey == NULL) return NULL; - result = set_discard_key(so, tmpkey); + rv = set_discard_key(so, tmpkey); Py_DECREF(tmpkey); - return result; + if (rv == -1) + return NULL; } Py_RETURN_NONE; } -- cgit v1.2.1 From 2c53e0c8092b8ba679d9b6b2b2b136d08dd846a4 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 30 Oct 2011 14:24:44 -0400 Subject: remove unused variable --- Objects/setobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/setobject.c b/Objects/setobject.c index 69eb88933d..3abeefb97d 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1931,7 +1931,7 @@ If the element is not a member, raise a KeyError."); static PyObject * set_discard(PySetObject *so, PyObject *key) { - PyObject *tmpkey, *result; + PyObject *tmpkey; int rv; rv = set_discard_key(so, key); -- cgit v1.2.1 From 802ed89e9f4aceb9ea1242a12ccbd28f0aa6f60a Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sat, 5 Nov 2011 23:20:57 +0200 Subject: Accept None as start and stop parameters for list.index() and tuple.index() Closes #13340. --- Objects/listobject.c | 14 +++++++++++--- Objects/tupleobject.c | 15 +++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 00de597e56..509795657a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2109,12 +2109,20 @@ listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); PyObject *v, *format_tuple, *err_string; + PyObject *start_obj = NULL, *stop_obj = NULL; static PyObject *err_format = NULL; - if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) + if (!PyArg_ParseTuple(args, "O|OO:index", &v, &start_obj, &stop_obj)) return NULL; + + if (start_obj != Py_None) + if (!_PyEval_SliceIndex(start_obj, &start)) + return NULL; + + if (stop_obj != Py_None) + if (!_PyEval_SliceIndex(stop_obj, &stop)) + return NULL; + if (start < 0) { start += Py_SIZE(self); if (start < 0) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 8aacd12114..6f893d9c68 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -483,12 +483,19 @@ static PyObject * tupleindex(PyTupleObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v; + PyObject *v, *start_obj = NULL, *stop_obj = NULL; - if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) + if (!PyArg_ParseTuple(args, "O|OO:index", &v, &start_obj, &stop_obj)) return NULL; + + if (start_obj != Py_None) + if (!_PyEval_SliceIndex(start_obj, &start)) + return NULL; + + if (stop_obj != Py_None) + if (!_PyEval_SliceIndex(stop_obj, &stop)) + return NULL; + if (start < 0) { start += Py_SIZE(self); if (start < 0) -- cgit v1.2.1 From b031ffa855fbd525506ad4504f35b4cac076b7d7 Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Sun, 6 Nov 2011 21:02:39 +0200 Subject: Revert "Accept None as start and stop parameters for list.index() and tuple.index()" Issue #13340. --- Objects/listobject.c | 14 +++----------- Objects/tupleobject.c | 15 ++++----------- 2 files changed, 7 insertions(+), 22 deletions(-) (limited to 'Objects') diff --git a/Objects/listobject.c b/Objects/listobject.c index 509795657a..00de597e56 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2109,20 +2109,12 @@ listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); PyObject *v, *format_tuple, *err_string; - PyObject *start_obj = NULL, *stop_obj = NULL; static PyObject *err_format = NULL; - if (!PyArg_ParseTuple(args, "O|OO:index", &v, &start_obj, &stop_obj)) + if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, + _PyEval_SliceIndex, &start, + _PyEval_SliceIndex, &stop)) return NULL; - - if (start_obj != Py_None) - if (!_PyEval_SliceIndex(start_obj, &start)) - return NULL; - - if (stop_obj != Py_None) - if (!_PyEval_SliceIndex(stop_obj, &stop)) - return NULL; - if (start < 0) { start += Py_SIZE(self); if (start < 0) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 6f893d9c68..8aacd12114 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -483,19 +483,12 @@ static PyObject * tupleindex(PyTupleObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v, *start_obj = NULL, *stop_obj = NULL; + PyObject *v; - if (!PyArg_ParseTuple(args, "O|OO:index", &v, &start_obj, &stop_obj)) + if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, + _PyEval_SliceIndex, &start, + _PyEval_SliceIndex, &stop)) return NULL; - - if (start_obj != Py_None) - if (!_PyEval_SliceIndex(start_obj, &start)) - return NULL; - - if (stop_obj != Py_None) - if (!_PyEval_SliceIndex(stop_obj, &stop)) - return NULL; - if (start < 0) { start += Py_SIZE(self); if (start < 0) -- cgit v1.2.1 From c5526372eb4a105d96d5b36dab49b326288ab6c6 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 11 Nov 2011 16:57:05 +0200 Subject: Issue #13161: fix doc strings of __i*__ operators --- Objects/typeobject.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 9f6240168e..7da961eaf2 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5556,25 +5556,25 @@ static slotdef slotdefs[] = { NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, "x[y:z] <==> x[y.__index__():z.__index__()]"), IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, - wrap_binaryfunc, "+"), + wrap_binaryfunc, "+="), IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, - wrap_binaryfunc, "-"), + wrap_binaryfunc, "-="), IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, - wrap_binaryfunc, "*"), + wrap_binaryfunc, "*="), IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, - wrap_binaryfunc, "%"), + wrap_binaryfunc, "%="), IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, - wrap_binaryfunc, "**"), + wrap_binaryfunc, "**="), IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, - wrap_binaryfunc, "<<"), + wrap_binaryfunc, "<<="), IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, - wrap_binaryfunc, ">>"), + wrap_binaryfunc, ">>="), IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, - wrap_binaryfunc, "&"), + wrap_binaryfunc, "&="), IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, - wrap_binaryfunc, "^"), + wrap_binaryfunc, "^="), IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, - wrap_binaryfunc, "|"), + 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, "/"), -- cgit v1.2.1 From d76bb7c70630bf8ba3e0cd36702791bf0f270338 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 15 Nov 2011 01:42:21 +0100 Subject: Issue #13333: The UTF-7 decoder now accepts lone surrogates (the encoder already accepts them). --- Objects/unicodeobject.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 7316abfc9c..8680726275 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2282,21 +2282,17 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s, *p++ = outCh; #endif surrogate = 0; + continue; } else { + *p++ = surrogate; surrogate = 0; - errmsg = "second surrogate missing"; - goto utf7Error; } } - else if (outCh >= 0xD800 && outCh <= 0xDBFF) { + if (outCh >= 0xD800 && outCh <= 0xDBFF) { /* first surrogate */ surrogate = outCh; } - else if (outCh >= 0xDC00 && outCh <= 0xDFFF) { - errmsg = "unexpected second surrogate"; - goto utf7Error; - } else { *p++ = outCh; } @@ -2306,8 +2302,8 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s, inShift = 0; s++; if (surrogate) { - errmsg = "second surrogate missing at end of shift sequence"; - goto utf7Error; + *p++ = surrogate; + surrogate = 0; } if (base64bits > 0) { /* left-over bits */ if (base64bits >= 6) { -- cgit v1.2.1 From 5eb27a453958201608425103e5836c775876b482 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 22 Nov 2011 01:45:37 +0100 Subject: Issue #13093: Fix error handling on PyUnicode_EncodeDecimal() * Add tests for PyUnicode_EncodeDecimal() and PyUnicode_TransformDecimalToASCII() * Remove the unused "e" variable in replace() --- Objects/unicodeobject.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 8680726275..d13c5470b3 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6323,11 +6323,10 @@ int PyUnicode_EncodeDecimal(Py_UNICODE *s, } /* All other characters are considered unencodable */ collstart = p; - collend = p+1; - while (collend < end) { + for (collend = p+1; collend < end; collend++) { if ((0 < *collend && *collend < 256) || - !Py_UNICODE_ISSPACE(*collend) || - Py_UNICODE_TODECIMAL(*collend)) + Py_UNICODE_ISSPACE(*collend) || + 0 <= Py_UNICODE_TODECIMAL(*collend)) break; } /* cache callback name lookup @@ -7004,7 +7003,7 @@ PyObject *replace(PyUnicodeObject *self, } } else { - Py_ssize_t n, i, j, e; + Py_ssize_t n, i, j; Py_ssize_t product, new_size, delta; Py_UNICODE *p; @@ -7036,7 +7035,6 @@ PyObject *replace(PyUnicodeObject *self, return NULL; i = 0; p = u->str; - e = self->length - str1->length; if (str1->length > 0) { while (n-- > 0) { /* look for next match */ -- cgit v1.2.1 From eee82e8687b28199e1b57149b1c8032733148b00 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 15 Dec 2011 14:15:31 +0100 Subject: Fix the fix for issue #12149: it was incorrect, although it had the side effect of appearing to resolve the issue. Thanks to Mark Shannon for noticing. --- Objects/typeobject.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7da961eaf2..de1e445ec0 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -967,8 +967,6 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); - PyType_Modified(type); - /* Can't reference self beyond this point */ Py_DECREF(type); @@ -2645,15 +2643,16 @@ type_clear(PyTypeObject *type) for heaptypes. */ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); - /* 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 + /* 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_dict: - It is a dict, so the collector will call its tp_clear. - tp_cache: Not used; if it were, it would be a dict. @@ -2670,6 +2669,9 @@ type_clear(PyTypeObject *type) 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; -- cgit v1.2.1 From 091d4329f886261808458c597ecae9f8611f39b8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 17 Dec 2011 23:18:07 +0100 Subject: Issue #11231: Fix bytes and bytearray docstrings Patch written by Brice Berna. --- Objects/bytearrayobject.c | 12 +++++------- Objects/bytesobject.c | 7 ++++--- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'Objects') diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 0b45394a4a..4202ff28e4 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2797,18 +2797,16 @@ bytearray_methods[] = { 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\ +bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\ +bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\ +bytearray() -> empty bytes array\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\ + - a bytes or a buffer object\n\ - any object implementing the buffer API.\n\ -\n\ -bytearray(int) -> bytearray\n\ -\n\ -Construct a zero-initialized bytearray of the given length."); + - an integer"); static PyObject *bytearray_iter(PyObject *seq); diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8e35fa9276..b10cb5d3de 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2721,13 +2721,14 @@ PyDoc_STRVAR(bytes_doc, "bytes(iterable_of_ints) -> bytes\n\ bytes(string, encoding[, errors]) -> bytes\n\ bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n\ -bytes(memory_view) -> bytes\n\ +bytes(int) -> bytes object of size given by the parameter initialized with null bytes\n\ +bytes() -> empty bytes object\n\ \n\ Construct an immutable array of bytes from:\n\ - an iterable yielding integers in range(256)\n\ - a text string encoded using the specified encoding\n\ - - a bytes or a buffer object\n\ - - any object implementing the buffer API."); + - any object implementing the buffer API.\n\ + - an integer"); static PyObject *bytes_iter(PyObject *seq); -- cgit v1.2.1 From d1d74b7eb95a0a59e91a27a73a3d802516aa68bc Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 18 Dec 2011 19:30:55 +0100 Subject: Small clarification in docstring of dict.update(): the positional argument is not required. --- Objects/dictobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 79894e5604..768351e224 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1973,9 +1973,9 @@ PyDoc_STRVAR(popitem__doc__, 2-tuple; but raise KeyError if D is empty."); PyDoc_STRVAR(update__doc__, -"D.update(E, **F) -> None. Update D from dict/iterable E and F.\n" -"If E has a .keys() method, does: for k in E: D[k] = E[k]\n\ -If E lacks .keys() method, does: for (k, v) in E: D[k] = v\n\ +"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__, -- cgit v1.2.1 From 941ef2634d2283d692966c5e3596abd940645399 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 20 Dec 2011 13:29:45 -0600 Subject: fix possible if unlikely leak --- Objects/unicodeobject.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d13c5470b3..c4cfe1bca0 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8888,9 +8888,13 @@ unicode_maketrans(PyUnicodeObject *null, PyObject *args) /* create entries for translating chars in x to those in y */ for (i = 0; i < PyUnicode_GET_SIZE(x); i++) { key = PyLong_FromLong(PyUnicode_AS_UNICODE(x)[i]); + if (!key) + goto err; value = PyLong_FromLong(PyUnicode_AS_UNICODE(y)[i]); - if (!key || !value) + if (!value) { + Py_DECREF(key); goto err; + } res = PyDict_SetItem(new, key, value); Py_DECREF(key); Py_DECREF(value); -- cgit v1.2.1 From a9cb20e5d95127a2f8bbedf914546517203f7a72 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 14 Jan 2012 15:31:34 -0800 Subject: Consolidate the occurrances of the prime used as the multiplier when hashing to a single #define instead of having several copies in several files. This excludes the Modules/ tree (datetime and expat both have a copy for their own purposes with no need for it to be the same). --- Objects/bytesobject.c | 2 +- Objects/tupleobject.c | 2 +- Objects/unicodeobject.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index b10cb5d3de..8249e5f6df 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -881,7 +881,7 @@ bytes_hash(PyBytesObject *a) p = (unsigned char *) a->ob_sval; x = *p << 7; while (--len >= 0) - x = (1000003*x) ^ *p++; + x = (_PyHASH_MULTIPLIER*x) ^ *p++; x ^= Py_SIZE(a); if (x == -1) x = -2; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 8aacd12114..f6dbc315d9 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -315,7 +315,7 @@ tuplehash(PyTupleObject *v) register Py_hash_t x, y; register Py_ssize_t len = Py_SIZE(v); register PyObject **p; - Py_hash_t mult = 1000003L; + Py_hash_t mult = _PyHASH_MULTIPLIER; x = 0x345678L; p = v->ob_item; while (--len >= 0) { diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c4cfe1bca0..20528b931d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7666,7 +7666,7 @@ unicode_hash(PyUnicodeObject *self) p = self->str; x = *p << 7; while (--len >= 0) - x = (1000003*x) ^ *p++; + x = (_PyHASH_MULTIPLIER*x) ^ *p++; x ^= Py_SIZE(self); if (x == -1) x = -2; -- cgit v1.2.1 From 38eb94936689a176b23d2908fe0e3fd08d1ef2de Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 18 Jan 2012 16:13:31 +0100 Subject: Fix leaking a RuntimeError objects when creating sub-interpreters --- Objects/exceptions.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 0106ba3df5..fc41853d26 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2093,27 +2093,29 @@ _PyExc_Init(void) preallocate_memerrors(); - 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 = PyUnicode_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); + if (!PyExc_RecursionErrorInst) { + 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 = PyUnicode_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); -- cgit v1.2.1 From c366f5fe519ed59f4268b7b005fd459d1f4ca181 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 18 Jan 2012 21:23:13 +0100 Subject: Fix refleaks in test_capi (this was easier than I thought!) --- Objects/exceptions.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index fc41853d26..e550591787 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1959,10 +1959,14 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, */ PyObject *PyExc_RecursionErrorInst = NULL; -#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ - Py_FatalError("exceptions bootstrapping error."); +#define PRE_INIT(TYPE) \ + if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ + if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ + Py_FatalError("exceptions bootstrapping error."); \ + Py_INCREF(PyExc_ ## TYPE); \ + } -#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \ +#define POST_INIT(TYPE) \ if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \ Py_FatalError("Module dictionary insertion problem."); -- cgit v1.2.1 From 3b1dde93232d3f0d2ac40cecf0751f98c1c36646 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 22 Jan 2012 21:31:21 +0100 Subject: Fix #13834: strip() strips leading and trailing whitespace. --- Objects/bytesobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8249e5f6df..a0d4cbd9ae 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1437,7 +1437,7 @@ PyDoc_STRVAR(strip__doc__, "B.strip([bytes]) -> bytes\n\ \n\ Strip leading and trailing bytes contained in the argument.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); +If the argument is omitted, strip leading and trailing ASCII whitespace."); static PyObject * bytes_strip(PyBytesObject *self, PyObject *args) { -- cgit v1.2.1 From cc0cabdf51fa0fdbdf7da71992b9d0804dea2614 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 27 Jan 2012 21:16:01 +0000 Subject: Issue #13889: Add missing _Py_SET_53BIT_PRECISION_* calls around uses of dtoa.c functions in float round. --- Objects/floatobject.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 09c0e961ba..e146a4fc7c 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -919,9 +919,12 @@ double_round(double x, int ndigits) { char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; int decpt, sign; PyObject *result = NULL; + _Py_SET_53BIT_PRECISION_HEADER; /* round to a decimal string */ + _Py_SET_53BIT_PRECISION_START; buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); + _Py_SET_53BIT_PRECISION_END; if (buf == NULL) { PyErr_NoMemory(); return NULL; @@ -944,7 +947,9 @@ double_round(double x, int ndigits) { /* 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"); -- cgit v1.2.1 From d7fbc18de7634910a3c5472cda5a17f49d0aa472 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 29 Jan 2012 18:36:34 +0100 Subject: Issue #13848: open() and the FileIO constructor now check for NUL characters in the file name. Patch by Hynek Schlawack. --- Objects/unicodeobject.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 20528b931d..f51d4d04be 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1866,6 +1866,19 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) } +int +_PyUnicode_HasNULChars(PyObject* s) +{ + static PyObject *nul = NULL; + + if (nul == NULL) + nul = PyUnicode_FromStringAndSize("\0", 1); + if (nul == NULL) + return -1; + return PyUnicode_Contains(s, nul); +} + + int PyUnicode_FSConverter(PyObject* arg, void* addr) { -- cgit v1.2.1 From 984d613dcec8ed97aeb4054b3055ee77a578c1c3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 29 Jan 2012 20:13:18 -0500 Subject: adjust declaration --- Objects/typeobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index de1e445ec0..e2316bd0ad 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2347,7 +2347,8 @@ static short slotoffsets[] = { #include "typeslots.inc" }; -PyObject* PyType_FromSpec(PyType_Spec *spec) +PyObject * +PyType_FromSpec(PyType_Spec *spec) { PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); char *res_start = (char*)res; -- cgit v1.2.1 From a70c2e3c9ee480638400009940609533343ca8c3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 29 Jan 2012 20:16:37 -0500 Subject: ready types returned from PyType_FromSpec --- Objects/typeobject.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e2316bd0ad..c3822abb0e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2386,6 +2386,9 @@ PyType_FromSpec(PyType_Spec *spec) } } + if (PyType_Ready(&res->ht_type) < 0) + goto fail; + return (PyObject*)res; fail: -- cgit v1.2.1 From 86462b082ee4701103e2b1ab6cc0f143fd06e392 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 3 Feb 2012 19:22:31 -0500 Subject: put returns on their own lines --- Objects/exceptions.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index e550591787..e01d6cfa19 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -213,7 +213,8 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val) return -1; } seq = PySequence_Tuple(val); - if (!seq) return -1; + if (!seq) + return -1; Py_CLEAR(self->args); self->args = seq; return 0; @@ -252,7 +253,8 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb) static PyObject * BaseException_get_context(PyObject *self) { PyObject *res = PyException_GetContext(self); - if (res) return res; /* new reference already returned above */ + if (res) + return res; /* new reference already returned above */ Py_RETURN_NONE; } @@ -278,7 +280,8 @@ BaseException_set_context(PyObject *self, PyObject *arg) { static PyObject * BaseException_get_cause(PyObject *self) { PyObject *res = PyException_GetCause(self); - if (res) return res; /* new reference already returned above */ + if (res) + return res; /* new reference already returned above */ Py_RETURN_NONE; } @@ -672,7 +675,8 @@ EnvironmentError_reduce(PyEnvironmentErrorObject *self) * file name given to EnvironmentError. */ if (PyTuple_GET_SIZE(args) == 2 && self->filename) { args = PyTuple_New(3); - if (!args) return NULL; + if (!args) + return NULL; tmp = PyTuple_GET_ITEM(self->args, 0); Py_INCREF(tmp); @@ -894,7 +898,8 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); info = PySequence_Tuple(info); - if (!info) return -1; + if (!info) + return -1; if (PyTuple_GET_SIZE(info) != 4) { /* not a very good error message, but it's what Python 2.4 gives */ -- cgit v1.2.1 From 833a4403aae9c3b84388cfc12cd5c49949ebe739 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 6 Feb 2012 11:28:45 -0500 Subject: bltinmod is borrowed, so it shouldn't be decrefed --- Objects/exceptions.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index e01d6cfa19..0651d1d577 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2127,7 +2127,6 @@ _PyExc_Init(void) } } - Py_DECREF(bltinmod); } void -- cgit v1.2.1 From 3b526090bea615bcb5f76d9ff38373e734ff3606 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 10 Feb 2012 08:46:54 -0500 Subject: this is only a borrowed ref in Brett's branch --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 0651d1d577..9daa12a4e9 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2126,7 +2126,7 @@ _PyExc_Init(void) Py_DECREF(args_tuple); } } - + Py_DECREF(bltinmod); } void -- cgit v1.2.1 From c930761487af7daa39b5398809c53620d2c8b93f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 14 Feb 2012 01:17:45 +0100 Subject: Issue #13913: normalize utf-8 codec name in UTF-8 decoder --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f51d4d04be..70856f5455 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2763,7 +2763,7 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s, outpos = p-PyUnicode_AS_UNICODE(unicode); if (unicode_decode_call_errorhandler( errors, &errorHandler, - "utf8", errmsg, + "utf-8", errmsg, &starts, &e, &startinpos, &endinpos, &exc, &s, &unicode, &outpos, &p)) goto onError; -- cgit v1.2.1 From 20ce47b070322a7293c118e60ca7681e6b40a07c Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 15 Feb 2012 02:51:43 +0100 Subject: Issue #13020: Fix a reference leak when allocating a structsequence object fails. Patch by Suman Saha. --- Objects/structseq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Objects') diff --git a/Objects/structseq.c b/Objects/structseq.c index ef17f49a31..ac4f980a06 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -129,6 +129,7 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) res = (PyStructSequence*) PyStructSequence_New(type); if (res == NULL) { + Py_DECREF(arg); return NULL; } for (i = 0; i < len; ++i) { -- cgit v1.2.1 From e7c88184588a5ccb3d044047e8887bc94abfc7e2 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 15 Feb 2012 02:52:58 +0100 Subject: Fix indentation --- Objects/structseq.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'Objects') diff --git a/Objects/structseq.c b/Objects/structseq.c index ac4f980a06..28cbb1901f 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -103,27 +103,27 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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; + "%.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; + "%.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; + "%.500s() takes a %zd-sequence (%zd-sequence given)", + type->tp_name, min_len, len); + Py_DECREF(arg); + return NULL; } } -- cgit v1.2.1 From 2ebad5661e95acc01c19456ffaf5dd39907015fe Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 19 Feb 2012 01:11:56 -0500 Subject: use Py_CLEAR --- Objects/funcobject.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 45f9f57578..2292a9ec98 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -889,9 +889,7 @@ sm_traverse(staticmethod *sm, visitproc visit, void *arg) static int sm_clear(staticmethod *sm) { - Py_XDECREF(sm->sm_callable); - sm->sm_callable = NULL; - + Py_CLEAR(sm->sm_callable); return 0; } -- cgit v1.2.1