summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c237
-rw-r--r--Objects/bytearrayobject.c974
-rw-r--r--Objects/bytes_methods.c282
-rw-r--r--Objects/capsule.c324
-rw-r--r--Objects/classobject.c9
-rw-r--r--Objects/cobject.c19
-rw-r--r--Objects/codeobject.c191
-rw-r--r--Objects/complexobject.c626
-rw-r--r--Objects/descrobject.c66
-rw-r--r--Objects/dictobject.c623
-rw-r--r--Objects/enumobject.c25
-rw-r--r--Objects/exceptions.c41
-rw-r--r--Objects/fileobject.c191
-rw-r--r--Objects/floatobject.c616
-rw-r--r--Objects/frameobject.c106
-rw-r--r--Objects/funcobject.c41
-rw-r--r--Objects/intobject.c187
-rw-r--r--Objects/listobject.c30
-rw-r--r--Objects/lnotab_notes.txt124
-rw-r--r--Objects/longobject.c1879
-rw-r--r--Objects/memoryobject.c842
-rw-r--r--Objects/object.c229
-rw-r--r--Objects/obmalloc.c191
-rw-r--r--Objects/setobject.c61
-rw-r--r--Objects/stringlib/README.txt16
-rw-r--r--Objects/stringlib/count.h16
-rw-r--r--Objects/stringlib/ctype.h1
-rw-r--r--Objects/stringlib/fastsearch.h148
-rw-r--r--Objects/stringlib/find.h149
-rw-r--r--Objects/stringlib/formatter.h1157
-rw-r--r--Objects/stringlib/localeutil.h254
-rw-r--r--Objects/stringlib/partition.h47
-rw-r--r--Objects/stringlib/split.h394
-rw-r--r--Objects/stringlib/string_format.h175
-rw-r--r--Objects/stringlib/stringdefs.h11
-rw-r--r--Objects/stringlib/transmogrify.h113
-rw-r--r--Objects/stringlib/unicodedefs.h22
-rw-r--r--Objects/stringobject.c812
-rw-r--r--Objects/tupleobject.c64
-rw-r--r--Objects/typeobject.c121
-rw-r--r--Objects/unicodectype.c607
-rw-r--r--Objects/unicodeobject.c1129
-rw-r--r--Objects/unicodetype_db.h4219
43 files changed, 10983 insertions, 6386 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index d53b17ffbf..1e79ddf4a3 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -93,7 +93,7 @@ Py_ssize_t
_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
{
static PyObject *hintstrobj = NULL;
- PyObject *ro;
+ PyObject *ro, *hintmeth;
Py_ssize_t rv;
/* try o.__len__() */
@@ -107,19 +107,22 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
PyErr_Clear();
}
- /* cache a hashed version of the attribute string */
- if (hintstrobj == NULL) {
- hintstrobj = PyString_InternFromString("__length_hint__");
- if (hintstrobj == NULL)
+ if (PyInstance_Check(o))
+ return defaultvalue;
+ /* try o.__length_hint__() */
+ hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
+ if (hintmeth == NULL) {
+ if (PyErr_Occurred())
return -1;
+ else
+ return defaultvalue;
}
-
- /* try o.__length_hint__() */
- ro = PyObject_CallMethodObjArgs(o, hintstrobj, NULL);
+ ro = PyObject_CallFunctionObjArgs(hintmeth, NULL);
+ Py_DECREF(hintmeth);
if (ro == NULL) {
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
!PyErr_ExceptionMatches(PyExc_AttributeError))
- return -1;
+ return -1;
PyErr_Clear();
return defaultvalue;
}
@@ -153,7 +156,7 @@ PyObject_GetItem(PyObject *o, PyObject *key)
"be integer, not '%.200s'", key);
}
- return type_error("'%.200s' object is unsubscriptable", o);
+ return type_error("'%.200s' object is not subscriptable", o);
}
int
@@ -439,8 +442,8 @@ PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
}
-static void
-_add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+void
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -455,8 +458,8 @@ _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape)
}
}
-static void
-_add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+void
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -480,7 +483,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;
@@ -507,10 +510,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
@@ -531,7 +534,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;
@@ -558,10 +561,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
@@ -638,7 +641,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);
@@ -720,19 +723,12 @@ PyBuffer_Release(Py_buffer *view)
PyObject *
PyObject_Format(PyObject* obj, PyObject *format_spec)
{
- static PyObject * str__format__ = NULL;
PyObject *empty = NULL;
PyObject *result = NULL;
+#ifdef Py_USING_UNICODE
int spec_is_unicode;
int result_is_unicode;
-
- /* Initialize cached value */
- if (str__format__ == NULL) {
- /* Initialize static variable needed by _PyType_Lookup */
- str__format__ = PyString_InternFromString("__format__");
- if (str__format__ == NULL)
- goto done;
- }
+#endif
/* If no format_spec is provided, use an empty string */
if (format_spec == NULL) {
@@ -741,91 +737,121 @@ PyObject_Format(PyObject* obj, PyObject *format_spec)
}
/* Check the format_spec type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
if (PyUnicode_Check(format_spec))
spec_is_unicode = 1;
else if (PyString_Check(format_spec))
spec_is_unicode = 0;
else {
+#else
+ if (!PyString_Check(format_spec)) {
+#endif
PyErr_Format(PyExc_TypeError,
"format expects arg 2 to be string "
"or unicode, not %.100s", Py_TYPE(format_spec)->tp_name);
goto done;
}
- /* 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;
-
/* Check for a __format__ method and call it. */
if (PyInstance_Check(obj)) {
/* We're an instance of a classic class */
- PyObject *bound_method = PyObject_GetAttr(obj,
- str__format__);
+ PyObject *bound_method = PyObject_GetAttrString(obj, "__format__");
if (bound_method != NULL) {
result = PyObject_CallFunctionObjArgs(bound_method,
format_spec,
NULL);
Py_DECREF(bound_method);
} else {
- PyObject *self_as_str;
- PyObject *format_method;
+ PyObject *self_as_str = NULL;
+ PyObject *format_method = NULL;
+ Py_ssize_t format_len;
PyErr_Clear();
/* Per the PEP, convert to str (or unicode,
depending on the type of the format
specifier). For new-style classes, this
logic is done by object.__format__(). */
- if (spec_is_unicode)
+#ifdef Py_USING_UNICODE
+ if (spec_is_unicode) {
+ format_len = PyUnicode_GET_SIZE(format_spec);
self_as_str = PyObject_Unicode(obj);
- else
+ } else
+#endif
+ {
+ format_len = PyString_GET_SIZE(format_spec);
self_as_str = PyObject_Str(obj);
+ }
if (self_as_str == NULL)
- goto done;
+ goto done1;
+
+ if (format_len > 0) {
+ /* See the almost identical code in
+ typeobject.c for new-style
+ classes. */
+ if (PyErr_WarnEx(
+ PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty "
+ "format string is deprecated", 1)
+ < 0) {
+ goto done1;
+ }
+ /* Eventually this will become an
+ error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to "
+ "object.__format__");
+ goto done1;
+ */
+ }
/* Then call str.__format__ on that result */
- format_method = PyObject_GetAttr(self_as_str,
- str__format__);
+ format_method = PyObject_GetAttrString(self_as_str, "__format__");
if (format_method == NULL) {
- Py_DECREF(self_as_str);
- goto done;
+ goto done1;
}
result = PyObject_CallFunctionObjArgs(format_method,
format_spec,
NULL);
- Py_DECREF(self_as_str);
- Py_DECREF(format_method);
+done1:
+ Py_XDECREF(self_as_str);
+ Py_XDECREF(format_method);
if (result == NULL)
goto done;
}
} else {
/* Not an instance of a classic class, use the code
from py3k */
+ static PyObject *format_cache = NULL;
/* Find the (unbound!) __format__ method (a borrowed
reference) */
- PyObject *method = _PyType_Lookup(Py_TYPE(obj),
- str__format__);
+ PyObject *method = _PyObject_LookupSpecial(obj, "__format__",
+ &format_cache);
if (method == 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(method, obj,
- format_spec, NULL);
+ /* And call it. */
+ result = PyObject_CallFunctionObjArgs(method, format_spec, NULL);
+ Py_DECREF(method);
}
if (result == NULL)
goto done;
/* Check the result type, and make sure it's str or unicode */
+#ifdef Py_USING_UNICODE
if (PyUnicode_Check(result))
result_is_unicode = 1;
else if (PyString_Check(result))
result_is_unicode = 0;
else {
+#else
+ if (!PyString_Check(result)) {
+#endif
PyErr_Format(PyExc_TypeError,
"%.100s.__format__ must return string or "
"unicode, not %.100s", Py_TYPE(obj)->tp_name,
@@ -837,12 +863,14 @@ PyObject_Format(PyObject* obj, PyObject *format_spec)
/* Convert to unicode, if needed. Required if spec is unicode
and result is str */
+#ifdef Py_USING_UNICODE
if (spec_is_unicode && !result_is_unicode) {
PyObject *tmp = PyObject_Unicode(result);
/* This logic works whether or not tmp is NULL */
Py_DECREF(result);
result = tmp;
}
+#endif
done:
Py_XDECREF(empty);
@@ -1685,7 +1713,14 @@ PyNumber_Long(PyObject *o)
if (m && m->nb_long) { /* This should include subclasses of long */
/* Classic classes always take this branch. */
PyObject *res = m->nb_long(o);
- if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+ if (res == NULL)
+ return NULL;
+ if (PyInt_Check(res)) {
+ long value = PyInt_AS_LONG(res);
+ Py_DECREF(res);
+ return PyLong_FromLong(value);
+ }
+ else if (!PyLong_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__long__ returned non-long (type %.200s)",
res->ob_type->tp_name);
@@ -1791,11 +1826,13 @@ PyNumber_ToBase(PyObject *n, int base)
int
PySequence_Check(PyObject *s)
{
- if (s && PyInstance_Check(s))
+ if (s == NULL)
+ return 0;
+ if (PyInstance_Check(s))
return PyObject_HasAttrString(s, "__getitem__");
- if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type))
+ if (PyDict_Check(s))
return 0;
- return s != NULL && s->ob_type->tp_as_sequence &&
+ return s->ob_type->tp_as_sequence &&
s->ob_type->tp_as_sequence->sq_item != NULL;
}
@@ -2889,7 +2926,6 @@ 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)
@@ -2913,29 +2949,28 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
Py_LeaveRecursiveCall();
return r;
}
- if (name == NULL) {
- name = PyString_InternFromString("__instancecheck__");
- if (name == NULL)
- return -1;
- }
- checker = PyObject_GetAttr(cls, name);
- if (checker == NULL && PyErr_Occurred())
- PyErr_Clear();
- if (checker != NULL) {
- PyObject *res;
- int ok = -1;
- if (Py_EnterRecursiveCall(" in __instancecheck__")) {
+
+ if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+ PyObject *checker;
+ checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
+ if (checker != NULL) {
+ PyObject *res;
+ int ok = -1;
+ if (Py_EnterRecursiveCall(" in __instancecheck__")) {
+ Py_DECREF(checker);
+ return ok;
+ }
+ res = PyObject_CallFunctionObjArgs(checker, inst, NULL);
+ Py_LeaveRecursiveCall();
Py_DECREF(checker);
+ if (res != NULL) {
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ }
return ok;
}
- 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);
}
@@ -2974,8 +3009,6 @@ int
PyObject_IsSubclass(PyObject *derived, PyObject *cls)
{
static PyObject *name = NULL;
- PyObject *t, *v, *tb;
- PyObject *checker;
if (PyTuple_Check(cls)) {
Py_ssize_t i;
@@ -2995,29 +3028,28 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
Py_LeaveRecursiveCall();
return r;
}
- if (name == NULL) {
- name = PyString_InternFromString("__subclasscheck__");
- if (name == NULL)
- return -1;
- }
- PyErr_Fetch(&t, &v, &tb);
- checker = PyObject_GetAttr(cls, name);
- PyErr_Restore(t, v, tb);
- if (checker != NULL) {
- PyObject *res;
- int ok = -1;
- if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+ if (!(PyClass_Check(cls) || PyInstance_Check(cls))) {
+ PyObject *checker;
+ checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
+ if (checker != NULL) {
+ PyObject *res;
+ int ok = -1;
+ if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+ Py_DECREF(checker);
+ return ok;
+ }
+ res = PyObject_CallFunctionObjArgs(checker, derived, NULL);
+ Py_LeaveRecursiveCall();
Py_DECREF(checker);
+ if (res != NULL) {
+ ok = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ }
return ok;
}
- res = PyObject_CallFunctionObjArgs(checker, derived, NULL);
- Py_LeaveRecursiveCall();
- Py_DECREF(checker);
- if (res != NULL) {
- ok = PyObject_IsTrue(res);
- Py_DECREF(res);
+ else if (PyErr_Occurred()) {
+ return -1;
}
- return ok;
}
return recursive_issubclass(derived, cls);
}
@@ -3072,7 +3104,6 @@ PyObject *
PyIter_Next(PyObject *iter)
{
PyObject *result;
- assert(PyIter_Check(iter));
result = (*iter->ob_type->tp_iternext)(iter);
if (result == NULL &&
PyErr_Occurred() &&
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 3877c6f7da..57471c3798 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -5,24 +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;
}
@@ -68,7 +60,7 @@ _getbytevalue(PyObject* arg, int *value)
}
static Py_ssize_t
-bytes_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
{
if ( index != 0 ) {
PyErr_SetString(PyExc_SystemError,
@@ -80,7 +72,7 @@ bytes_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **
}
static Py_ssize_t
-bytes_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
+bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
{
if ( index != 0 ) {
PyErr_SetString(PyExc_SystemError,
@@ -92,7 +84,7 @@ bytes_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void *
}
static Py_ssize_t
-bytes_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
+bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
{
if ( lenp )
*lenp = Py_SIZE(self);
@@ -100,7 +92,7 @@ bytes_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
}
static Py_ssize_t
-bytes_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
+bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
{
if ( index != 0 ) {
PyErr_SetString(PyExc_SystemError,
@@ -112,7 +104,7 @@ bytes_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **
}
static int
-bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
+bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
{
int ret;
void *ptr;
@@ -129,7 +121,7 @@ bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
}
static void
-bytes_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
+bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
{
obj->ob_exports--;
}
@@ -296,7 +288,7 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
size = va.len + vb.len;
if (size < 0) {
- return PyErr_NoMemory();
+ PyErr_NoMemory();
goto done;
}
@@ -317,13 +309,13 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
/* Functions stuffed into the type object */
static Py_ssize_t
-bytes_length(PyByteArrayObject *self)
+bytearray_length(PyByteArrayObject *self)
{
return Py_SIZE(self);
}
static PyObject *
-bytes_iconcat(PyByteArrayObject *self, PyObject *other)
+bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
{
Py_ssize_t mysize;
Py_ssize_t size;
@@ -356,7 +348,7 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
}
static PyObject *
-bytes_repeat(PyByteArrayObject *self, Py_ssize_t count)
+bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
{
PyByteArrayObject *result;
Py_ssize_t mysize;
@@ -382,7 +374,7 @@ bytes_repeat(PyByteArrayObject *self, Py_ssize_t count)
}
static PyObject *
-bytes_irepeat(PyByteArrayObject *self, Py_ssize_t count)
+bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
{
Py_ssize_t mysize;
Py_ssize_t size;
@@ -413,7 +405,7 @@ bytes_irepeat(PyByteArrayObject *self, Py_ssize_t count)
}
static PyObject *
-bytes_getitem(PyByteArrayObject *self, Py_ssize_t i)
+bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
{
if (i < 0)
i += Py_SIZE(self);
@@ -425,7 +417,7 @@ bytes_getitem(PyByteArrayObject *self, Py_ssize_t i)
}
static PyObject *
-bytes_subscript(PyByteArrayObject *self, PyObject *index)
+bytearray_subscript(PyByteArrayObject *self, PyObject *index)
{
if (PyIndex_Check(index)) {
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
@@ -480,7 +472,7 @@ bytes_subscript(PyByteArrayObject *self, PyObject *index)
}
static int
-bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
+bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
PyObject *values)
{
Py_ssize_t avail, needed;
@@ -495,7 +487,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
values = PyByteArray_FromObject(values);
if (values == NULL)
return -1;
- err = bytes_setslice(self, lo, hi, values);
+ err = bytearray_setslice(self, lo, hi, values);
Py_DECREF(values);
return err;
}
@@ -570,7 +562,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
}
static int
-bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
+bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
{
int ival;
@@ -583,7 +575,7 @@ bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
}
if (value == NULL)
- return bytes_setslice(self, i, i+1, NULL);
+ return bytearray_setslice(self, i, i+1, NULL);
if (!_getbytevalue(value, &ival))
return -1;
@@ -593,7 +585,7 @@ bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
}
static int
-bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
+bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
{
Py_ssize_t start, stop, step, slicelen, needed;
char *bytes;
@@ -644,12 +636,12 @@ bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
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)
return -1;
- err = bytes_ass_subscript(self, index, values);
+ err = bytearray_ass_subscript(self, index, values);
Py_DECREF(values);
return err;
}
@@ -751,7 +743,7 @@ bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
}
static int
-bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
+bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"source", "encoding", "errors", 0};
PyObject *arg = NULL;
@@ -794,7 +786,7 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
encoded = arg;
Py_INCREF(arg);
}
- new = bytes_iconcat(self, arg);
+ new = bytearray_iconcat(self, arg);
Py_DECREF(encoded);
if (new == NULL)
return -1;
@@ -802,6 +794,7 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
return 0;
}
+#ifdef Py_USING_UNICODE
if (PyUnicode_Check(arg)) {
/* Encode via the codec registry */
PyObject *encoded, *new;
@@ -814,13 +807,14 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
if (encoded == NULL)
return -1;
assert(PyBytes_Check(encoded));
- new = bytes_iconcat(self, encoded);
+ new = bytearray_iconcat(self, encoded);
Py_DECREF(encoded);
if (new == NULL)
return -1;
Py_DECREF(new);
return 0;
}
+#endif
/* If it's not unicode, there can't be encoding or errors */
if (encoding != NULL || errors != NULL) {
@@ -917,7 +911,7 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
/* Mostly copied from string_repr, but without the
"smart quote" functionality. */
static PyObject *
-bytes_repr(PyByteArrayObject *self)
+bytearray_repr(PyByteArrayObject *self)
{
static const char *hexdigits = "0123456789abcdef";
const char *quote_prefix = "bytearray(b";
@@ -932,14 +926,14 @@ bytes_repr(PyByteArrayObject *self)
return NULL;
}
newsize = 14 + 4 * length;
- v = PyUnicode_FromUnicode(NULL, newsize);
+ v = PyString_FromStringAndSize(NULL, newsize);
if (v == NULL) {
return NULL;
}
else {
register Py_ssize_t i;
- register Py_UNICODE c;
- register Py_UNICODE *p;
+ register char c;
+ register char *p;
int quote;
/* Figure out which quote to use; single is preferred */
@@ -959,7 +953,7 @@ bytes_repr(PyByteArrayObject *self)
;
}
- p = PyUnicode_AS_UNICODE(v);
+ p = PyString_AS_STRING(v);
while (*quote_prefix)
*p++ = *quote_prefix++;
*p++ = quote;
@@ -967,7 +961,7 @@ bytes_repr(PyByteArrayObject *self)
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);
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
c = self->ob_bytes[i];
if (c == '\'' || c == '\\')
*p++ = '\\', *p++ = c;
@@ -988,13 +982,13 @@ bytes_repr(PyByteArrayObject *self)
else
*p++ = c;
}
- assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
+ assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote;
while (*quote_postfix) {
*p++ = *quote_postfix++;
}
*p = '\0';
- if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
+ if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
Py_DECREF(v);
return NULL;
}
@@ -1003,7 +997,7 @@ bytes_repr(PyByteArrayObject *self)
}
static PyObject *
-bytes_str(PyObject *op)
+bytearray_str(PyObject *op)
{
#if 0
if (Py_BytesWarningFlag) {
@@ -1011,13 +1005,13 @@ bytes_str(PyObject *op)
"str() on a bytearray instance", 1))
return NULL;
}
- return bytes_repr((PyByteArrayObject*)op);
+ return bytearray_repr((PyByteArrayObject*)op);
#endif
return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
}
static PyObject *
-bytes_richcompare(PyObject *self, PyObject *other, int op)
+bytearray_richcompare(PyObject *self, PyObject *other, int op)
{
Py_ssize_t self_size, other_size;
Py_buffer self_bytes, other_bytes;
@@ -1028,6 +1022,7 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
/* Bytes can be compared to anything that supports the (binary)
buffer API. Except that a comparison with Unicode is always an
error, even if the comparison is for equality. */
+#ifdef Py_USING_UNICODE
if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
if (Py_BytesWarningFlag && op == Py_EQ) {
@@ -1039,6 +1034,7 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
+#endif
self_size = _getbuffer(self, &self_bytes);
if (self_size < 0) {
@@ -1092,13 +1088,13 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
}
static void
-bytes_dealloc(PyByteArrayObject *self)
+bytearray_dealloc(PyByteArrayObject *self)
{
- if (self->ob_exports > 0) {
- PyErr_SetString(PyExc_SystemError,
+ if (self->ob_exports > 0) {
+ PyErr_SetString(PyExc_SystemError,
"deallocated bytearray object has exported buffers");
- PyErr_Print();
- }
+ PyErr_Print();
+ }
if (self->ob_bytes != 0) {
PyMem_Free(self->ob_bytes);
}
@@ -1110,19 +1106,19 @@ bytes_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
-#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"
@@ -1130,32 +1126,31 @@ bytes_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)
-bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
+bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
{
PyObject *subobj;
Py_buffer subbuf;
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
Py_ssize_t res;
- if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+ args, &subobj, &start, &end))
return -2;
if (_getbuffer(subobj, &subbuf) < 0)
return -2;
@@ -1181,9 +1176,9 @@ arguments start and end are interpreted as in slice notation.\n\
Return -1 on failure.");
static PyObject *
-bytes_find(PyByteArrayObject *self, PyObject *args)
+bytearray_find(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t result = bytes_find_internal(self, args, +1);
+ Py_ssize_t result = bytearray_find_internal(self, args, +1);
if (result == -2)
return NULL;
return PyInt_FromSsize_t(result);
@@ -1197,7 +1192,7 @@ bytes B[start:end]. Optional arguments start and end are interpreted\n\
as in slice notation.");
static PyObject *
-bytes_count(PyByteArrayObject *self, PyObject *args)
+bytearray_count(PyByteArrayObject *self, PyObject *args)
{
PyObject *sub_obj;
const char *str = PyByteArray_AS_STRING(self);
@@ -1205,17 +1200,16 @@ bytes_count(PyByteArrayObject *self, PyObject *args)
Py_buffer vsub;
PyObject *count_obj;
- if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
return NULL;
if (_getbuffer(sub_obj, &vsub) < 0)
return NULL;
- _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
+ ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
count_obj = PyInt_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;
@@ -1228,9 +1222,9 @@ PyDoc_STRVAR(index__doc__,
Like B.find() but raise ValueError when the subsection is not found.");
static PyObject *
-bytes_index(PyByteArrayObject *self, PyObject *args)
+bytearray_index(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t result = bytes_find_internal(self, args, +1);
+ Py_ssize_t result = bytearray_find_internal(self, args, +1);
if (result == -2)
return NULL;
if (result == -1) {
@@ -1252,9 +1246,9 @@ arguments start and end are interpreted as in slice notation.\n\
Return -1 on failure.");
static PyObject *
-bytes_rfind(PyByteArrayObject *self, PyObject *args)
+bytearray_rfind(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t result = bytes_find_internal(self, args, -1);
+ Py_ssize_t result = bytearray_find_internal(self, args, -1);
if (result == -2)
return NULL;
return PyInt_FromSsize_t(result);
@@ -1267,9 +1261,9 @@ PyDoc_STRVAR(rindex__doc__,
Like B.rfind() but raise ValueError when the subsection is not found.");
static PyObject *
-bytes_rindex(PyByteArrayObject *self, PyObject *args)
+bytearray_rindex(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t result = bytes_find_internal(self, args, -1);
+ Py_ssize_t result = bytearray_find_internal(self, args, -1);
if (result == -2)
return NULL;
if (result == -1) {
@@ -1282,7 +1276,7 @@ bytes_rindex(PyByteArrayObject *self, PyObject *args)
static int
-bytes_contains(PyObject *self, PyObject *arg)
+bytearray_contains(PyObject *self, PyObject *arg)
{
Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
if (ival == -1 && PyErr_Occurred()) {
@@ -1310,7 +1304,7 @@ bytes_contains(PyObject *self, PyObject *arg)
* -1 on error, 0 if not found and 1 if found.
*/
Py_LOCAL(int)
-_bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
+_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Py_ssize_t end, int direction)
{
Py_ssize_t len = PyByteArray_GET_SIZE(self);
@@ -1323,7 +1317,7 @@ _bytes_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 */
@@ -1357,20 +1351,19 @@ With optional end, stop comparing B at that position.\n\
prefix can also be a tuple of strings to try.");
static PyObject *
-bytes_startswith(PyByteArrayObject *self, PyObject *args)
+bytearray_startswith(PyByteArrayObject *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))
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
- result = _bytes_tailmatch(self,
+ result = _bytearray_tailmatch(self,
PyTuple_GET_ITEM(subobj, i),
start, end, -1);
if (result == -1)
@@ -1381,7 +1374,7 @@ bytes_startswith(PyByteArrayObject *self, PyObject *args)
}
Py_RETURN_FALSE;
}
- result = _bytes_tailmatch(self, subobj, start, end, -1);
+ result = _bytearray_tailmatch(self, subobj, start, end, -1);
if (result == -1)
return NULL;
else
@@ -1397,20 +1390,19 @@ With optional end, stop comparing B at that position.\n\
suffix can also be a tuple of strings to try.");
static PyObject *
-bytes_endswith(PyByteArrayObject *self, PyObject *args)
+bytearray_endswith(PyByteArrayObject *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))
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
- result = _bytes_tailmatch(self,
+ result = _bytearray_tailmatch(self,
PyTuple_GET_ITEM(subobj, i),
start, end, +1);
if (result == -1)
@@ -1421,7 +1413,7 @@ bytes_endswith(PyByteArrayObject *self, PyObject *args)
}
Py_RETURN_FALSE;
}
- result = _bytes_tailmatch(self, subobj, start, end, +1);
+ result = _bytearray_tailmatch(self, subobj, start, end, +1);
if (result == -1)
return NULL;
else
@@ -1438,7 +1430,7 @@ characters have been mapped through the given translation\n\
table, which must be a bytes object of length 256.");
static PyObject *
-bytes_translate(PyByteArrayObject *self, PyObject *args)
+bytearray_translate(PyByteArrayObject *self, PyObject *args)
{
register char *input, *output;
register const char *table;
@@ -1446,29 +1438,35 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
PyObject *input_obj = (PyObject*)self;
const char *output_start;
Py_ssize_t inlen;
- PyObject *result;
+ PyObject *result = NULL;
int trans_table[256];
- PyObject *tableobj, *delobj = NULL;
+ PyObject *tableobj = NULL, *delobj = NULL;
Py_buffer vtable, vdel;
if (!PyArg_UnpackTuple(args, "translate", 1, 2,
&tableobj, &delobj))
return NULL;
- if (_getbuffer(tableobj, &vtable) < 0)
- return NULL;
-
- if (vtable.len != 256) {
- PyErr_SetString(PyExc_ValueError,
- "translation table must be 256 characters long");
- PyBuffer_Release(&vtable);
+ if (tableobj == Py_None) {
+ table = NULL;
+ tableobj = NULL;
+ } else if (_getbuffer(tableobj, &vtable) < 0) {
return NULL;
+ } else {
+ if (vtable.len != 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "translation table must be 256 characters long");
+ PyBuffer_Release(&vtable);
+ return NULL;
+ }
+ table = (const char*)vtable.buf;
}
if (delobj != NULL) {
if (_getbuffer(delobj, &vdel) < 0) {
- PyBuffer_Release(&vtable);
- return NULL;
+ if (tableobj != NULL)
+ PyBuffer_Release(&vtable);
+ return NULL;
}
}
else {
@@ -1476,7 +1474,6 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
vdel.len = 0;
}
- table = (const char *)vtable.buf;
inlen = PyByteArray_GET_SIZE(input_obj);
result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
if (result == NULL)
@@ -1484,7 +1481,7 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
output_start = output = PyByteArray_AsString(result);
input = PyByteArray_AS_STRING(input_obj);
- if (vdel.len == 0) {
+ if (vdel.len == 0 && table != NULL) {
/* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
@@ -1492,9 +1489,14 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
}
goto done;
}
-
- for (i = 0; i < 256; i++)
- trans_table[i] = Py_CHARMASK(table[i]);
+
+ if (table == NULL) {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(i);
+ } else {
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(table[i]);
+ }
for (i = 0; i < vdel.len; i++)
trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
@@ -1510,27 +1512,19 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
PyByteArray_Resize(result, output - output_start);
done:
- PyBuffer_Release(&vtable);
+ if (tableobj != NULL)
+ PyBuffer_Release(&vtable);
if (delobj != NULL)
PyBuffer_Release(&vdel);
return result;
}
-#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 *)
@@ -1557,93 +1551,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 */
@@ -1765,10 +1672,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 */
@@ -1787,9 +1693,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;
@@ -1865,9 +1771,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);
@@ -1887,9 +1793,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);
@@ -1982,9 +1888,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);
@@ -2011,9 +1918,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;
@@ -2117,7 +2024,7 @@ old replaced by new. If the optional argument count is\n\
given, only the first count occurrences are replaced.");
static PyObject *
-bytes_replace(PyByteArrayObject *self, PyObject *args)
+bytearray_replace(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t count = -1;
PyObject *from, *to, *res;
@@ -2142,123 +2049,6 @@ bytes_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 && ISSPACE(s[i]))
- i++;
- j = i;
- while (i < len && !ISSPACE(s[i]))
- i++;
- if (j < i) {
- if (maxcount-- <= 0)
- break;
- SPLIT_ADD(s, j, i);
- while (i < len && 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 bytearray\n\
\n\
@@ -2268,16 +2058,13 @@ If sep is not given, B is split on ASCII whitespace characters\n\
If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
-bytes_split(PyByteArrayObject *self, PyObject *args)
+bytearray_split(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
- 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;
-#ifdef USE_FAST
- Py_ssize_t pos;
-#endif
if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
return NULL;
@@ -2285,86 +2072,18 @@ bytes_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;
- }
-
-#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;
-}
-
-/* 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__,
@@ -2375,7 +2094,7 @@ the separator itself, and the part after it. If the separator is not\n\
found, returns B and two empty bytearray objects.");
static PyObject *
-bytes_partition(PyByteArrayObject *self, PyObject *sep_obj)
+bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
{
PyObject *bytesep, *result;
@@ -2391,7 +2110,7 @@ bytes_partition(PyByteArrayObject *self, PyObject *sep_obj)
);
Py_DECREF(bytesep);
- return make_nullbytes_unique(result);
+ return result;
}
PyDoc_STRVAR(rpartition__doc__,
@@ -2403,7 +2122,7 @@ part after it. If the separator is not found, returns two empty\n\
bytearray objects and B.");
static PyObject *
-bytes_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
+bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
{
PyObject *bytesep, *result;
@@ -2419,81 +2138,7 @@ bytes_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 && ISSPACE(s[i]))
- i--;
- j = i;
- while (i >= 0 && !ISSPACE(s[i]))
- i--;
- if (j > i) {
- if (maxcount-- <= 0)
- break;
- SPLIT_ADD(s, i + 1, j + 1);
- while (i >= 0 && 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__,
@@ -2506,12 +2151,12 @@ If sep is not given, B is split on ASCII whitespace characters\n\
If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
-bytes_rsplit(PyByteArrayObject *self, PyObject *args)
+bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
- 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))
@@ -2520,54 +2165,18 @@ bytes_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;
- 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;
- }
- }
- }
- 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__,
@@ -2575,7 +2184,7 @@ PyDoc_STRVAR(reverse__doc__,
\n\
Reverse the order of the values in B in place.");
static PyObject *
-bytes_reverse(PyByteArrayObject *self, PyObject *unused)
+bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
{
char swap, *head, *tail;
Py_ssize_t i, j, n = Py_SIZE(self);
@@ -2597,7 +2206,7 @@ PyDoc_STRVAR(insert__doc__,
\n\
Insert a single item into the bytearray before the given index.");
static PyObject *
-bytes_insert(PyByteArrayObject *self, PyObject *args)
+bytearray_insert(PyByteArrayObject *self, PyObject *args)
{
PyObject *value;
int ival;
@@ -2634,7 +2243,7 @@ PyDoc_STRVAR(append__doc__,
\n\
Append a single item to the end of B.");
static PyObject *
-bytes_append(PyByteArrayObject *self, PyObject *arg)
+bytearray_append(PyByteArrayObject *self, PyObject *arg)
{
int value;
Py_ssize_t n = Py_SIZE(self);
@@ -2660,16 +2269,16 @@ PyDoc_STRVAR(extend__doc__,
Append all the elements from the iterator or sequence to the\n\
end of B.");
static PyObject *
-bytes_extend(PyByteArrayObject *self, PyObject *arg)
+bytearray_extend(PyByteArrayObject *self, PyObject *arg)
{
- PyObject *it, *item, *bytes_obj;
+ PyObject *it, *item, *bytearray_obj;
Py_ssize_t buf_size = 0, len = 0;
int value;
char *buf;
- /* bytes_setslice code only accepts something supporting PEP 3118. */
+ /* bytearray_setslice code only accepts something supporting PEP 3118. */
if (PyObject_CheckBuffer(arg)) {
- if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
+ if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
return NULL;
Py_RETURN_NONE;
@@ -2679,23 +2288,23 @@ bytes_extend(PyByteArrayObject *self, PyObject *arg)
if (it == NULL)
return NULL;
- /* Try to determine the length of the argument. 32 is abitrary. */
+ /* Try to determine the length of the argument. 32 is arbitrary. */
buf_size = _PyObject_LengthHint(arg, 32);
if (buf_size == -1) {
Py_DECREF(it);
return NULL;
}
- bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
- if (bytes_obj == NULL)
+ bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
+ if (bytearray_obj == NULL)
return NULL;
- buf = PyByteArray_AS_STRING(bytes_obj);
+ buf = PyByteArray_AS_STRING(bytearray_obj);
while ((item = PyIter_Next(it)) != NULL) {
if (! _getbytevalue(item, &value)) {
Py_DECREF(item);
Py_DECREF(it);
- Py_DECREF(bytes_obj);
+ Py_DECREF(bytearray_obj);
return NULL;
}
buf[len++] = value;
@@ -2703,27 +2312,27 @@ bytes_extend(PyByteArrayObject *self, PyObject *arg)
if (len >= buf_size) {
buf_size = len + (len >> 1) + 1;
- if (PyByteArray_Resize((PyObject *)bytes_obj, buf_size) < 0) {
+ if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Py_DECREF(it);
- Py_DECREF(bytes_obj);
+ Py_DECREF(bytearray_obj);
return NULL;
}
/* Recompute the `buf' pointer, since the resizing operation may
have invalidated it. */
- buf = PyByteArray_AS_STRING(bytes_obj);
+ buf = PyByteArray_AS_STRING(bytearray_obj);
}
}
Py_DECREF(it);
/* Resize down to exact size. */
- if (PyByteArray_Resize((PyObject *)bytes_obj, len) < 0) {
- Py_DECREF(bytes_obj);
+ if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
+ Py_DECREF(bytearray_obj);
return NULL;
}
- if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), bytes_obj) == -1)
+ if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
return NULL;
- Py_DECREF(bytes_obj);
+ Py_DECREF(bytearray_obj);
Py_RETURN_NONE;
}
@@ -2734,7 +2343,7 @@ PyDoc_STRVAR(pop__doc__,
Remove and return a single item from B. If no index\n\
argument is given, will pop the last value.");
static PyObject *
-bytes_pop(PyByteArrayObject *self, PyObject *args)
+bytearray_pop(PyByteArrayObject *self, PyObject *args)
{
int value;
Py_ssize_t where = -1, n = Py_SIZE(self);
@@ -2743,8 +2352,8 @@ bytes_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)
@@ -2769,7 +2378,7 @@ PyDoc_STRVAR(remove__doc__,
\n\
Remove the first occurance of a value in B.");
static PyObject *
-bytes_remove(PyByteArrayObject *self, PyObject *arg)
+bytearray_remove(PyByteArrayObject *self, PyObject *arg)
{
int value;
Py_ssize_t where, n = Py_SIZE(self);
@@ -2823,7 +2432,7 @@ PyDoc_STRVAR(strip__doc__,
Strip leading and trailing bytes contained in the argument.\n\
If the argument is omitted, strip ASCII whitespace.");
static PyObject *
-bytes_strip(PyByteArrayObject *self, PyObject *args)
+bytearray_strip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t left, right, mysize, argsize;
void *myptr, *argptr;
@@ -2859,7 +2468,7 @@ PyDoc_STRVAR(lstrip__doc__,
Strip leading bytes contained in the argument.\n\
If the argument is omitted, strip leading ASCII whitespace.");
static PyObject *
-bytes_lstrip(PyByteArrayObject *self, PyObject *args)
+bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t left, right, mysize, argsize;
void *myptr, *argptr;
@@ -2892,7 +2501,7 @@ PyDoc_STRVAR(rstrip__doc__,
Strip trailing bytes contained in the argument.\n\
If the argument is omitted, strip trailing ASCII whitespace.");
static PyObject *
-bytes_rstrip(PyByteArrayObject *self, PyObject *args)
+bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t left, right, mysize, argsize;
void *myptr, *argptr;
@@ -2930,15 +2539,22 @@ as well as any other name registered with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");
static PyObject *
-bytes_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)
+ if (encoding == NULL) {
+#ifdef Py_USING_UNICODE
encoding = PyUnicode_GetDefaultEncoding();
+#else
+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
+ return NULL;
+#endif
+ }
return PyCodec_Decode(self, encoding, errors);
}
@@ -2948,7 +2564,7 @@ PyDoc_STRVAR(alloc_doc,
Returns the number of bytes actually allocated.");
static PyObject *
-bytes_alloc(PyByteArrayObject *self)
+bytearray_alloc(PyByteArrayObject *self)
{
return PyInt_FromSsize_t(self->ob_alloc);
}
@@ -2959,7 +2575,7 @@ PyDoc_STRVAR(join_doc,
Concatenates any number of bytearray objects, with B in between each pair.");
static PyObject *
-bytes_join(PyByteArrayObject *self, PyObject *it)
+bytearray_join(PyByteArrayObject *self, PyObject *it)
{
PyObject *seq;
Py_ssize_t mysize = Py_SIZE(self);
@@ -3028,6 +2644,27 @@ bytes_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\n\
\n\
@@ -3036,15 +2673,13 @@ Spaces between two numbers are accepted.\n\
Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
static int
-hex_digit_to_int(Py_UNICODE c)
+hex_digit_to_int(char 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;
}
@@ -3052,19 +2687,16 @@ hex_digit_to_int(Py_UNICODE c)
}
static PyObject *
-bytes_fromhex(PyObject *cls, PyObject *args)
+bytearray_fromhex(PyObject *cls, PyObject *args)
{
- PyObject *newbytes, *hexobj;
+ PyObject *newbytes;
char *buf;
- Py_UNICODE *hex;
+ char *hex;
Py_ssize_t hexlen, byteslen, i, j;
int top, bot;
- if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
+ if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
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 */
newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
if (!newbytes)
@@ -3098,14 +2730,22 @@ bytes_fromhex(PyObject *cls, PyObject *args)
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
static PyObject *
-bytes_reduce(PyByteArrayObject *self)
+bytearray_reduce(PyByteArrayObject *self)
{
PyObject *latin1, *dict;
if (self->ob_bytes)
+#ifdef Py_USING_UNICODE
latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
Py_SIZE(self), NULL);
+#else
+ latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
+#endif
else
+#ifdef Py_USING_UNICODE
latin1 = PyUnicode_FromString("");
+#else
+ latin1 = PyString_FromString("");
+#endif
dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
if (dict == NULL) {
@@ -3122,7 +2762,7 @@ PyDoc_STRVAR(sizeof_doc,
\n\
Returns the size of B in memory, in bytes");
static PyObject *
-bytes_sizeof(PyByteArrayObject *self)
+bytearray_sizeof(PyByteArrayObject *self)
{
Py_ssize_t res;
@@ -3130,54 +2770,54 @@ bytes_sizeof(PyByteArrayObject *self)
return PyInt_FromSsize_t(res);
}
-static PySequenceMethods bytes_as_sequence = {
- (lenfunc)bytes_length, /* sq_length */
+static PySequenceMethods bytearray_as_sequence = {
+ (lenfunc)bytearray_length, /* sq_length */
(binaryfunc)PyByteArray_Concat, /* sq_concat */
- (ssizeargfunc)bytes_repeat, /* sq_repeat */
- (ssizeargfunc)bytes_getitem, /* sq_item */
- 0, /* sq_slice */
- (ssizeobjargproc)bytes_setitem, /* sq_ass_item */
- 0, /* sq_ass_slice */
- (objobjproc)bytes_contains, /* sq_contains */
- (binaryfunc)bytes_iconcat, /* sq_inplace_concat */
- (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */
+ (ssizeargfunc)bytearray_repeat, /* sq_repeat */
+ (ssizeargfunc)bytearray_getitem, /* sq_item */
+ 0, /* sq_slice */
+ (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)bytearray_contains, /* sq_contains */
+ (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
+ (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
};
-static PyMappingMethods bytes_as_mapping = {
- (lenfunc)bytes_length,
- (binaryfunc)bytes_subscript,
- (objobjargproc)bytes_ass_subscript,
+static PyMappingMethods bytearray_as_mapping = {
+ (lenfunc)bytearray_length,
+ (binaryfunc)bytearray_subscript,
+ (objobjargproc)bytearray_ass_subscript,
};
-static PyBufferProcs bytes_as_buffer = {
- (readbufferproc)bytes_buffer_getreadbuf,
- (writebufferproc)bytes_buffer_getwritebuf,
- (segcountproc)bytes_buffer_getsegcount,
- (charbufferproc)bytes_buffer_getcharbuf,
- (getbufferproc)bytes_getbuffer,
- (releasebufferproc)bytes_releasebuffer,
+static PyBufferProcs bytearray_as_buffer = {
+ (readbufferproc)bytearray_buffer_getreadbuf,
+ (writebufferproc)bytearray_buffer_getwritebuf,
+ (segcountproc)bytearray_buffer_getsegcount,
+ (charbufferproc)bytearray_buffer_getcharbuf,
+ (getbufferproc)bytearray_getbuffer,
+ (releasebufferproc)bytearray_releasebuffer,
};
static PyMethodDef
-bytes_methods[] = {
- {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc},
- {"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc},
- {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, sizeof_doc},
- {"append", (PyCFunction)bytes_append, METH_O, append__doc__},
+bytearray_methods[] = {
+ {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
+ {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
+ {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
+ {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
{"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
_Py_capitalize__doc__},
{"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
- {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__},
- {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc},
- {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__},
+ {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
+ {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
+ {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
expandtabs__doc__},
- {"extend", (PyCFunction)bytes_extend, METH_O, extend__doc__},
- {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
- {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,
+ {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
+ {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
+ {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
fromhex_doc},
- {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__},
- {"insert", (PyCFunction)bytes_insert, METH_VARARGS, insert__doc__},
+ {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
+ {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
{"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
_Py_isalnum__doc__},
{"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
@@ -3192,38 +2832,38 @@ bytes_methods[] = {
_Py_istitle__doc__},
{"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
_Py_isupper__doc__},
- {"join", (PyCFunction)bytes_join, METH_O, join_doc},
+ {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
{"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
{"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
- {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__},
- {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__},
- {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__},
- {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__},
- {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__},
- {"reverse", (PyCFunction)bytes_reverse, METH_NOARGS, reverse__doc__},
- {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__},
- {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__},
+ {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
+ {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
+ {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
+ {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
+ {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
+ {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
+ {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
+ {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
{"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
- {"rpartition", (PyCFunction)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)stringlib_splitlines, METH_VARARGS,
+ {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
+ {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
+ {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
+ {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
+ {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
splitlines__doc__},
- {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS ,
+ {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
startswith__doc__},
- {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__},
+ {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
{"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
_Py_swapcase__doc__},
{"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
- {"translate", (PyCFunction)bytes_translate, METH_VARARGS,
+ {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
translate__doc__},
{"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
{"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
{NULL}
};
-PyDoc_STRVAR(bytes_doc,
+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\
@@ -3240,38 +2880,38 @@ bytearray(int) -> bytearray.\n\
Construct a zero-initialized bytearray of the given length.");
-static PyObject *bytes_iter(PyObject *seq);
+static PyObject *bytearray_iter(PyObject *seq);
PyTypeObject PyByteArray_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"bytearray",
sizeof(PyByteArrayObject),
0,
- (destructor)bytes_dealloc, /* tp_dealloc */
+ (destructor)bytearray_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- (reprfunc)bytes_repr, /* tp_repr */
+ (reprfunc)bytearray_repr, /* tp_repr */
0, /* tp_as_number */
- &bytes_as_sequence, /* tp_as_sequence */
- &bytes_as_mapping, /* tp_as_mapping */
+ &bytearray_as_sequence, /* tp_as_sequence */
+ &bytearray_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
- bytes_str, /* tp_str */
+ bytearray_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
- &bytes_as_buffer, /* tp_as_buffer */
+ &bytearray_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
- bytes_doc, /* tp_doc */
+ bytearray_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- (richcmpfunc)bytes_richcompare, /* tp_richcompare */
+ (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
- bytes_iter, /* tp_iter */
+ bytearray_iter, /* tp_iter */
0, /* tp_iternext */
- bytes_methods, /* tp_methods */
+ bytearray_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@@ -3279,7 +2919,7 @@ PyTypeObject PyByteArray_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- (initproc)bytes_init, /* tp_init */
+ (initproc)bytearray_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
PyType_GenericNew, /* tp_new */
PyObject_Del, /* tp_free */
@@ -3294,7 +2934,7 @@ typedef struct {
} bytesiterobject;
static void
-bytesiter_dealloc(bytesiterobject *it)
+bytearrayiter_dealloc(bytesiterobject *it)
{
_PyObject_GC_UNTRACK(it);
Py_XDECREF(it->it_seq);
@@ -3302,14 +2942,14 @@ bytesiter_dealloc(bytesiterobject *it)
}
static int
-bytesiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
+bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
{
Py_VISIT(it->it_seq);
return 0;
}
static PyObject *
-bytesiter_next(bytesiterobject *it)
+bytearrayiter_next(bytesiterobject *it)
{
PyByteArrayObject *seq;
PyObject *item;
@@ -3334,7 +2974,7 @@ bytesiter_next(bytesiterobject *it)
}
static PyObject *
-bytesiter_length_hint(bytesiterobject *it)
+bytesarrayiter_length_hint(bytesiterobject *it)
{
Py_ssize_t len = 0;
if (it->it_seq)
@@ -3345,8 +2985,8 @@ bytesiter_length_hint(bytesiterobject *it)
PyDoc_STRVAR(length_hint_doc,
"Private method returning an estimate of len(list(it)).");
-static PyMethodDef bytesiter_methods[] = {
- {"__length_hint__", (PyCFunction)bytesiter_length_hint, METH_NOARGS,
+static PyMethodDef bytearrayiter_methods[] = {
+ {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
length_hint_doc},
{NULL, NULL} /* sentinel */
};
@@ -3357,7 +2997,7 @@ PyTypeObject PyByteArrayIter_Type = {
sizeof(bytesiterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- (destructor)bytesiter_dealloc, /* tp_dealloc */
+ (destructor)bytearrayiter_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -3374,18 +3014,18 @@ PyTypeObject PyByteArrayIter_Type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
- (traverseproc)bytesiter_traverse, /* tp_traverse */
+ (traverseproc)bytearrayiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
- (iternextfunc)bytesiter_next, /* tp_iternext */
- bytesiter_methods, /* tp_methods */
+ (iternextfunc)bytearrayiter_next, /* tp_iternext */
+ bytearrayiter_methods, /* tp_methods */
0,
};
static PyObject *
-bytes_iter(PyObject *seq)
+bytearray_iter(PyObject *seq)
{
bytesiterobject *it;
diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c
index 8ce08565d6..1406ac11ca 100644
--- a/Objects/bytes_methods.c
+++ b/Objects/bytes_methods.c
@@ -1,219 +1,6 @@
#include "Python.h"
#include "bytes_methods.h"
-/* Our own locale-independent ctype.h-like macros */
-
-const unsigned int _Py_ctype_table[256] = {
- 0, /* 0x0 '\x00' */
- 0, /* 0x1 '\x01' */
- 0, /* 0x2 '\x02' */
- 0, /* 0x3 '\x03' */
- 0, /* 0x4 '\x04' */
- 0, /* 0x5 '\x05' */
- 0, /* 0x6 '\x06' */
- 0, /* 0x7 '\x07' */
- 0, /* 0x8 '\x08' */
- FLAG_SPACE, /* 0x9 '\t' */
- FLAG_SPACE, /* 0xa '\n' */
- FLAG_SPACE, /* 0xb '\v' */
- FLAG_SPACE, /* 0xc '\f' */
- FLAG_SPACE, /* 0xd '\r' */
- 0, /* 0xe '\x0e' */
- 0, /* 0xf '\x0f' */
- 0, /* 0x10 '\x10' */
- 0, /* 0x11 '\x11' */
- 0, /* 0x12 '\x12' */
- 0, /* 0x13 '\x13' */
- 0, /* 0x14 '\x14' */
- 0, /* 0x15 '\x15' */
- 0, /* 0x16 '\x16' */
- 0, /* 0x17 '\x17' */
- 0, /* 0x18 '\x18' */
- 0, /* 0x19 '\x19' */
- 0, /* 0x1a '\x1a' */
- 0, /* 0x1b '\x1b' */
- 0, /* 0x1c '\x1c' */
- 0, /* 0x1d '\x1d' */
- 0, /* 0x1e '\x1e' */
- 0, /* 0x1f '\x1f' */
- FLAG_SPACE, /* 0x20 ' ' */
- 0, /* 0x21 '!' */
- 0, /* 0x22 '"' */
- 0, /* 0x23 '#' */
- 0, /* 0x24 '$' */
- 0, /* 0x25 '%' */
- 0, /* 0x26 '&' */
- 0, /* 0x27 "'" */
- 0, /* 0x28 '(' */
- 0, /* 0x29 ')' */
- 0, /* 0x2a '*' */
- 0, /* 0x2b '+' */
- 0, /* 0x2c ',' */
- 0, /* 0x2d '-' */
- 0, /* 0x2e '.' */
- 0, /* 0x2f '/' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x30 '0' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x31 '1' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x32 '2' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x33 '3' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x34 '4' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x35 '5' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x36 '6' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x37 '7' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x38 '8' */
- FLAG_DIGIT|FLAG_XDIGIT, /* 0x39 '9' */
- 0, /* 0x3a ':' */
- 0, /* 0x3b ';' */
- 0, /* 0x3c '<' */
- 0, /* 0x3d '=' */
- 0, /* 0x3e '>' */
- 0, /* 0x3f '?' */
- 0, /* 0x40 '@' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x41 'A' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x42 'B' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x43 'C' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x44 'D' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x45 'E' */
- FLAG_UPPER|FLAG_XDIGIT, /* 0x46 'F' */
- FLAG_UPPER, /* 0x47 'G' */
- FLAG_UPPER, /* 0x48 'H' */
- FLAG_UPPER, /* 0x49 'I' */
- FLAG_UPPER, /* 0x4a 'J' */
- FLAG_UPPER, /* 0x4b 'K' */
- FLAG_UPPER, /* 0x4c 'L' */
- FLAG_UPPER, /* 0x4d 'M' */
- FLAG_UPPER, /* 0x4e 'N' */
- FLAG_UPPER, /* 0x4f 'O' */
- FLAG_UPPER, /* 0x50 'P' */
- FLAG_UPPER, /* 0x51 'Q' */
- FLAG_UPPER, /* 0x52 'R' */
- FLAG_UPPER, /* 0x53 'S' */
- FLAG_UPPER, /* 0x54 'T' */
- FLAG_UPPER, /* 0x55 'U' */
- FLAG_UPPER, /* 0x56 'V' */
- FLAG_UPPER, /* 0x57 'W' */
- FLAG_UPPER, /* 0x58 'X' */
- FLAG_UPPER, /* 0x59 'Y' */
- FLAG_UPPER, /* 0x5a 'Z' */
- 0, /* 0x5b '[' */
- 0, /* 0x5c '\\' */
- 0, /* 0x5d ']' */
- 0, /* 0x5e '^' */
- 0, /* 0x5f '_' */
- 0, /* 0x60 '`' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x61 'a' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x62 'b' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x63 'c' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x64 'd' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x65 'e' */
- FLAG_LOWER|FLAG_XDIGIT, /* 0x66 'f' */
- FLAG_LOWER, /* 0x67 'g' */
- FLAG_LOWER, /* 0x68 'h' */
- FLAG_LOWER, /* 0x69 'i' */
- FLAG_LOWER, /* 0x6a 'j' */
- FLAG_LOWER, /* 0x6b 'k' */
- FLAG_LOWER, /* 0x6c 'l' */
- FLAG_LOWER, /* 0x6d 'm' */
- FLAG_LOWER, /* 0x6e 'n' */
- FLAG_LOWER, /* 0x6f 'o' */
- FLAG_LOWER, /* 0x70 'p' */
- FLAG_LOWER, /* 0x71 'q' */
- FLAG_LOWER, /* 0x72 'r' */
- FLAG_LOWER, /* 0x73 's' */
- FLAG_LOWER, /* 0x74 't' */
- FLAG_LOWER, /* 0x75 'u' */
- FLAG_LOWER, /* 0x76 'v' */
- FLAG_LOWER, /* 0x77 'w' */
- FLAG_LOWER, /* 0x78 'x' */
- FLAG_LOWER, /* 0x79 'y' */
- FLAG_LOWER, /* 0x7a 'z' */
- 0, /* 0x7b '{' */
- 0, /* 0x7c '|' */
- 0, /* 0x7d '}' */
- 0, /* 0x7e '~' */
- 0, /* 0x7f '\x7f' */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-
-const unsigned char _Py_ctype_tolower[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-};
-
-const unsigned char _Py_ctype_toupper[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-};
-
-
PyDoc_STRVAR_shared(_Py_isspace__doc__,
"B.isspace() -> bool\n\
\n\
@@ -228,7 +15,7 @@ _Py_bytes_isspace(const char *cptr, Py_ssize_t len)
register const unsigned char *e;
/* Shortcut for single character strings */
- if (len == 1 && ISSPACE(*p))
+ if (len == 1 && Py_ISSPACE(*p))
Py_RETURN_TRUE;
/* Special case for empty strings */
@@ -237,7 +24,7 @@ _Py_bytes_isspace(const char *cptr, Py_ssize_t len)
e = p + len;
for (; p < e; p++) {
- if (!ISSPACE(*p))
+ if (!Py_ISSPACE(*p))
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
@@ -258,7 +45,7 @@ _Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
register const unsigned char *e;
/* Shortcut for single character strings */
- if (len == 1 && ISALPHA(*p))
+ if (len == 1 && Py_ISALPHA(*p))
Py_RETURN_TRUE;
/* Special case for empty strings */
@@ -267,7 +54,7 @@ _Py_bytes_isalpha(const char *cptr, Py_ssize_t len)
e = p + len;
for (; p < e; p++) {
- if (!ISALPHA(*p))
+ if (!Py_ISALPHA(*p))
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
@@ -288,7 +75,7 @@ _Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
register const unsigned char *e;
/* Shortcut for single character strings */
- if (len == 1 && ISALNUM(*p))
+ if (len == 1 && Py_ISALNUM(*p))
Py_RETURN_TRUE;
/* Special case for empty strings */
@@ -297,7 +84,7 @@ _Py_bytes_isalnum(const char *cptr, Py_ssize_t len)
e = p + len;
for (; p < e; p++) {
- if (!ISALNUM(*p))
+ if (!Py_ISALNUM(*p))
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
@@ -318,7 +105,7 @@ _Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
register const unsigned char *e;
/* Shortcut for single character strings */
- if (len == 1 && ISDIGIT(*p))
+ if (len == 1 && Py_ISDIGIT(*p))
Py_RETURN_TRUE;
/* Special case for empty strings */
@@ -327,7 +114,7 @@ _Py_bytes_isdigit(const char *cptr, Py_ssize_t len)
e = p + len;
for (; p < e; p++) {
- if (!ISDIGIT(*p))
+ if (!Py_ISDIGIT(*p))
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
@@ -350,7 +137,7 @@ _Py_bytes_islower(const char *cptr, Py_ssize_t len)
/* Shortcut for single character strings */
if (len == 1)
- return PyBool_FromLong(ISLOWER(*p));
+ return PyBool_FromLong(Py_ISLOWER(*p));
/* Special case for empty strings */
if (len == 0)
@@ -359,9 +146,9 @@ _Py_bytes_islower(const char *cptr, Py_ssize_t len)
e = p + len;
cased = 0;
for (; p < e; p++) {
- if (ISUPPER(*p))
+ if (Py_ISUPPER(*p))
Py_RETURN_FALSE;
- else if (!cased && ISLOWER(*p))
+ else if (!cased && Py_ISLOWER(*p))
cased = 1;
}
return PyBool_FromLong(cased);
@@ -384,7 +171,7 @@ _Py_bytes_isupper(const char *cptr, Py_ssize_t len)
/* Shortcut for single character strings */
if (len == 1)
- return PyBool_FromLong(ISUPPER(*p));
+ return PyBool_FromLong(Py_ISUPPER(*p));
/* Special case for empty strings */
if (len == 0)
@@ -393,9 +180,9 @@ _Py_bytes_isupper(const char *cptr, Py_ssize_t len)
e = p + len;
cased = 0;
for (; p < e; p++) {
- if (ISLOWER(*p))
+ if (Py_ISLOWER(*p))
Py_RETURN_FALSE;
- else if (!cased && ISUPPER(*p))
+ else if (!cased && Py_ISUPPER(*p))
cased = 1;
}
return PyBool_FromLong(cased);
@@ -420,7 +207,7 @@ _Py_bytes_istitle(const char *cptr, Py_ssize_t len)
/* Shortcut for single character strings */
if (len == 1)
- return PyBool_FromLong(ISUPPER(*p));
+ return PyBool_FromLong(Py_ISUPPER(*p));
/* Special case for empty strings */
if (len == 0)
@@ -432,13 +219,13 @@ _Py_bytes_istitle(const char *cptr, Py_ssize_t len)
for (; p < e; p++) {
register const unsigned char ch = *p;
- if (ISUPPER(ch)) {
+ if (Py_ISUPPER(ch)) {
if (previous_is_cased)
Py_RETURN_FALSE;
previous_is_cased = 1;
cased = 1;
}
- else if (ISLOWER(ch)) {
+ else if (Py_ISLOWER(ch)) {
if (!previous_is_cased)
Py_RETURN_FALSE;
previous_is_cased = 1;
@@ -473,8 +260,8 @@ _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len)
for (i = 0; i < len; i++) {
int c = Py_CHARMASK(result[i]);
- if (ISUPPER(c))
- result[i] = TOLOWER(c);
+ if (Py_ISUPPER(c))
+ result[i] = Py_TOLOWER(c);
}
}
@@ -501,8 +288,8 @@ _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len)
for (i = 0; i < len; i++) {
int c = Py_CHARMASK(result[i]);
- if (ISLOWER(c))
- result[i] = TOUPPER(c);
+ if (Py_ISLOWER(c))
+ result[i] = Py_TOUPPER(c);
}
}
@@ -527,13 +314,13 @@ _Py_bytes_title(char *result, char *s, Py_ssize_t len)
*/
for (i = 0; i < len; i++) {
int c = Py_CHARMASK(*s++);
- if (ISLOWER(c)) {
+ if (Py_ISLOWER(c)) {
if (!previous_is_cased)
- c = TOUPPER(c);
+ c = Py_TOUPPER(c);
previous_is_cased = 1;
- } else if (ISUPPER(c)) {
+ } else if (Py_ISUPPER(c)) {
if (previous_is_cased)
- c = TOLOWER(c);
+ c = Py_TOLOWER(c);
previous_is_cased = 1;
} else
previous_is_cased = 0;
@@ -545,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)
@@ -560,16 +348,16 @@ _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len)
*/
if (0 < len) {
int c = Py_CHARMASK(*s++);
- if (ISLOWER(c))
- *result = TOUPPER(c);
+ if (Py_ISLOWER(c))
+ *result = Py_TOUPPER(c);
else
*result = c;
result++;
}
for (i = 1; i < len; i++) {
int c = Py_CHARMASK(*s++);
- if (ISUPPER(c))
- *result = TOLOWER(c);
+ if (Py_ISUPPER(c))
+ *result = Py_TOLOWER(c);
else
*result = c;
result++;
@@ -596,11 +384,11 @@ _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len)
*/
for (i = 0; i < len; i++) {
int c = Py_CHARMASK(*s++);
- if (ISLOWER(c)) {
- *result = TOUPPER(c);
+ if (Py_ISLOWER(c)) {
+ *result = Py_TOUPPER(c);
}
- else if (ISUPPER(c)) {
- *result = TOLOWER(c);
+ else if (Py_ISUPPER(c)) {
+ *result = Py_TOLOWER(c);
}
else
*result = c;
diff --git a/Objects/capsule.c b/Objects/capsule.c
new file mode 100644
index 0000000000..ea20f82b0d
--- /dev/null
+++ b/Objects/capsule.c
@@ -0,0 +1,324 @@
+/* Wrap void * pointers to be passed between C modules */
+
+#include "Python.h"
+
+/* Internal structure of PyCapsule */
+typedef struct {
+ PyObject_HEAD
+ void *pointer;
+ const char *name;
+ void *context;
+ PyCapsule_Destructor destructor;
+} PyCapsule;
+
+
+
+static int
+_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
+{
+ if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
+ PyErr_SetString(PyExc_ValueError, invalid_capsule);
+ return 0;
+ }
+ return 1;
+}
+
+#define is_legal_capsule(capsule, name) \
+ (_is_legal_capsule(capsule, \
+ name " called with invalid PyCapsule object"))
+
+
+static int
+name_matches(const char *name1, const char *name2) {
+ /* if either is NULL, */
+ if (!name1 || !name2) {
+ /* they're only the same if they're both NULL. */
+ return name1 == name2;
+ }
+ return !strcmp(name1, name2);
+}
+
+
+
+PyObject *
+PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
+{
+ PyCapsule *capsule;
+
+ if (!pointer) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
+ return NULL;
+ }
+
+ capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
+ if (capsule == NULL) {
+ return NULL;
+ }
+
+ capsule->pointer = pointer;
+ capsule->name = name;
+ capsule->context = NULL;
+ capsule->destructor = destructor;
+
+ return (PyObject *)capsule;
+}
+
+
+int
+PyCapsule_IsValid(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ return (capsule != NULL &&
+ PyCapsule_CheckExact(capsule) &&
+ capsule->pointer != NULL &&
+ name_matches(capsule->name, name));
+}
+
+
+void *
+PyCapsule_GetPointer(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
+ return NULL;
+ }
+
+ if (!name_matches(name, capsule->name)) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
+ return NULL;
+ }
+
+ return capsule->pointer;
+}
+
+
+const char *
+PyCapsule_GetName(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
+ return NULL;
+ }
+ return capsule->name;
+}
+
+
+PyCapsule_Destructor
+PyCapsule_GetDestructor(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
+ return NULL;
+ }
+ return capsule->destructor;
+}
+
+
+void *
+PyCapsule_GetContext(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
+ return NULL;
+ }
+ return capsule->context;
+}
+
+
+int
+PyCapsule_SetPointer(PyObject *o, void *pointer)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!pointer) {
+ PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
+ return -1;
+ }
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
+ return -1;
+ }
+
+ capsule->pointer = pointer;
+ return 0;
+}
+
+
+int
+PyCapsule_SetName(PyObject *o, const char *name)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
+ return -1;
+ }
+
+ capsule->name = name;
+ return 0;
+}
+
+
+int
+PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
+ return -1;
+ }
+
+ capsule->destructor = destructor;
+ return 0;
+}
+
+
+int
+PyCapsule_SetContext(PyObject *o, void *context)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+
+ if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
+ return -1;
+ }
+
+ capsule->context = context;
+ return 0;
+}
+
+
+void *
+PyCapsule_Import(const char *name, int no_block)
+{
+ PyObject *object = NULL;
+ void *return_value = NULL;
+ char *trace;
+ size_t name_length = (strlen(name) + 1) * sizeof(char);
+ char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+ if (!name_dup) {
+ return NULL;
+ }
+
+ memcpy(name_dup, name, name_length);
+
+ trace = name_dup;
+ while (trace) {
+ char *dot = strchr(trace, '.');
+ if (dot) {
+ *dot++ = '\0';
+ }
+
+ if (object == NULL) {
+ if (no_block) {
+ object = PyImport_ImportModuleNoBlock(trace);
+ } else {
+ object = PyImport_ImportModule(trace);
+ if (!object) {
+ PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
+ }
+ }
+ } else {
+ PyObject *object2 = PyObject_GetAttrString(object, trace);
+ Py_DECREF(object);
+ object = object2;
+ }
+ if (!object) {
+ goto EXIT;
+ }
+
+ trace = dot;
+ }
+
+ /* compare attribute name to module.name by hand */
+ if (PyCapsule_IsValid(object, name)) {
+ PyCapsule *capsule = (PyCapsule *)object;
+ return_value = capsule->pointer;
+ } else {
+ PyErr_Format(PyExc_AttributeError,
+ "PyCapsule_Import \"%s\" is not valid",
+ name);
+ }
+
+EXIT:
+ Py_XDECREF(object);
+ if (name_dup) {
+ PyMem_FREE(name_dup);
+ }
+ return return_value;
+}
+
+
+static void
+capsule_dealloc(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+ if (capsule->destructor) {
+ capsule->destructor(o);
+ }
+ PyObject_DEL(o);
+}
+
+
+static PyObject *
+capsule_repr(PyObject *o)
+{
+ PyCapsule *capsule = (PyCapsule *)o;
+ const char *name;
+ const char *quote;
+
+ if (capsule->name) {
+ quote = "\"";
+ name = capsule->name;
+ } else {
+ quote = "";
+ name = "NULL";
+ }
+
+ return PyString_FromFormat("<capsule object %s%s%s at %p>",
+ quote, name, quote, capsule);
+}
+
+
+
+PyDoc_STRVAR(PyCapsule_Type__doc__,
+"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
+object. They're a way of passing data through the Python interpreter\n\
+without creating your own custom type.\n\
+\n\
+Capsules are used for communication between extension modules.\n\
+They provide a way for an extension module to export a C interface\n\
+to other extension modules, so that extension modules can use the\n\
+Python import mechanism to link to one another.\n\
+");
+
+PyTypeObject PyCapsule_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "PyCapsule", /*tp_name*/
+ sizeof(PyCapsule), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ capsule_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ capsule_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ 0, /*tp_flags*/
+ PyCapsule_Type__doc__ /*tp_doc*/
+};
+
+
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 8c338232e4..0832531422 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -123,6 +123,7 @@ alloc_error:
op->cl_dict = dict;
Py_XINCREF(name);
op->cl_name = name;
+ op->cl_weakreflist = NULL;
op->cl_getattr = class_lookup(op, getattrstr, &dummy);
op->cl_setattr = class_lookup(op, setattrstr, &dummy);
@@ -188,6 +189,8 @@ static void
class_dealloc(PyClassObject *op)
{
_PyObject_GC_UNTRACK(op);
+ if (op->cl_weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) op);
Py_DECREF(op->cl_bases);
Py_DECREF(op->cl_dict);
Py_XDECREF(op->cl_name);
@@ -454,7 +457,7 @@ PyTypeObject PyClass_Type = {
(traverseproc)class_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
+ offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
@@ -2226,10 +2229,6 @@ PyObject *
PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
{
register PyMethodObject *im;
- if (!PyCallable_Check(func)) {
- PyErr_BadInternalCall();
- return NULL;
- }
im = free_list;
if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self);
diff --git a/Objects/cobject.c b/Objects/cobject.c
index c437491c27..355421e635 100644
--- a/Objects/cobject.c
+++ b/Objects/cobject.c
@@ -9,11 +9,22 @@
typedef void (*destructor1)(void *);
typedef void (*destructor2)(void *, void*);
+static int cobject_deprecation_warning(void)
+{
+ return PyErr_WarnPy3k("CObject type is not supported in 3.x. "
+ "Please use capsule objects instead.", 1);
+}
+
+
PyObject *
PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
{
PyCObject *self;
+ if (cobject_deprecation_warning()) {
+ return NULL;
+ }
+
self = PyObject_NEW(PyCObject, &PyCObject_Type);
if (self == NULL)
return NULL;
@@ -30,6 +41,10 @@ PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
{
PyCObject *self;
+ if (cobject_deprecation_warning()) {
+ return NULL;
+ }
+
if (!desc) {
PyErr_SetString(PyExc_TypeError,
"PyCObject_FromVoidPtrAndDesc called with null"
@@ -50,6 +65,10 @@ void *
PyCObject_AsVoidPtr(PyObject *self)
{
if (self) {
+ if (PyCapsule_CheckExact(self)) {
+ const char *name = PyCapsule_GetName(self);
+ return (void *)PyCapsule_GetPointer(self, name);
+ }
if (self->ob_type == &PyCObject_Type)
return ((PyCObject *)self)->cobject;
PyErr_SetString(PyExc_TypeError,
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 9c3bfee7f9..9879df5392 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -103,10 +103,57 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
Py_INCREF(lnotab);
co->co_lnotab = lnotab;
co->co_zombieframe = NULL;
+ co->co_weakreflist = NULL;
}
return co;
}
+PyCodeObject *
+PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
+{
+ static PyObject *emptystring = NULL;
+ static PyObject *nulltuple = NULL;
+ PyObject *filename_ob = NULL;
+ PyObject *funcname_ob = NULL;
+ PyCodeObject *result = NULL;
+ if (emptystring == NULL) {
+ emptystring = PyString_FromString("");
+ if (emptystring == NULL)
+ goto failed;
+ }
+ if (nulltuple == NULL) {
+ nulltuple = PyTuple_New(0);
+ if (nulltuple == NULL)
+ goto failed;
+ }
+ funcname_ob = PyString_FromString(funcname);
+ if (funcname_ob == NULL)
+ goto failed;
+ filename_ob = PyString_FromString(filename);
+ if (filename_ob == NULL)
+ goto failed;
+
+ result = PyCode_New(0, /* argcount */
+ 0, /* nlocals */
+ 0, /* stacksize */
+ 0, /* flags */
+ emptystring, /* code */
+ nulltuple, /* consts */
+ nulltuple, /* names */
+ nulltuple, /* varnames */
+ nulltuple, /* freevars */
+ nulltuple, /* cellvars */
+ filename_ob, /* filename */
+ funcname_ob, /* name */
+ firstlineno, /* firstlineno */
+ emptystring /* lnotab */
+ );
+
+failed:
+ Py_XDECREF(funcname_ob);
+ Py_XDECREF(filename_ob);
+ return result;
+}
#define OFF(x) offsetof(PyCodeObject, x)
@@ -268,6 +315,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);
}
@@ -444,8 +493,8 @@ PyTypeObject PyCode_Type = {
code_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- code_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
+ code_richcompare, /* tp_richcompare */
+ offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
@@ -461,48 +510,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
@@ -521,85 +530,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.
- */
-
-
+/* 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)
+_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
{
int size, addr, line;
unsigned char* p;
@@ -616,11 +550,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) {
@@ -633,13 +565,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/complexobject.c b/Objects/complexobject.c
index e8c8ebb3aa..677ac0ebe5 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -8,10 +8,6 @@
#include "Python.h"
#include "structmember.h"
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-
#ifndef WITHOUT_COMPLEX
/* Precisions used by repr() and str(), respectively.
@@ -284,12 +280,43 @@ PyComplex_ImagAsDouble(PyObject *op)
}
}
+static PyObject *
+try_complex_special_method(PyObject *op) {
+ PyObject *f;
+ static PyObject *complexstr;
+
+ if (complexstr == NULL) {
+ complexstr = PyString_InternFromString("__complex__");
+ if (complexstr == NULL)
+ return NULL;
+ }
+ if (PyInstance_Check(op)) {
+ f = PyObject_GetAttr(op, complexstr);
+ if (f == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
+ if (f == NULL && PyErr_Occurred())
+ return NULL;
+ }
+ if (f != NULL) {
+ PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
+ Py_DECREF(f);
+ return res;
+ }
+ return NULL;
+}
+
Py_complex
PyComplex_AsCComplex(PyObject *op)
{
Py_complex cv;
PyObject *newop = NULL;
- static PyObject *complex_str = NULL;
assert(op);
/* If op is already of type PyComplex_Type, return its value */
@@ -302,29 +329,7 @@ PyComplex_AsCComplex(PyObject *op)
cv.real = -1.;
cv.imag = 0.;
- if (complex_str == NULL) {
- if (!(complex_str = PyString_InternFromString("__complex__")))
- return cv;
- }
-
- if (PyInstance_Check(op)) {
- /* this can go away in python 3000 */
- if (PyObject_HasAttr(op, complex_str)) {
- newop = PyObject_CallMethod(op, "__complex__", NULL);
- if (!newop)
- return cv;
- }
- /* else try __float__ */
- } else {
- 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)) {
@@ -337,6 +342,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 {
@@ -353,83 +361,98 @@ complex_dealloc(PyObject *op)
}
-static void
-complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision)
+static PyObject *
+complex_format(PyComplexObject *v, int precision, char format_code)
{
- char format[32];
- if (v->cval.real == 0.) {
- if (!Py_IS_FINITE(v->cval.imag)) {
- if (Py_IS_NAN(v->cval.imag))
- strncpy(buf, "nan*j", 6);
- else if (copysign(1, v->cval.imag) == 1)
- strncpy(buf, "inf*j", 6);
- else
- strncpy(buf, "-inf*j", 7);
- }
- else {
- PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
- PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag);
- strncat(buf, "j", 1);
+ 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 {
- char re[64], im[64];
/* Format imaginary part with sign, real part without */
- if (!Py_IS_FINITE(v->cval.real)) {
- if (Py_IS_NAN(v->cval.real))
- strncpy(re, "nan", 4);
- /* else if (copysign(1, v->cval.real) == 1) */
- else if (v->cval.real > 0)
- strncpy(re, "inf", 4);
- else
- strncpy(re, "-inf", 5);
- }
- else {
- PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
- PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real);
- }
- if (!Py_IS_FINITE(v->cval.imag)) {
- if (Py_IS_NAN(v->cval.imag))
- strncpy(im, "+nan*", 6);
- /* else if (copysign(1, v->cval.imag) == 1) */
- else if (v->cval.imag > 0)
- strncpy(im, "+inf*", 6);
- else
- strncpy(im, "-inf*", 6);
+ pre = PyOS_double_to_string(v->cval.real, format_code,
+ precision, 0, NULL);
+ if (!pre) {
+ PyErr_NoMemory();
+ goto done;
}
- else {
- PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision);
- PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag);
+ re = pre;
+
+ im = PyOS_double_to_string(v->cval.imag, format_code,
+ precision, Py_DTSF_SIGN, NULL);
+ if (!im) {
+ PyErr_NoMemory();
+ goto done;
}
- PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im);
+ lead = "(";
+ tail = ")";
}
+ /* Alloc the final buffer. Add one for the "j" in the format string,
+ and one for the trailing zero. */
+ len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
+ buf = PyMem_Malloc(len);
+ if (!buf) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail);
+ result = PyString_FromString(buf);
+ done:
+ PyMem_Free(im);
+ PyMem_Free(pre);
+ PyMem_Free(buf);
+
+ return result;
}
static int
complex_print(PyComplexObject *v, FILE *fp, int flags)
{
- char buf[100];
- complex_to_buf(buf, sizeof(buf), v,
- (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
+ PyObject *formatv;
+ char *buf;
+ if (flags & Py_PRINT_RAW)
+ formatv = complex_format(v, PyFloat_STR_PRECISION, 'g');
+ else
+ formatv = complex_format(v, 0, 'r');
+ if (formatv == NULL)
+ return -1;
+ buf = PyString_AS_STRING(formatv);
Py_BEGIN_ALLOW_THREADS
fputs(buf, fp);
Py_END_ALLOW_THREADS
+ Py_DECREF(formatv);
return 0;
}
static PyObject *
complex_repr(PyComplexObject *v)
{
- char buf[100];
- complex_to_buf(buf, sizeof(buf), v, PREC_REPR);
- return PyString_FromString(buf);
+ return complex_format(v, 0, 'r');
}
static PyObject *
complex_str(PyComplexObject *v)
{
- char buf[100];
- complex_to_buf(buf, sizeof(buf), v, PREC_STR);
- return PyString_FromString(buf);
+ return complex_format(v, PyFloat_STR_PRECISION, 'g');
}
static long
@@ -490,56 +513,69 @@ to_complex(PyObject **pobj, Py_complex *pc)
static PyObject *
-complex_add(PyComplexObject *v, PyComplexObject *w)
+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(v->cval,w->cval);
+ result = c_sum(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
-complex_sub(PyComplexObject *v, PyComplexObject *w)
+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(v->cval,w->cval);
+ result = c_diff(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
-complex_mul(PyComplexObject *v, PyComplexObject *w)
+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(v->cval,w->cval);
+ result = c_prod(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
-complex_div(PyComplexObject *v, PyComplexObject *w)
+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(v->cval,w->cval);
+ 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);
}
static PyObject *
-complex_classic_div(PyComplexObject *v, PyComplexObject *w)
+complex_classic_div(PyObject *v, PyObject *w)
{
Py_complex quot;
-
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
if (Py_DivisionWarningFlag >= 2 &&
PyErr_Warn(PyExc_DeprecationWarning,
"classic complex division") < 0)
@@ -547,57 +583,61 @@ complex_classic_div(PyComplexObject *v, PyComplexObject *w)
PyFPE_START_PROTECT("complex_classic_div", return 0)
errno = 0;
- quot = c_quot(v->cval,w->cval);
+ 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);
}
static PyObject *
-complex_remainder(PyComplexObject *v, PyComplexObject *w)
+complex_remainder(PyObject *v, PyObject *w)
{
Py_complex div, mod;
-
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0)
return NULL;
errno = 0;
- div = c_quot(v->cval,w->cval); /* The raw divisor value. */
+ div = c_quot(a, b); /* The raw divisor value. */
if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
- mod = c_diff(v->cval, c_prod(w->cval, div));
+ mod = c_diff(a, c_prod(b, div));
return PyComplex_FromCComplex(mod);
}
static PyObject *
-complex_divmod(PyComplexObject *v, PyComplexObject *w)
+complex_divmod(PyObject *v, PyObject *w)
{
Py_complex div, mod;
PyObject *d, *m, *z;
-
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0)
return NULL;
errno = 0;
- div = c_quot(v->cval,w->cval); /* The raw divisor value. */
+ div = c_quot(a, b); /* The raw divisor value. */
if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
- mod = c_diff(v->cval, c_prod(w->cval, div));
+ mod = c_diff(a, c_prod(b, div));
d = PyComplex_FromCComplex(div);
m = PyComplex_FromCComplex(mod);
z = PyTuple_Pack(2, d, m);
@@ -615,7 +655,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
-
if (z!=Py_None) {
PyErr_SetString(PyExc_ValueError, "complex modulo");
return NULL;
@@ -645,10 +684,12 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
}
static PyObject *
-complex_int_div(PyComplexObject *v, PyComplexObject *w)
+complex_int_div(PyObject *v, PyObject *w)
{
PyObject *t, *r;
-
+ Py_complex a, b;
+ TO_COMPLEX(v, a);
+ TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0)
return NULL;
@@ -742,43 +783,70 @@ complex_coerce(PyObject **pv, PyObject **pw)
static PyObject *
complex_richcompare(PyObject *v, PyObject *w, int op)
{
- int c;
- Py_complex i, j;
PyObject *res;
+ Py_complex i;
+ int equal;
- c = PyNumber_CoerceEx(&v, &w);
- if (c < 0)
- return NULL;
- if (c > 0) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- /* Make sure both arguments are complex. */
- if (!(PyComplex_Check(v) && PyComplex_Check(w))) {
- Py_DECREF(v);
- Py_DECREF(w);
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ if (op != Py_EQ && op != Py_NE) {
+ /* for backwards compatibility, comparisons with non-numbers return
+ * NotImplemented. Only comparisons with core numeric types raise
+ * TypeError.
+ */
+ if (PyInt_Check(w) || PyLong_Check(w) ||
+ PyFloat_Check(w) || PyComplex_Check(w)) {
+ PyErr_SetString(PyExc_TypeError,
+ "no ordering relation is defined "
+ "for complex numbers");
+ return NULL;
+ }
+ goto Unimplemented;
}
- i = ((PyComplexObject *)v)->cval;
- j = ((PyComplexObject *)w)->cval;
- Py_DECREF(v);
- Py_DECREF(w);
+ assert(PyComplex_Check(v));
+ TO_COMPLEX(v, i);
+
+ if (PyInt_Check(w) || PyLong_Check(w)) {
+ /* Check for 0.0 imaginary part first to avoid the rich
+ * comparison when possible.
+ */
+ if (i.imag == 0.0) {
+ PyObject *j, *sub_res;
+ j = PyFloat_FromDouble(i.real);
+ if (j == NULL)
+ return NULL;
- if (op != Py_EQ && op != Py_NE) {
- PyErr_SetString(PyExc_TypeError,
- "no ordering relation is defined for complex numbers");
- 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 ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
- res = Py_True;
+ 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 *
@@ -826,6 +894,41 @@ complex_getnewargs(PyComplexObject *v)
return Py_BuildValue("(dd)", c.real, c.imag);
}
+PyDoc_STRVAR(complex__format__doc,
+"complex.__format__() -> str\n"
+"\n"
+"Converts to a string according to format_spec.");
+
+static PyObject *
+complex__format__(PyObject* self, PyObject* args)
+{
+ PyObject *format_spec;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+ if (PyBytes_Check(format_spec))
+ return _PyComplex_FormatAdvanced(self,
+ PyBytes_AS_STRING(format_spec),
+ PyBytes_GET_SIZE(format_spec));
+ if (PyUnicode_Check(format_spec)) {
+ /* Convert format_spec to a str */
+ PyObject *result;
+ PyObject *str_spec = PyObject_Str(format_spec);
+
+ if (str_spec == NULL)
+ return NULL;
+
+ result = _PyComplex_FormatAdvanced(self,
+ PyBytes_AS_STRING(str_spec),
+ PyBytes_GET_SIZE(str_spec));
+
+ Py_DECREF(str_spec);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+ return NULL;
+}
+
#if 0
static PyObject *
complex_is_finite(PyObject *self)
@@ -850,6 +953,8 @@ static PyMethodDef complex_methods[] = {
complex_is_finite_doc},
#endif
{"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS},
+ {"__format__", (PyCFunction)complex__format__,
+ METH_VARARGS, complex__format__doc},
{NULL, NULL} /* sentinel */
};
@@ -867,13 +972,9 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
const char *s, *start;
char *end;
double x=0.0, y=0.0, z;
- int got_re=0, got_im=0, got_bracket=0, done=0;
- int digit_or_dot;
- int sw_error=0;
- int sign;
- char buffer[256]; /* For errors */
+ int got_bracket=0;
#ifdef Py_USING_UNICODE
- char s_buffer[256];
+ char *s_buffer = NULL;
#endif
Py_ssize_t len;
@@ -883,16 +984,14 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
}
#ifdef Py_USING_UNICODE
else 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))
- return NULL;
+ goto error;
s = s_buffer;
len = strlen(s);
}
@@ -905,147 +1004,138 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
/* position on first nonblank */
start = s;
- while (*s && isspace(Py_CHARMASK(*s)))
+ while (Py_ISSPACE(*s))
s++;
- if (s[0] == '\0') {
- PyErr_SetString(PyExc_ValueError,
- "complex() arg is an empty string");
- return NULL;
- }
- if (s[0] == '(') {
+ if (*s == '(') {
/* Skip over possible bracket from repr(). */
got_bracket = 1;
s++;
- while (*s && isspace(Py_CHARMASK(*s)))
+ while (Py_ISSPACE(*s))
s++;
}
- z = -1.0;
- sign = 1;
- do {
+ /* a valid complex string usually takes one of the three forms:
- switch (*s) {
+ <float> - real part only
+ <float>j - imaginary part only
+ <float><signed-float>j - real and imaginary parts
- case '\0':
- if (s-start != len) {
- PyErr_SetString(
- PyExc_ValueError,
- "complex() arg contains a null byte");
- return NULL;
- }
- if(!done) sw_error=1;
- break;
+ where <float> represents any numeric string that's accepted by the
+ float constructor (including 'nan', 'inf', 'infinity', etc.), and
+ <signed-float> is any string of the form <float> whose first
+ character is '+' or '-'.
+
+ For backwards compatibility, the extra forms
+
+ <float><sign>j
+ <sign>j
+ j
- case ')':
- if (!got_bracket || !(got_re || got_im)) {
- sw_error=1;
- break;
+ are also accepted, though support for these forms may be removed from
+ a future version of Python.
+ */
+
+ /* first look for forms starting with <float> */
+ z = PyOS_string_to_double(s, &end, NULL);
+ if (z == -1.0 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_ValueError))
+ PyErr_Clear();
+ else
+ goto error;
+ }
+ if (end != s) {
+ /* all 4 forms starting with <float> land here */
+ s = end;
+ if (*s == '+' || *s == '-') {
+ /* <float><signed-float>j | <float><sign>j */
+ x = z;
+ y = PyOS_string_to_double(s, &end, NULL);
+ if (y == -1.0 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_ValueError))
+ PyErr_Clear();
+ else
+ goto error;
}
- got_bracket=0;
- done=1;
- s++;
- while (*s && isspace(Py_CHARMASK(*s)))
+ if (end != s)
+ /* <float><signed-float>j */
+ s = end;
+ else {
+ /* <float><sign>j */
+ y = *s == '+' ? 1.0 : -1.0;
s++;
- if (*s) sw_error=1;
- break;
-
- case '-':
- sign = -1;
- /* Fallthrough */
- case '+':
- if (done) sw_error=1;
- s++;
- if ( *s=='\0'||*s=='+'||*s=='-'||*s==')'||
- isspace(Py_CHARMASK(*s)) ) sw_error=1;
- break;
-
- case 'J':
- case 'j':
- if (got_im || done) {
- sw_error = 1;
- break;
- }
- if (z<0.0) {
- y=sign;
}
- else{
- y=sign*z;
- }
- got_im=1;
+ if (!(*s == 'j' || *s == 'J'))
+ goto parse_error;
s++;
- if (*s!='+' && *s!='-' )
- done=1;
- break;
-
- default:
- if (isspace(Py_CHARMASK(*s))) {
- while (*s && isspace(Py_CHARMASK(*s)))
- s++;
- if (*s && *s != ')')
- sw_error=1;
- else
- done = 1;
- break;
- }
- digit_or_dot =
- (*s=='.' || isdigit(Py_CHARMASK(*s)));
- if (done||!digit_or_dot) {
- sw_error=1;
- break;
- }
- errno = 0;
- PyFPE_START_PROTECT("strtod", return 0)
- z = PyOS_ascii_strtod(s, &end) ;
- PyFPE_END_PROTECT(z)
- if (errno == ERANGE && fabs(z) >= 1.0) {
- PyOS_snprintf(buffer, sizeof(buffer),
- "float() out of range: %.150s", s);
- PyErr_SetString(
- PyExc_ValueError,
- buffer);
- return NULL;
- }
- s=end;
- if (*s=='J' || *s=='j') {
-
- break;
- }
- if (got_re) {
- sw_error=1;
- break;
- }
+ }
+ else if (*s == 'j' || *s == 'J') {
+ /* <float>j */
+ s++;
+ y = z;
+ }
+ else
+ /* <float> */
+ x = z;
+ }
+ else {
+ /* not starting with <float>; must be <sign>j or j */
+ if (*s == '+' || *s == '-') {
+ /* <sign>j */
+ y = *s == '+' ? 1.0 : -1.0;
+ s++;
+ }
+ else
+ /* j */
+ y = 1.0;
+ if (!(*s == 'j' || *s == 'J'))
+ goto parse_error;
+ s++;
+ }
- /* accept a real part */
- x=sign*z;
- got_re=1;
- if (got_im) done=1;
- z = -1.0;
- sign = 1;
- break;
+ /* 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++;
+ }
- } /* end of switch */
+ /* we should now be at the end of the string */
+ if (s-start != len)
+ goto parse_error;
- } while (s - start < len && !sw_error);
-
- if (sw_error || got_bracket) {
- PyErr_SetString(PyExc_ValueError,
- "complex() arg is a malformed string");
- return NULL;
- }
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
return complex_subtype_from_doubles(type, x, y);
+
+ parse_error:
+ PyErr_SetString(PyExc_ValueError,
+ "complex() arg is a malformed string");
+ error:
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return NULL;
}
static PyObject *
complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *r, *i, *tmp, *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;
@@ -1080,26 +1170,15 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
- /* XXX Hack to support classes with __complex__ method */
- if (complexstr == NULL) {
- complexstr = PyString_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;
@@ -1248,7 +1327,8 @@ PyTypeObject PyComplex_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE, /* tp_flags */
complex_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index bfe6656c29..135b6d2a9a 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -224,7 +224,8 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
return NULL;
}
self = PyTuple_GET_ITEM(args, 0);
- if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
+ if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type))) {
PyErr_Format(PyExc_TypeError,
"descriptor '%.200s' "
"requires a '%.100s' object "
@@ -282,7 +283,8 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
return NULL;
}
self = PyTuple_GET_ITEM(args, 0);
- if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) {
+ if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type))) {
PyErr_Format(PyExc_TypeError,
"descriptor '%.200s' "
"requires a '%.100s' object "
@@ -1046,7 +1048,8 @@ 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_RealIsSubclass((PyObject *)Py_TYPE(self),
+ (PyObject *)(descr->d_type)));
wp = PyObject_GC_New(wrapperobject, &wrappertype);
if (wp != NULL) {
@@ -1102,7 +1105,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},
@@ -1119,7 +1122,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);
}
@@ -1129,7 +1132,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);
}
@@ -1139,7 +1142,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);
}
@@ -1208,11 +1211,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)
@@ -1230,15 +1232,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);
@@ -1280,26 +1279,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);
- return -1;
- }
+ }
+ 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 {
+ }
+ else if (PyErr_ExceptionMatches(PyExc_Exception)) {
PyErr_Clear();
}
+ else {
+ return -1;
+ }
}
return 0;
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 9d19b1db13..e8f8b4a846 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -180,6 +180,24 @@ show_alloc(void)
}
#endif
+/* Debug statistic to count GC tracking of dicts */
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+ fprintf(stderr, "Dicts created: %" PY_FORMAT_SIZE_T "d\n",
+ count_tracked + count_untracked);
+ fprintf(stderr, "Dicts tracked by the GC: %" PY_FORMAT_SIZE_T
+ "d\n", count_tracked);
+ fprintf(stderr, "%.2f%% dict tracking rate\n\n",
+ (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
/* Initialization macros.
There are two ways to create a dict: PyDict_New() is the main C API
function, and the tp_new slot maps to dict_new(). In the latter case we
@@ -233,6 +251,9 @@ PyDict_New(void)
#ifdef SHOW_ALLOC_COUNT
Py_AtExit(show_alloc);
#endif
+#ifdef SHOW_TRACK_COUNT
+ Py_AtExit(show_track);
+#endif
}
if (numfree) {
mp = free_list[--numfree];
@@ -262,10 +283,12 @@ PyDict_New(void)
#endif
}
mp->ma_lookup = lookdict_string;
+#ifdef SHOW_TRACK_COUNT
+ count_untracked++;
+#endif
#ifdef SHOW_CONVERSION_COUNTS
++created;
#endif
- _PyObject_GC_TRACK(mp);
return (PyObject *)mp;
}
@@ -433,6 +456,53 @@ lookdict_string(PyDictObject *mp, PyObject *key, register long hash)
return 0;
}
+#ifdef SHOW_TRACK_COUNT
+#define INCREASE_TRACK_COUNT \
+ (count_tracked++, count_untracked--);
+#define DECREASE_TRACK_COUNT \
+ (count_tracked--, count_untracked++);
+#else
+#define INCREASE_TRACK_COUNT
+#define DECREASE_TRACK_COUNT
+#endif
+
+#define MAINTAIN_TRACKING(mp, key, value) \
+ do { \
+ if (!_PyObject_GC_IS_TRACKED(mp)) { \
+ if (_PyObject_GC_MAY_BE_TRACKED(key) || \
+ _PyObject_GC_MAY_BE_TRACKED(value)) { \
+ _PyObject_GC_TRACK(mp); \
+ INCREASE_TRACK_COUNT \
+ } \
+ } \
+ } while(0)
+
+void
+_PyDict_MaybeUntrack(PyObject *op)
+{
+ PyDictObject *mp;
+ PyObject *value;
+ Py_ssize_t mask, i;
+ PyDictEntry *ep;
+
+ if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+ return;
+
+ mp = (PyDictObject *) op;
+ ep = mp->ma_table;
+ mask = mp->ma_mask;
+ for (i = 0; i <= mask; i++) {
+ if ((value = ep[i].me_value) == NULL)
+ continue;
+ if (_PyObject_GC_MAY_BE_TRACKED(value) ||
+ _PyObject_GC_MAY_BE_TRACKED(ep[i].me_key))
+ return;
+ }
+ DECREASE_TRACK_COUNT
+ _PyObject_GC_UNTRACK(op);
+}
+
+
/*
Internal routine to insert a new item into the table.
Used both by the internal resize routine and by the public insert routine.
@@ -453,6 +523,7 @@ insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
Py_DECREF(value);
return -1;
}
+ MAINTAIN_TRACKING(mp, key, value);
if (ep->me_value != NULL) {
old_value = ep->me_value;
ep->me_value = value;
@@ -492,6 +563,7 @@ insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
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) {
@@ -640,9 +712,11 @@ 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... */
+ /* We can arrive here with a NULL tstate during initialization: try
+ running "python -Wi" for an example related to string interning.
+ Let's just hope that no exception occurs then... This must be
+ _PyThreadState_Current and not PyThreadState_GET() because in debug
+ mode, the latter complains if tstate is NULL. */
tstate = _PyThreadState_Current;
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
@@ -1081,15 +1155,19 @@ dict_subscript(PyDictObject *mp, register PyObject *key)
if (v == NULL) {
if (!PyDict_CheckExact(mp)) {
/* Look up __missing__ method if we're a subclass. */
- PyObject *missing;
+ PyObject *missing, *res;
static PyObject *missing_str = NULL;
- if (missing_str == NULL)
- missing_str =
- PyString_InternFromString("__missing__");
- missing = _PyType_Lookup(Py_TYPE(mp), missing_str);
- if (missing != NULL)
- return PyObject_CallFunctionObjArgs(missing,
- (PyObject *)mp, key, 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;
@@ -1902,8 +1980,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 (!PyString_CheckExact(key) ||
@@ -2106,6 +2183,18 @@ PyDoc_STRVAR(itervalues__doc__,
PyDoc_STRVAR(iteritems__doc__,
"D.iteritems() -> an iterator over the (key, value) items of D");
+/* Forward */
+static PyObject *dictkeys_new(PyObject *);
+static PyObject *dictitems_new(PyObject *);
+static PyObject *dictvalues_new(PyObject *);
+
+PyDoc_STRVAR(viewkeys__doc__,
+ "D.viewkeys() -> a set-like object providing a view on D's keys");
+PyDoc_STRVAR(viewitems__doc__,
+ "D.viewitems() -> a set-like object providing a view on D's items");
+PyDoc_STRVAR(viewvalues__doc__,
+ "D.viewvalues() -> an object providing a view on D's values");
+
static PyMethodDef mapp_methods[] = {
{"__contains__",(PyCFunction)dict_contains, METH_O | METH_COEXIST,
contains__doc__},
@@ -2129,6 +2218,12 @@ static PyMethodDef mapp_methods[] = {
items__doc__},
{"values", (PyCFunction)dict_values, METH_NOARGS,
values__doc__},
+ {"viewkeys", (PyCFunction)dictkeys_new, METH_NOARGS,
+ viewkeys__doc__},
+ {"viewitems", (PyCFunction)dictitems_new, METH_NOARGS,
+ viewitems__doc__},
+ {"viewvalues", (PyCFunction)dictvalues_new, METH_NOARGS,
+ viewvalues__doc__},
{"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS,
update__doc__},
{"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS,
@@ -2202,9 +2297,18 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0);
INIT_NONZERO_DICT_SLOTS(d);
d->ma_lookup = lookdict_string;
+ /* The object has been implicitly tracked by tp_alloc */
+ if (type == &PyDict_Type)
+ _PyObject_GC_UNTRACK(d);
#ifdef SHOW_CONVERSION_COUNTS
++created;
#endif
+#ifdef SHOW_TRACK_COUNT
+ if (_PyObject_GC_IS_TRACKED(d))
+ count_tracked++;
+ else
+ count_untracked++;
+#endif
}
return self;
}
@@ -2613,3 +2717,494 @@ PyTypeObject PyDictIterItem_Type = {
dictiter_methods, /* tp_methods */
0,
};
+
+/***********************************************/
+/* View objects for keys(), items(), values(). */
+/***********************************************/
+
+/* The instance lay-out is the same for all three; but the type differs. */
+
+typedef struct {
+ PyObject_HEAD
+ PyDictObject *dv_dict;
+} dictviewobject;
+
+
+static void
+dictview_dealloc(dictviewobject *dv)
+{
+ Py_XDECREF(dv->dv_dict);
+ PyObject_GC_Del(dv);
+}
+
+static int
+dictview_traverse(dictviewobject *dv, visitproc visit, void *arg)
+{
+ Py_VISIT(dv->dv_dict);
+ return 0;
+}
+
+static Py_ssize_t
+dictview_len(dictviewobject *dv)
+{
+ Py_ssize_t len = 0;
+ if (dv->dv_dict != NULL)
+ len = dv->dv_dict->ma_used;
+ return len;
+}
+
+static PyObject *
+dictview_new(PyObject *dict, PyTypeObject *type)
+{
+ dictviewobject *dv;
+ if (dict == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ if (!PyDict_Check(dict)) {
+ /* XXX Get rid of this restriction later */
+ PyErr_Format(PyExc_TypeError,
+ "%s() requires a dict argument, not '%s'",
+ type->tp_name, dict->ob_type->tp_name);
+ return NULL;
+ }
+ dv = PyObject_GC_New(dictviewobject, type);
+ if (dv == NULL)
+ return NULL;
+ Py_INCREF(dict);
+ dv->dv_dict = (PyDictObject *)dict;
+ _PyObject_GC_TRACK(dv);
+ return (PyObject *)dv;
+}
+
+/* TODO(guido): The views objects are not complete:
+
+ * support more set operations
+ * support arbitrary mappings?
+ - either these should be static or exported in dictobject.h
+ - if public then they should probably be in builtins
+*/
+
+/* Return 1 if self is a subset of other, iterating over self;
+ 0 if not; -1 if an error occurred. */
+static int
+all_contained_in(PyObject *self, PyObject *other)
+{
+ PyObject *iter = PyObject_GetIter(self);
+ int ok = 1;
+
+ if (iter == NULL)
+ return -1;
+ for (;;) {
+ PyObject *next = PyIter_Next(iter);
+ if (next == NULL) {
+ if (PyErr_Occurred())
+ ok = -1;
+ break;
+ }
+ ok = PySequence_Contains(other, next);
+ Py_DECREF(next);
+ if (ok <= 0)
+ break;
+ }
+ Py_DECREF(iter);
+ return ok;
+}
+
+static PyObject *
+dictview_richcompare(PyObject *self, PyObject *other, int op)
+{
+ Py_ssize_t len_self, len_other;
+ int ok;
+ PyObject *result;
+
+ assert(self != NULL);
+ assert(PyDictViewSet_Check(self));
+ assert(other != NULL);
+
+ if (!PyAnySet_Check(other) && !PyDictViewSet_Check(other)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ len_self = PyObject_Size(self);
+ if (len_self < 0)
+ return NULL;
+ len_other = PyObject_Size(other);
+ if (len_other < 0)
+ return NULL;
+
+ ok = 0;
+ switch(op) {
+
+ case Py_NE:
+ case Py_EQ:
+ if (len_self == len_other)
+ ok = all_contained_in(self, other);
+ if (op == Py_NE && ok >= 0)
+ ok = !ok;
+ break;
+
+ case Py_LT:
+ if (len_self < len_other)
+ ok = all_contained_in(self, other);
+ break;
+
+ case Py_LE:
+ if (len_self <= len_other)
+ ok = all_contained_in(self, other);
+ break;
+
+ case Py_GT:
+ if (len_self > len_other)
+ ok = all_contained_in(other, self);
+ break;
+
+ case Py_GE:
+ if (len_self >= len_other)
+ ok = all_contained_in(other, self);
+ break;
+
+ }
+ if (ok < 0)
+ return NULL;
+ result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+static PyObject *
+dictview_repr(dictviewobject *dv)
+{
+ PyObject *seq;
+ PyObject *seq_str;
+ PyObject *result;
+
+ seq = PySequence_List((PyObject *)dv);
+ if (seq == NULL)
+ return NULL;
+
+ seq_str = PyObject_Repr(seq);
+ result = PyString_FromFormat("%s(%s)", Py_TYPE(dv)->tp_name,
+ PyString_AS_STRING(seq_str));
+ Py_DECREF(seq_str);
+ Py_DECREF(seq);
+ return result;
+}
+
+/*** dict_keys ***/
+
+static PyObject *
+dictkeys_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterKey_Type);
+}
+
+static int
+dictkeys_contains(dictviewobject *dv, PyObject *obj)
+{
+ if (dv->dv_dict == NULL)
+ return 0;
+ return PyDict_Contains((PyObject *)dv->dv_dict, obj);
+}
+
+static PySequenceMethods dictkeys_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)dictkeys_contains, /* sq_contains */
+};
+
+static PyObject*
+dictviews_sub(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "difference_update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_and(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "intersection_update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_or(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "update", "O", other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyObject*
+dictviews_xor(PyObject* self, PyObject *other)
+{
+ PyObject *result = PySet_New(self);
+ PyObject *tmp;
+ if (result == NULL)
+ return NULL;
+
+ tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O",
+ other);
+ if (tmp == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ Py_DECREF(tmp);
+ return result;
+}
+
+static PyNumberMethods dictviews_as_number = {
+ 0, /*nb_add*/
+ (binaryfunc)dictviews_sub, /*nb_subtract*/
+ 0, /*nb_multiply*/
+ 0, /*nb_divide*/
+ 0, /*nb_remainder*/
+ 0, /*nb_divmod*/
+ 0, /*nb_power*/
+ 0, /*nb_negative*/
+ 0, /*nb_positive*/
+ 0, /*nb_absolute*/
+ 0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ (binaryfunc)dictviews_and, /*nb_and*/
+ (binaryfunc)dictviews_xor, /*nb_xor*/
+ (binaryfunc)dictviews_or, /*nb_or*/
+};
+
+static PyMethodDef dictkeys_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictKeys_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_keys", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ &dictviews_as_number, /* tp_as_number */
+ &dictkeys_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ dictview_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictkeys_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictkeys_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictkeys_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictKeys_Type);
+}
+
+/*** dict_items ***/
+
+static PyObject *
+dictitems_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterItem_Type);
+}
+
+static int
+dictitems_contains(dictviewobject *dv, PyObject *obj)
+{
+ PyObject *key, *value, *found;
+ if (dv->dv_dict == NULL)
+ return 0;
+ if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2)
+ return 0;
+ key = PyTuple_GET_ITEM(obj, 0);
+ value = PyTuple_GET_ITEM(obj, 1);
+ found = PyDict_GetItem((PyObject *)dv->dv_dict, key);
+ if (found == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+ }
+ return PyObject_RichCompareBool(value, found, Py_EQ);
+}
+
+static PySequenceMethods dictitems_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)dictitems_contains, /* sq_contains */
+};
+
+static PyMethodDef dictitems_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictItems_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_items", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ &dictviews_as_number, /* tp_as_number */
+ &dictitems_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_CHECKTYPES, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ dictview_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictitems_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictitems_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictitems_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictItems_Type);
+}
+
+/*** dict_values ***/
+
+static PyObject *
+dictvalues_iter(dictviewobject *dv)
+{
+ if (dv->dv_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return dictiter_new(dv->dv_dict, &PyDictIterValue_Type);
+}
+
+static PySequenceMethods dictvalues_as_sequence = {
+ (lenfunc)dictview_len, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)0, /* sq_contains */
+};
+
+static PyMethodDef dictvalues_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+PyTypeObject PyDictValues_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "dict_values", /* tp_name */
+ sizeof(dictviewobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictview_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ (reprfunc)dictview_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &dictvalues_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)dictview_traverse, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictvalues_iter, /* tp_iter */
+ 0, /* tp_iternext */
+ dictvalues_methods, /* tp_methods */
+ 0,
+};
+
+static PyObject *
+dictvalues_new(PyObject *dict)
+{
+ return dictview_new(dict, &PyDictValues_Type);
+}
diff --git a/Objects/enumobject.c b/Objects/enumobject.c
index d0c8782966..1ef381f391 100644
--- a/Objects/enumobject.c
+++ b/Objects/enumobject.c
@@ -223,7 +223,8 @@ static PyObject *
reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Py_ssize_t n;
- PyObject *seq;
+ PyObject *seq, *reversed_meth;
+ static PyObject *reversed_cache = NULL;
reversedobject *ro;
if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
@@ -232,8 +233,26 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
return NULL;
- if (PyObject_HasAttrString(seq, "__reversed__"))
- return PyObject_CallMethod(seq, "__reversed__", NULL);
+ if (PyInstance_Check(seq)) {
+ reversed_meth = PyObject_GetAttrString(seq, "__reversed__");
+ if (reversed_meth == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__",
+ &reversed_cache);
+ if (reversed_meth == NULL && PyErr_Occurred())
+ return NULL;
+ }
+ if (reversed_meth != NULL) {
+ PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
+ Py_DECREF(reversed_meth);
+ return res;
+ }
if (!PySequence_Check(seq)) {
PyErr_SetString(PyExc_TypeError,
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index a0d7b536a1..711c87dea9 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -9,7 +9,6 @@
#include "structmember.h"
#include "osdefs.h"
-#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
#define EXC_MODULE_NAME "exceptions."
/* NOTE: If the exception class hierarchy changes, don't forget to update
@@ -2047,28 +2046,6 @@ static PyMethodDef functions[] = {
if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
Py_FatalError("Module dictionary insertion problem.");
-#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
-/* crt variable checking in VisualStudio .NET 2005 */
-#include <crtdbg.h>
-
-static int prevCrtReportMode;
-static _invalid_parameter_handler prevCrtHandler;
-
-/* Invalid parameter handler. Sets a ValueError exception */
-static void
-InvalidParameterHandler(
- const wchar_t * expression,
- const wchar_t * function,
- const wchar_t * file,
- unsigned int line,
- uintptr_t pReserved)
-{
- /* Do nothing, allow execution to continue. Usually this
- * means that the CRT will set errno to EINVAL
- */
-}
-#endif
-
PyMODINIT_FUNC
_PyExc_Init(void)
@@ -2202,7 +2179,7 @@ _PyExc_Init(void)
PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
if (!PyExc_MemoryErrorInst)
- Py_FatalError("Cannot pre-allocate MemoryError instance\n");
+ Py_FatalError("Cannot pre-allocate MemoryError instance");
PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL);
if (!PyExc_RecursionErrorInst)
@@ -2228,23 +2205,11 @@ _PyExc_Init(void)
}
Py_DECREF(bltinmod);
-
-#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
- /* Set CRT argument error handler */
- prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
- /* turn off assertions in debug mode */
- prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
-#endif
}
void
_PyExc_Fini(void)
{
- Py_XDECREF(PyExc_MemoryErrorInst);
- PyExc_MemoryErrorInst = NULL;
-#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
- /* reset CRT error handling */
- _set_invalid_parameter_handler(prevCrtHandler);
- _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
-#endif
+ Py_CLEAR(PyExc_MemoryErrorInst);
+ Py_CLEAR(PyExc_RecursionErrorInst);
}
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index df5a102ab4..974d6424e4 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -16,19 +16,13 @@
#include <windows.h>
#endif
-#ifdef _MSC_VER
-/* Need GetVersion to see if on NT so safe to use _wfopen */
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif /* _MSC_VER */
-
#if defined(PYOS_OS2) && defined(PYCC_GCC)
#include <io.h>
#endif
#define BUF(v) PyString_AS_STRING((PyStringObject *)v)
-#ifndef DONT_HAVE_ERRNO_H
+#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -188,6 +182,87 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
return (PyObject *) f;
}
+#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
+#define Py_VERIFY_WINNT
+/* The CRT on windows compiled with Visual Studio 2005 and higher may
+ * assert if given invalid mode strings. This is all fine and well
+ * in static languages like C where the mode string is typcially hard
+ * coded. But in Python, were we pass in the mode string from the user,
+ * we need to verify it first manually
+ */
+static int _PyVerify_Mode_WINNT(const char *mode)
+{
+ /* See if mode string is valid on Windows to avoid hard assertions */
+ /* remove leading spacese */
+ int singles = 0;
+ int pairs = 0;
+ int encoding = 0;
+ const char *s, *c;
+
+ while(*mode == ' ') /* strip initial spaces */
+ ++mode;
+ if (!strchr("rwa", *mode)) /* must start with one of these */
+ return 0;
+ while (*++mode) {
+ if (*mode == ' ' || *mode == 'N') /* ignore spaces and N */
+ continue;
+ s = "+TD"; /* each of this can appear only once */
+ c = strchr(s, *mode);
+ if (c) {
+ ptrdiff_t idx = s-c;
+ if (singles & (1<<idx))
+ return 0;
+ singles |= (1<<idx);
+ continue;
+ }
+ s = "btcnSR"; /* only one of each letter in the pairs allowed */
+ c = strchr(s, *mode);
+ if (c) {
+ ptrdiff_t idx = (s-c)/2;
+ if (pairs & (1<<idx))
+ return 0;
+ pairs |= (1<<idx);
+ continue;
+ }
+ if (*mode == ',') {
+ encoding = 1;
+ break;
+ }
+ return 0; /* found an invalid char */
+ }
+
+ if (encoding) {
+ char *e[] = {"UTF-8", "UTF-16LE", "UNICODE"};
+ while (*mode == ' ')
+ ++mode;
+ /* find 'ccs =' */
+ if (strncmp(mode, "ccs", 3))
+ return 0;
+ mode += 3;
+ while (*mode == ' ')
+ ++mode;
+ if (*mode != '=')
+ return 0;
+ while (*mode == ' ')
+ ++mode;
+ for(encoding = 0; encoding<_countof(e); ++encoding) {
+ size_t l = strlen(e[encoding]);
+ if (!strncmp(mode, e[encoding], l)) {
+ mode += l; /* found a valid encoding */
+ break;
+ }
+ }
+ if (encoding == _countof(e))
+ return 0;
+ }
+ /* skip trailing spaces */
+ while (*mode == ' ')
+ ++mode;
+
+ return *mode == '\0'; /* must be at the end of the string */
+}
+#endif
+
/* check for known incorrect mode strings - problem is, platforms are
free to accept any mode characters they like and are supposed to
ignore stuff they don't understand... write or append mode with
@@ -230,7 +305,13 @@ _PyFile_SanitizeMode(char *mode)
"one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
return -1;
}
-
+#ifdef Py_VERIFY_WINNT
+ /* additional checks on NT with visual studio 2005 and higher */
+ if (!_PyVerify_Mode_WINNT(mode)) {
+ PyErr_Format(PyExc_ValueError, "Invalid mode ('%.50s')", mode);
+ return -1;
+ }
+#endif
return 0;
}
@@ -342,6 +423,7 @@ close_the_file(PyFileObject *f)
int sts = 0;
int (*local_close)(FILE *);
FILE *local_fp = f->f_fp;
+ char *local_setbuf = f->f_setbuf;
if (local_fp != NULL) {
local_close = f->f_close;
if (local_close != NULL && f->unlocked_count > 0) {
@@ -365,10 +447,15 @@ close_the_file(PyFileObject *f)
* called. */
f->f_fp = NULL;
if (local_close != NULL) {
+ /* Issue #9295: must temporarily reset f_setbuf so that another
+ thread doesn't free it when running file_close() concurrently.
+ Otherwise this close() will crash when flushing the buffer. */
+ f->f_setbuf = NULL;
Py_BEGIN_ALLOW_THREADS
errno = 0;
sts = (*local_close)(local_fp);
Py_END_ALLOW_THREADS
+ f->f_setbuf = local_setbuf;
if (sts == EOF)
return PyErr_SetFromErrno(PyExc_IOError);
if (sts != 0)
@@ -1023,8 +1110,8 @@ file_read(PyFileObject *f, PyObject *args)
break;
}
}
- if (bytesread != buffersize)
- _PyString_Resize(&v, bytesread);
+ if (bytesread != buffersize && _PyString_Resize(&v, bytesread))
+ return NULL;
return v;
}
@@ -1277,8 +1364,8 @@ getline_via_fgets(PyFileObject *f, FILE *fp)
/* overwrite the trailing null byte */
pvfree = BUF(v) + (prev_v_size - 1);
}
- if (BUF(v) + total_v_size != p)
- _PyString_Resize(&v, p - BUF(v));
+ if (BUF(v) + total_v_size != p && _PyString_Resize(&v, p - BUF(v)))
+ return NULL;
return v;
#undef INITBUFSIZE
#undef MAXBUFSIZE
@@ -1390,8 +1477,8 @@ get_line(PyFileObject *f, int n)
}
used_v_size = buf - BUF(v);
- if (used_v_size != total_v_size)
- _PyString_Resize(&v, used_v_size);
+ if (used_v_size != total_v_size && _PyString_Resize(&v, used_v_size))
+ return NULL;
return v;
}
@@ -1457,8 +1544,10 @@ PyFile_GetLine(PyObject *f, int n)
"EOF when reading a line");
}
else if (s[len-1] == '\n') {
- if (result->ob_refcnt == 1)
- _PyString_Resize(&result, len-1);
+ if (result->ob_refcnt == 1) {
+ if (_PyString_Resize(&result, len-1))
+ return NULL;
+ }
else {
PyObject *v;
v = PyString_FromStringAndSize(s, len-1);
@@ -1652,8 +1741,10 @@ static PyObject *
file_write(PyFileObject *f, PyObject *args)
{
Py_buffer pbuf;
- char *s;
+ const char *s;
Py_ssize_t n, n2;
+ PyObject *encoded = NULL;
+
if (f->f_fp == NULL)
return err_closed();
if (!f->writable)
@@ -1663,14 +1754,41 @@ file_write(PyFileObject *f, PyObject *args)
return NULL;
s = pbuf.buf;
n = pbuf.len;
- } else
- if (!PyArg_ParseTuple(args, "t#", &s, &n))
- return NULL;
+ }
+ else {
+ const char *encoding, *errors;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, "O", &text))
+ return NULL;
+
+ if (PyString_Check(text)) {
+ s = PyString_AS_STRING(text);
+ n = PyString_GET_SIZE(text);
+ } else if (PyUnicode_Check(text)) {
+ if (f->f_encoding != Py_None)
+ encoding = PyString_AS_STRING(f->f_encoding);
+ else
+ encoding = PyUnicode_GetDefaultEncoding();
+ if (f->f_errors != Py_None)
+ errors = PyString_AS_STRING(f->f_errors);
+ else
+ errors = "strict";
+ encoded = PyUnicode_AsEncodedString(text, encoding, errors);
+ if (encoded == NULL)
+ return NULL;
+ s = PyString_AS_STRING(encoded);
+ n = PyString_GET_SIZE(encoded);
+ } else {
+ if (PyObject_AsCharBuffer(text, &s, &n))
+ return NULL;
+ }
+ }
f->f_softspace = 0;
FILE_BEGIN_ALLOW_THREADS(f)
errno = 0;
n2 = fwrite(s, 1, n, f->f_fp);
FILE_END_ALLOW_THREADS(f)
+ Py_XDECREF(encoded);
if (f->f_binary)
PyBuffer_Release(&pbuf);
if (n2 != n) {
@@ -1737,6 +1855,11 @@ file_writelines(PyFileObject *f, PyObject *seq)
}
PyList_SetItem(list, j, line);
}
+ /* The iterator might have closed the file on us. */
+ if (f->f_fp == NULL) {
+ err_closed();
+ goto error;
+ }
}
if (j == 0)
break;
@@ -2191,6 +2314,9 @@ file_init(PyObject *self, PyObject *args, PyObject *kwds)
char *mode = "r";
int bufsize = -1;
int wideargument = 0;
+#ifdef MS_WINDOWS
+ PyObject *po;
+#endif
assert(PyFile_Check(self));
if (foself->f_fp != NULL) {
@@ -2201,20 +2327,17 @@ file_init(PyObject *self, PyObject *args, PyObject *kwds)
Py_DECREF(closeresult);
}
-#ifdef Py_WIN_WIDE_FILENAMES
- if (GetVersion() < 0x80000000) { /* On NT, so wide API available */
- PyObject *po;
- if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
- kwlist, &po, &mode, &bufsize)) {
- wideargument = 1;
- if (fill_file_fields(foself, NULL, po, mode,
- fclose) == NULL)
- goto Error;
- } else {
- /* Drop the argument parsing error as narrow
- strings are also valid. */
- PyErr_Clear();
- }
+#ifdef MS_WINDOWS
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
+ kwlist, &po, &mode, &bufsize)) {
+ wideargument = 1;
+ if (fill_file_fields(foself, NULL, po, mode,
+ fclose) == NULL)
+ goto Error;
+ } else {
+ /* Drop the argument parsing error as narrow
+ strings are also valid. */
+ PyErr_Clear();
}
#endif
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 0bb6961c86..63b7c17b6b 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 <ieeefp.h>
-#endif
-
#ifdef _OSF_SOURCE
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
extern int finite(double);
@@ -72,7 +68,7 @@ PyFloat_GetMin(void)
static PyTypeObject FloatInfoType = {0, 0, 0, 0, 0, 0};
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\
@@ -99,7 +95,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
@@ -177,13 +173,14 @@ still supported but now *officially* useless: if pend is not NULL,
PyObject *
PyFloat_FromString(PyObject *v, char **pend)
{
- const char *s, *last, *end, *sp;
+ const char *s, *last, *end;
double x;
char buffer[256]; /* for errors */
#ifdef Py_USING_UNICODE
- char s_buffer[256]; /* for objects convertible to a char buffer */
+ char *s_buffer = NULL;
#endif
Py_ssize_t len;
+ PyObject *result = NULL;
if (pend)
*pend = NULL;
@@ -193,101 +190,50 @@ PyFloat_FromString(PyObject *v, char **pend)
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(v)) {
- if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
- PyErr_SetString(PyExc_ValueError,
- "Unicode float() literal too long 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))
- return NULL;
+ goto error;
s = s_buffer;
len = strlen(s);
}
#endif
else if (PyObject_AsCharBuffer(v, &s, &len)) {
PyErr_SetString(PyExc_TypeError,
- "float() argument must be a string or a number");
+ "float() argument must be a string or a number");
return NULL;
}
-
last = s + len;
- while (*s && isspace(Py_CHARMASK(*s)))
+
+ while (Py_ISSPACE(*s))
s++;
- if (*s == '\0') {
- PyErr_SetString(PyExc_ValueError, "empty string for float()");
- return NULL;
- }
- sp = s;
- /* We don't care about overflow or underflow. If the platform supports
- * them, infinities and signed zeroes (on underflow) are fine.
- * However, strtod can return 0 for denormalized numbers, where atof
- * does not. So (alas!) we special-case a zero result. Note that
- * whether strtod sets errno on underflow is not defined, so we can't
- * key off errno.
- */
- PyFPE_START_PROTECT("strtod", return NULL)
- x = PyOS_ascii_strtod(s, (char **)&end);
- PyFPE_END_PROTECT(x)
- errno = 0;
- /* Believe it or not, Solaris 2.6 can move end *beyond* the null
- byte at the end of the string, when the input is inf(inity). */
- if (end > last)
- end = last;
- /* Check for inf and nan. This is done late because it rarely happens. */
- if (end == s) {
- char *p = (char*)sp;
- int sign = 1;
-
- if (*p == '-') {
- sign = -1;
- p++;
- }
- if (*p == '+') {
- p++;
- }
- if (PyOS_strnicmp(p, "inf", 4) == 0) {
- Py_RETURN_INF(sign);
- }
- if (PyOS_strnicmp(p, "infinity", 9) == 0) {
- Py_RETURN_INF(sign);
- }
-#ifdef Py_NAN
- if(PyOS_strnicmp(p, "nan", 4) == 0) {
- Py_RETURN_NAN;
- }
-#endif
- PyOS_snprintf(buffer, sizeof(buffer),
- "invalid literal for float(): %.200s", s);
- PyErr_SetString(PyExc_ValueError, buffer);
- return NULL;
- }
- /* Since end != s, the platform made *some* kind of sense out
- of the input. Trust it. */
- while (*end && isspace(Py_CHARMASK(*end)))
+ /* 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 != '\0') {
+ if (end == last)
+ result = PyFloat_FromDouble(x);
+ else {
PyOS_snprintf(buffer, sizeof(buffer),
"invalid literal for float(): %.200s", s);
PyErr_SetString(PyExc_ValueError, buffer);
- return NULL;
+ result = NULL;
}
- else if (end != last) {
- PyErr_SetString(PyExc_ValueError,
- "null byte in argument for float()");
- return NULL;
- }
- if (x == 0.0) {
- /* See above -- may have been strtod being anal
- about denorms. */
- PyFPE_START_PROTECT("atof", return NULL)
- x = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(x)
- errno = 0; /* whether atof ever set errno is undefined */
- }
- return PyFloat_FromDouble(x);
+
+ error:
+#ifdef Py_USING_UNICODE
+ if (s_buffer)
+ PyMem_FREE(s_buffer);
+#endif
+ return result;
}
static void
@@ -338,74 +284,6 @@ PyFloat_AsDouble(PyObject *op)
/* Methods */
-static void
-format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
-{
- register char *cp;
- char format[32];
- int i;
-
- /* Subroutine for float_repr and float_print.
- We want float numbers to be recognizable as such,
- i.e., they should contain a decimal point or an exponent.
- However, %g may print the number as an integer;
- in such cases, we append ".0" to the string. */
-
- assert(PyFloat_Check(v));
- PyOS_snprintf(format, 32, "%%.%ig", precision);
- PyOS_ascii_formatd(buf, buflen, format, v->ob_fval);
- cp = buf;
- if (*cp == '-')
- cp++;
- for (; *cp != '\0'; cp++) {
- /* Any non-digit means it's not an integer;
- this takes care of NAN and INF as well. */
- if (!isdigit(Py_CHARMASK(*cp)))
- break;
- }
- if (*cp == '\0') {
- *cp++ = '.';
- *cp++ = '0';
- *cp++ = '\0';
- return;
- }
- /* Checking the next three chars should be more than enough to
- * detect inf or nan, even on Windows. We check for inf or nan
- * at last because they are rare cases.
- */
- for (i=0; *cp != '\0' && i<3; cp++, i++) {
- if (isdigit(Py_CHARMASK(*cp)) || *cp == '.')
- continue;
- /* found something that is neither a digit nor point
- * it might be a NaN or INF
- */
-#ifdef Py_NAN
- if (Py_IS_NAN(v->ob_fval)) {
- strcpy(buf, "nan");
- }
- else
-#endif
- if (Py_IS_INFINITY(v->ob_fval)) {
- cp = buf;
- if (*cp == '-')
- cp++;
- strcpy(cp, "inf");
- }
- break;
- }
-
-}
-
-/* XXX PyFloat_AsStringEx should not be a public API function (for one
- XXX thing, its signature passes a buffer without a length; for another,
- XXX it isn't useful outside this file).
-*/
-void
-PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
-{
- format_float(buf, 100, v, precision);
-}
-
/* Macro and helper that convert PyObject obj to a C double and store
the value in dbl; this replaces the functionality of the coercion
slot function. If conversion to double raises an exception, obj is
@@ -442,66 +320,72 @@ convert_to_double(PyObject **v, double *dbl)
return 0;
}
-/* Precisions used by repr() and str(), respectively.
-
- The repr() precision (17 significant decimal digits) is the minimal number
- that is guaranteed to have enough precision so that if the number is read
- back in the exact same binary value is recreated. This is true for IEEE
- floating point by design, and also happens to work for all other modern
- hardware.
-
- The str() precision is chosen so that in most cases, the rounding noise
- created by various operations is suppressed, while giving plenty of
- precision for practical use.
-
-*/
-
-#define PREC_REPR 17
-#define PREC_STR 12
-
-/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated:
+/* XXX PyFloat_AsString and PyFloat_AsReprString are deprecated:
XXX they pass a char buffer without passing a length.
*/
void
PyFloat_AsString(char *buf, PyFloatObject *v)
{
- format_float(buf, 100, v, PREC_STR);
+ char *tmp = PyOS_double_to_string(v->ob_fval, 'g',
+ PyFloat_STR_PRECISION,
+ Py_DTSF_ADD_DOT_0, NULL);
+ strcpy(buf, tmp);
+ PyMem_Free(tmp);
}
void
PyFloat_AsReprString(char *buf, PyFloatObject *v)
{
- format_float(buf, 100, v, PREC_REPR);
+ char * tmp = PyOS_double_to_string(v->ob_fval, 'r', 0,
+ Py_DTSF_ADD_DOT_0, NULL);
+ strcpy(buf, tmp);
+ PyMem_Free(tmp);
}
/* ARGSUSED */
static int
float_print(PyFloatObject *v, FILE *fp, int flags)
{
- char buf[100];
- format_float(buf, sizeof(buf), v,
- (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR);
+ char *buf;
+ if (flags & Py_PRINT_RAW)
+ buf = PyOS_double_to_string(v->ob_fval,
+ 'g', PyFloat_STR_PRECISION,
+ Py_DTSF_ADD_DOT_0, NULL);
+ else
+ buf = PyOS_double_to_string(v->ob_fval,
+ 'r', 0, Py_DTSF_ADD_DOT_0, NULL);
Py_BEGIN_ALLOW_THREADS
fputs(buf, fp);
Py_END_ALLOW_THREADS
+ PyMem_Free(buf);
return 0;
}
static PyObject *
-float_repr(PyFloatObject *v)
+float_str_or_repr(PyFloatObject *v, int precision, char format_code)
{
- char buf[100];
- format_float(buf, sizeof(buf), v, PREC_REPR);
+ PyObject *result;
+ char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
+ format_code, precision,
+ Py_DTSF_ADD_DOT_0,
+ NULL);
+ if (!buf)
+ return PyErr_NoMemory();
+ result = PyString_FromString(buf);
+ PyMem_Free(buf);
+ return result;
+}
- return PyString_FromString(buf);
+static PyObject *
+float_repr(PyFloatObject *v)
+{
+ return float_str_or_repr(v, 0, 'r');
}
static PyObject *
float_str(PyFloatObject *v)
{
- char buf[100];
- format_float(buf, sizeof(buf), v, PREC_STR);
- return PyString_FromString(buf);
+ return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');
}
/* Comparison is pretty much a nightmare. When comparing float to float,
@@ -784,7 +668,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
@@ -806,7 +690,7 @@ float_classic_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
@@ -832,10 +716,20 @@ float_rem(PyObject *v, PyObject *w)
#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;
+ 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);
@@ -907,10 +801,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 "
@@ -925,17 +824,53 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
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.
@@ -945,33 +880,41 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
"cannot be raised to a fractional power");
return NULL;
}
- /* 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.
@@ -983,6 +926,8 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
return PyFloat_FromDouble(ix);
}
+#undef DOUBLE_IS_ODD_INTEGER
+
static PyObject *
float_neg(PyFloatObject *v)
{
@@ -1090,14 +1035,17 @@ float_trunc(PyObject *v)
* 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.
+ * that). Note that checking for <= LONG_MAX is unsafe: if a long
+ * has more bits of precision than a double, casting LONG_MAX to
+ * double may yield an approximation, and if that's rounded up,
+ * then, e.g., wholepart=LONG_MAX+1 would yield true from the C
+ * expression wholepart<=LONG_MAX, despite that wholepart is
+ * actually greater than LONG_MAX. However, assuming a two's complement
+ * machine with no trap representation, LONG_MIN will be a power of 2 (and
+ * hence exactly representable as a double), and LONG_MAX = -1-LONG_MIN, so
+ * the comparisons with (double)LONG_MIN below should be safe.
*/
- if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
+ if ((double)LONG_MIN <= wholepart && wholepart < -(double)LONG_MIN) {
const long aslong = (long)wholepart;
return PyInt_FromLong(aslong);
}
@@ -1111,6 +1059,202 @@ float_long(PyObject *v)
return PyLong_FromDouble(x);
}
+/* _Py_double_round: rounds a finite nonzero double to the closest multiple of
+ 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
+ ndigits <= 323). Returns a Python float, or sets a Python error and
+ returns NULL on failure (OverflowError and memory errors are possible). */
+
+#ifndef PY_NO_SHORT_FLOAT_REPR
+/* version of _Py_double_round that uses the correctly-rounded string<->double
+ conversions from Python/dtoa.c */
+
+/* FIVE_POW_LIMIT is the largest k such that 5**k is exactly representable as
+ a double. Since we're using the code in Python/dtoa.c, it should be safe
+ to assume that C doubles are IEEE 754 binary64 format. To be on the safe
+ side, we check this. */
+#if DBL_MANT_DIG == 53
+#define FIVE_POW_LIMIT 22
+#else
+#error "C doubles do not appear to be IEEE 754 binary64 format"
+#endif
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+
+ double rounded, m;
+ Py_ssize_t buflen, mybuflen=100;
+ char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
+ int decpt, sign, val, halfway_case;
+ PyObject *result = NULL;
+
+ /* The basic idea is very simple: convert and round the double to a
+ decimal string using _Py_dg_dtoa, then convert that decimal string
+ back to a double with _Py_dg_strtod. There's one minor difficulty:
+ Python 2.x expects round to do round-half-away-from-zero, while
+ _Py_dg_dtoa does round-half-to-even. So we need some way to detect
+ and correct the halfway cases.
+
+ Detection: a halfway value has the form k * 0.5 * 10**-ndigits for
+ some odd integer k. Or in other words, a rational number x is
+ exactly halfway between two multiples of 10**-ndigits if its
+ 2-valuation is exactly -ndigits-1 and its 5-valuation is at least
+ -ndigits. For ndigits >= 0 the latter condition is automatically
+ satisfied for a binary float x, since any such float has
+ nonnegative 5-valuation. For 0 > ndigits >= -22, x needs to be an
+ integral multiple of 5**-ndigits; we can check this using fmod.
+ For -22 > ndigits, there are no halfway cases: 5**23 takes 54 bits
+ to represent exactly, so any odd multiple of 0.5 * 10**n for n >=
+ 23 takes at least 54 bits of precision to represent exactly.
+
+ Correction: a simple strategy for dealing with halfway cases is to
+ (for the halfway cases only) call _Py_dg_dtoa with an argument of
+ ndigits+1 instead of ndigits (thus doing an exact conversion to
+ decimal), round the resulting string manually, and then convert
+ back using _Py_dg_strtod.
+ */
+
+ /* nans, infinities and zeros should have already been dealt
+ with by the caller (in this case, builtin_round) */
+ assert(Py_IS_FINITE(x) && x != 0.0);
+
+ /* find 2-valuation val of x */
+ m = frexp(x, &val);
+ while (m != floor(m)) {
+ m *= 2.0;
+ val--;
+ }
+
+ /* determine whether this is a halfway case */
+ if (val == -ndigits-1) {
+ if (ndigits >= 0)
+ halfway_case = 1;
+ else if (ndigits >= -FIVE_POW_LIMIT) {
+ double five_pow = 1.0;
+ int i;
+ for (i=0; i < -ndigits; i++)
+ five_pow *= 5.0;
+ halfway_case = fmod(x, five_pow) == 0.0;
+ }
+ else
+ halfway_case = 0;
+ }
+ else
+ halfway_case = 0;
+
+ /* round to a decimal string; use an extra place for halfway case */
+ buf = _Py_dg_dtoa(x, 3, ndigits+halfway_case, &decpt, &sign, &buf_end);
+ if (buf == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ buflen = buf_end - buf;
+
+ /* in halfway case, do the round-half-away-from-zero manually */
+ if (halfway_case) {
+ int i, carry;
+ /* sanity check: _Py_dg_dtoa should not have stripped
+ any zeros from the result: there should be exactly
+ ndigits+1 places following the decimal point, and
+ the last digit in the buffer should be a '5'.*/
+ assert(buflen - decpt == ndigits+1);
+ assert(buf[buflen-1] == '5');
+
+ /* increment and shift right at the same time. */
+ decpt += 1;
+ carry = 1;
+ for (i=buflen-1; i-- > 0;) {
+ carry += buf[i] - '0';
+ buf[i+1] = carry % 10 + '0';
+ carry /= 10;
+ }
+ buf[0] = carry + '0';
+ }
+
+ /* Get new buffer if shortbuf is too small. Space needed <= buf_end -
+ buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */
+ if (buflen + 8 > mybuflen) {
+ mybuflen = buflen+8;
+ mybuf = (char *)PyMem_Malloc(mybuflen);
+ if (mybuf == NULL) {
+ PyErr_NoMemory();
+ goto exit;
+ }
+ }
+ /* copy buf to mybuf, adding exponent, sign and leading 0 */
+ PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),
+ buf, decpt - (int)buflen);
+
+ /* and convert the resulting string back to a double */
+ errno = 0;
+ 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;
+}
+
+#undef FIVE_POW_LIMIT
+
+#else /* PY_NO_SHORT_FLOAT_REPR */
+
+/* fallback version, to be used when correctly rounded binary<->decimal
+ conversions aren't available */
+
+PyObject *
+_Py_double_round(double x, int ndigits) {
+ double pow1, pow2, y, z;
+ if (ndigits >= 0) {
+ if (ndigits > 22) {
+ /* pow1 and pow2 are each safe from overflow, but
+ pow1*pow2 ~= pow(10.0, ndigits) might overflow */
+ pow1 = pow(10.0, (double)(ndigits-22));
+ pow2 = 1e22;
+ }
+ else {
+ pow1 = pow(10.0, (double)ndigits);
+ pow2 = 1.0;
+ }
+ y = (x*pow1)*pow2;
+ /* if y overflows, then rounded value is exactly x */
+ if (!Py_IS_FINITE(y))
+ return PyFloat_FromDouble(x);
+ }
+ else {
+ pow1 = pow(10.0, (double)-ndigits);
+ pow2 = 1.0; /* unused; silences a gcc compiler warning */
+ y = x / pow1;
+ }
+
+ z = round(y);
+ if (fabs(y-z) == 0.5)
+ /* halfway between two integers; use round-away-from-zero */
+ z = y + copysign(0.5, y);
+
+ if (ndigits >= 0)
+ z = (z / pow2) / pow1;
+ else
+ z *= pow1;
+
+ /* if computation resulted in overflow, raise OverflowError */
+ if (!Py_IS_FINITE(z)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "overflow occurred during round");
+ return NULL;
+ }
+
+ return PyFloat_FromDouble(z);
+}
+
+#endif /* PY_NO_SHORT_FLOAT_REPR */
+
static PyObject *
float_float(PyObject *v)
{
@@ -1263,14 +1407,14 @@ Return a hexadecimal representation of a floating-point number.\n\
>>> 3.14159.hex()\n\
'0x1.921f9f01b866ep+1'");
-/* Case-insensitive string match used for nan and inf detection. t should be
- lower-case and null-terminated. Return a nonzero result if the first
- strlen(t) characters of s match t and 0 otherwise. */
+/* Case-insensitive locale-independent string match used for nan and inf
+ detection. t should be lower-case and null-terminated. Return a nonzero
+ result if the first strlen(t) characters of s match t and 0 otherwise. */
static int
case_insensitive_match(const char *s, const char *t)
{
- while(*t && tolower(*s) == *t) {
+ while(*t && Py_TOLOWER(*s) == *t) {
s++;
t++;
}
@@ -1343,7 +1487,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
********************/
/* leading whitespace and optional sign */
- while (*s && isspace(Py_CHARMASK(*s)))
+ while (Py_ISSPACE(*s))
s++;
if (*s == '-') {
s++;
@@ -1374,7 +1518,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
s_store = s;
if (*s == '0') {
s++;
- if (tolower(*s) == (int)'x')
+ if (*s == 'x' || *s == 'X')
s++;
else
s = s_store;
@@ -1404,7 +1548,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
goto insane_length_error;
/* [p <exponent>] */
- if (tolower(*s) == (int)'p') {
+ if (*s == 'p' || *s == 'P') {
s++;
exp_start = s;
if (*s == '-' || *s == '+')
@@ -1501,7 +1645,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
finished:
/* optional trailing whitespace leading to the end of the string */
- while (*s && isspace(Py_CHARMASK(*s)))
+ while (Py_ISSPACE(*s))
s++;
if (s != s_end)
goto parse_error;
@@ -2116,15 +2260,21 @@ PyFloat_Fini(void)
i++, p++) {
if (PyFloat_CheckExact(p) &&
Py_REFCNT(p) != 0) {
- char buf[100];
- PyFloat_AsString(buf, p);
- /* XXX(twouters) cast refcount to
- long until %zd is universally
- available
- */
- fprintf(stderr,
+ char *buf = PyOS_double_to_string(
+ PyFloat_AS_DOUBLE(p), 'r',
+ 0, 0, NULL);
+ if (buf) {
+ /* XXX(twouters) cast
+ refcount to long
+ until %zd is
+ universally
+ available
+ */
+ fprintf(stderr,
"# <float at %p, refcnt=%ld, val=%s>\n",
p, (long)Py_REFCNT(p), buf);
+ PyMem_Free(buf);
+ }
}
}
list = list->next;
@@ -2341,7 +2491,7 @@ _PyFloat_Pack8(double x, unsigned char *p, int le)
/* Eighth byte */
*p = flo & 0xFF;
- p += incr;
+ /* p += incr; Unneeded (for now) */
/* Done */
return 0;
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 112110cd29..a3476cfff1 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -20,12 +20,38 @@ static PyMemberDef frame_memberlist[] = {
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
{"f_globals", T_OBJECT, OFF(f_globals), RO},
{"f_lasti", T_INT, OFF(f_lasti), RO},
- {"f_exc_type", T_OBJECT, OFF(f_exc_type)},
- {"f_exc_value", T_OBJECT, OFF(f_exc_value)},
- {"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
{NULL} /* Sentinel */
};
+#define WARN_GET_SET(NAME) \
+static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \
+ if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+ return NULL; \
+ if (f->NAME) { \
+ Py_INCREF(f->NAME); \
+ return f->NAME; \
+ } \
+ Py_RETURN_NONE; \
+} \
+static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \
+ if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \
+ return -1; \
+ if (f->NAME) { \
+ Py_CLEAR(f->NAME); \
+ } \
+ if (new == Py_None) \
+ new = NULL; \
+ Py_XINCREF(new); \
+ f->NAME = new; \
+ return 0; \
+}
+
+
+WARN_GET_SET(f_exc_traceback)
+WARN_GET_SET(f_exc_type)
+WARN_GET_SET(f_exc_value)
+
+
static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
@@ -34,17 +60,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 PyInt_FromLong(lineno);
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+ return PyInt_FromLong(PyFrame_GetLineNumber(f));
}
/* Setter for f_lineno - you can set f_lineno from within a trace function in
@@ -86,7 +114,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
int in_finally[CO_MAXBLOCKS]; /* (ditto) */
int blockstack_top = 0; /* (ditto) */
unsigned char setup_op = 0; /* (ditto) */
- char *tmp;
/* f_lineno must be an integer. */
if (!PyInt_Check(p_new_lineno)) {
@@ -100,7 +127,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
if (!f->f_trace)
{
PyErr_Format(PyExc_ValueError,
- "f_lineno can only be set by a trace function");
+ "f_lineno can only be set by a"
+ " line trace function");
return -1;
}
@@ -112,22 +140,28 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
new_lineno);
return -1;
}
-
- /* Find the bytecode offset for the start of the given line, or the
- * first code-owning line after it. */
- PyString_AsStringAndSize(f->f_code->co_lnotab,
- &tmp, &lnotab_len);
- lnotab = (unsigned char *) tmp;
- addr = 0;
- line = f->f_code->co_firstlineno;
- new_lasti = -1;
- for (offset = 0; offset < lnotab_len; offset += 2) {
- addr += lnotab[offset];
- line += lnotab[offset+1];
- if (line >= new_lineno) {
- new_lasti = addr;
- new_lineno = line;
- break;
+ else if (new_lineno == f->f_code->co_firstlineno) {
+ new_lasti = 0;
+ new_lineno = f->f_code->co_firstlineno;
+ }
+ else {
+ /* Find the bytecode offset for the start of the given
+ * line, or the first code-owning line after it. */
+ char *tmp;
+ PyString_AsStringAndSize(f->f_code->co_lnotab,
+ &tmp, &lnotab_len);
+ lnotab = (unsigned char *) tmp;
+ addr = 0;
+ line = f->f_code->co_firstlineno;
+ new_lasti = -1;
+ for (offset = 0; offset < lnotab_len; offset += 2) {
+ addr += lnotab[offset];
+ line += lnotab[offset+1];
+ if (line >= new_lineno) {
+ new_lasti = addr;
+ new_lineno = line;
+ break;
+ }
}
}
@@ -328,16 +362,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;
@@ -355,6 +387,12 @@ static PyGetSetDef frame_getsetlist[] = {
(setter)frame_setlineno, NULL},
{"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL},
{"f_restricted",(getter)frame_getrestricted,NULL, NULL},
+ {"f_exc_traceback", (getter)frame_get_f_exc_traceback,
+ (setter)frame_set_f_exc_traceback, NULL},
+ {"f_exc_type", (getter)frame_get_f_exc_type,
+ (setter)frame_set_f_exc_type, NULL},
+ {"f_exc_value", (getter)frame_get_f_exc_value,
+ (setter)frame_set_f_exc_value, NULL},
{0}
};
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 7f6b123aa4..ad0f427f59 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -489,13 +489,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;
@@ -505,16 +506,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;
@@ -524,12 +526,11 @@ 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_CLOSURE(func));
- if (k != NULL)
- PyMem_DEL(k);
+ Py_XDECREF(kwtuple);
return result;
}
@@ -658,17 +659,16 @@ 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;
}
+static PyMemberDef cm_memberlist[] = {
+ {"__func__", T_OBJECT, offsetof(classmethod, cm_callable), READONLY},
+ {NULL} /* Sentinel */
+};
+
PyDoc_STRVAR(classmethod_doc,
"classmethod(function) -> method\n\
\n\
@@ -719,7 +719,7 @@ PyTypeObject PyClassMethod_Type = {
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
- 0, /* tp_members */
+ cm_memberlist, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
@@ -819,6 +819,11 @@ sm_init(PyObject *self, PyObject *args, PyObject *kwds)
return 0;
}
+static PyMemberDef sm_memberlist[] = {
+ {"__func__", T_OBJECT, offsetof(staticmethod, sm_callable), READONLY},
+ {NULL} /* Sentinel */
+};
+
PyDoc_STRVAR(staticmethod_doc,
"staticmethod(function) -> method\n\
\n\
@@ -866,7 +871,7 @@ PyTypeObject PyStaticMethod_Type = {
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
- 0, /* tp_members */
+ sm_memberlist, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 029854fad2..7d70bfb6e3 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -3,6 +3,7 @@
#include "Python.h"
#include <ctype.h>
+#include <float.h>
static PyObject *int_int(PyIntObject *v);
@@ -78,7 +79,8 @@ fill_free_list(void)
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
-int quick_int_allocs, quick_neg_int_allocs;
+Py_ssize_t quick_int_allocs;
+Py_ssize_t quick_neg_int_allocs;
#endif
PyObject *
@@ -176,7 +178,7 @@ PyInt_AsLong(register PyObject *op)
{
Py_DECREF(io);
PyErr_SetString(PyExc_TypeError,
- "nb_int should return int object");
+ "__int__ method should return an integer");
return -1;
}
}
@@ -234,7 +236,7 @@ PyInt_AsSsize_t(register PyObject *op)
{
Py_DECREF(io);
PyErr_SetString(PyExc_TypeError,
- "nb_int should return int object");
+ "__int__ method should return an integer");
return -1;
}
}
@@ -279,7 +281,7 @@ PyInt_AsUnsignedLongMask(register PyObject *op)
{
Py_DECREF(io);
PyErr_SetString(PyExc_TypeError,
- "nb_int should return int object");
+ "__int__ method should return an integer");
return (unsigned long)-1;
}
}
@@ -324,7 +326,7 @@ PyInt_AsUnsignedLongLongMask(register PyObject *op)
{
Py_DECREF(io);
PyErr_SetString(PyExc_TypeError,
- "nb_int should return int object");
+ "__int__ method should return an integer");
return (unsigned PY_LONG_LONG)-1;
}
}
@@ -434,12 +436,6 @@ int_print(PyIntObject *v, FILE *fp, int flags)
return 0;
}
-static PyObject *
-int_repr(PyIntObject *v)
-{
- return _PyInt_Format(v, 10, 0);
-}
-
static int
int_compare(PyIntObject *v, PyIntObject *w)
{
@@ -649,16 +645,35 @@ int_classic_div(PyIntObject *x, PyIntObject *y)
}
static PyObject *
-int_true_divide(PyObject *v, PyObject *w)
+int_true_divide(PyIntObject *x, PyIntObject *y)
{
+ long xi, yi;
/* If they aren't both ints, give someone else a chance. In
particular, this lets int/long get handled by longs, which
underflows to 0 gracefully if the long is too big to convert
to float. */
- if (PyInt_Check(v) && PyInt_Check(w))
- return PyFloat_Type.tp_as_number->nb_true_divide(v, w);
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ CONVERT_TO_LONG(x, xi);
+ CONVERT_TO_LONG(y, yi);
+ if (yi == 0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "division by zero");
+ return NULL;
+ }
+ if (xi == 0)
+ return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0);
+
+#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
+#if DBL_MANT_DIG < WIDTH_OF_ULONG
+ if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG ||
+ (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG)
+ /* Large x or y. Use long integer arithmetic. */
+ return PyLong_Type.tp_as_number->nb_true_divide(
+ (PyObject *)x, (PyObject *)y);
+ else
+#endif
+ /* Both ints can be exactly represented as doubles. Do a
+ floating-point division. */
+ return PyFloat_FromDouble((double)xi / (double)yi);
}
static PyObject *
@@ -939,12 +954,78 @@ int_long(PyIntObject *v)
return PyLong_FromLong((v -> ob_ival));
}
+static const unsigned char BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_ulong(unsigned long d)
+{
+ int d_bits = 0;
+ while (d >= 32) {
+ d_bits += 6;
+ d >>= 6;
+ }
+ d_bits += (int)BitLengthTable[d];
+ return d_bits;
+}
+
+#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG
+/* Every Python int can be exactly represented as a float. */
+
static PyObject *
int_float(PyIntObject *v)
{
return PyFloat_FromDouble((double)(v -> ob_ival));
}
+#else
+/* Here not all Python ints are exactly representable as floats, so we may
+ have to round. We do this manually, since the C standards don't specify
+ whether converting an integer to a float rounds up or down */
+
+static PyObject *
+int_float(PyIntObject *v)
+{
+ unsigned long abs_ival, lsb;
+ int round_up;
+
+ if (v->ob_ival < 0)
+ abs_ival = 0U-(unsigned long)v->ob_ival;
+ else
+ abs_ival = (unsigned long)v->ob_ival;
+ if (abs_ival < (1L << DBL_MANT_DIG))
+ /* small integer; no need to round */
+ return PyFloat_FromDouble((double)v->ob_ival);
+
+ /* Round abs_ival to MANT_DIG significant bits, using the
+ round-half-to-even rule. abs_ival & lsb picks out the 'rounding'
+ bit: the first bit after the most significant MANT_DIG bits of
+ abs_ival. We round up if this bit is set, provided that either:
+
+ (1) abs_ival isn't exactly halfway between two floats, in which
+ case at least one of the bits following the rounding bit must be
+ set; i.e., abs_ival & lsb-1 != 0, or:
+
+ (2) the resulting rounded value has least significant bit 0; or
+ in other words the bit above the rounding bit is set (this is the
+ 'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0
+
+ The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */
+
+ lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1);
+ round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1));
+ abs_ival &= -2*lsb;
+ if (round_up)
+ abs_ival += 2*lsb;
+ return PyFloat_FromDouble(v->ob_ival < 0 ?
+ -(double)abs_ival :
+ (double)abs_ival);
+}
+
+#endif
+
static PyObject *
int_oct(PyIntObject *v)
{
@@ -1048,8 +1129,33 @@ int_getnewargs(PyIntObject *v)
}
static PyObject *
-int_getN(PyIntObject *v, void *context) {
- return PyInt_FromLong((Py_intptr_t)context);
+int_get0(PyIntObject *v, void *context) {
+ return PyInt_FromLong(0L);
+}
+
+static PyObject *
+int_get1(PyIntObject *v, void *context) {
+ return PyInt_FromLong(1L);
+}
+
+/* Convert an integer to a decimal string. On many platforms, this
+ will be significantly faster than the general arbitrary-base
+ conversion machinery in _PyInt_Format, thanks to optimization
+ opportunities offered by division by a compile-time constant. */
+static PyObject *
+int_to_decimal_string(PyIntObject *v) {
+ char buf[sizeof(long)*CHAR_BIT/3+6], *p, *bufend;
+ long n = v->ob_ival;
+ unsigned long absn;
+ p = bufend = buf + sizeof(buf);
+ absn = n < 0 ? 0UL - n : n;
+ do {
+ *--p = '0' + (char)(absn % 10);
+ absn /= 10;
+ } while (absn);
+ if (n < 0)
+ *--p = '-';
+ return PyString_FromStringAndSize(p, bufend - p);
}
/* Convert an integer to the given base. Returns a string.
@@ -1076,6 +1182,10 @@ _PyInt_Format(PyIntObject *v, int base, int newstyle)
assert(base >= 2 && base <= 36);
+ /* Special case base 10, for speed */
+ if (base == 10)
+ return int_to_decimal_string(v);
+
do {
/* I'd use i_divmod, except it doesn't produce the results
I want when n is negative. So just duplicate the salient
@@ -1108,7 +1218,7 @@ _PyInt_Format(PyIntObject *v, int base, int newstyle)
*--p = 'x';
*--p = '0';
}
- else if (base != 10) {
+ else {
*--p = '#';
*--p = '0' + base%10;
if (base > 10)
@@ -1150,6 +1260,29 @@ int__format__(PyObject *self, PyObject *args)
return NULL;
}
+static PyObject *
+int_bit_length(PyIntObject *v)
+{
+ unsigned long n;
+
+ if (v->ob_ival < 0)
+ /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */
+ n = 0U-(unsigned long)v->ob_ival;
+ else
+ n = (unsigned long)v->ob_ival;
+
+ return PyInt_FromLong(bits_in_ulong(n));
+}
+
+PyDoc_STRVAR(int_bit_length_doc,
+"int.bit_length() -> int\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37)\n\
+'0b100101'\n\
+>>> (37).bit_length()\n\
+6");
+
#if 0
static PyObject *
int_is_finite(PyObject *v)
@@ -1161,6 +1294,8 @@ int_is_finite(PyObject *v)
static PyMethodDef int_methods[] = {
{"conjugate", (PyCFunction)int_int, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
+ {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS,
+ int_bit_length_doc},
#if 0
{"is_finite", (PyCFunction)int_is_finite, METH_NOARGS,
"Returns always True."},
@@ -1178,17 +1313,17 @@ static PyGetSetDef int_getset[] = {
"the real part of a complex number",
NULL},
{"imag",
- (getter)int_getN, (setter)NULL,
+ (getter)int_get0, (setter)NULL,
"the imaginary part of a complex number",
- (void*)0},
+ NULL},
{"numerator",
(getter)int_int, (setter)NULL,
"the numerator of a rational number in lowest terms",
NULL},
{"denominator",
- (getter)int_getN, (setter)NULL,
+ (getter)int_get1, (setter)NULL,
"the denominator of a rational number in lowest terms",
- (void*)1},
+ NULL},
{NULL} /* Sentinel */
};
@@ -1239,7 +1374,7 @@ static PyNumberMethods int_as_number = {
0, /*nb_inplace_xor*/
0, /*nb_inplace_or*/
(binaryfunc)int_div, /* nb_floor_divide */
- int_true_divide, /* nb_true_divide */
+ (binaryfunc)int_true_divide, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
(unaryfunc)int_int, /* nb_index */
@@ -1255,13 +1390,13 @@ PyTypeObject PyInt_Type = {
0, /* tp_getattr */
0, /* tp_setattr */
(cmpfunc)int_compare, /* tp_compare */
- (reprfunc)int_repr, /* tp_repr */
+ (reprfunc)int_to_decimal_string, /* tp_repr */
&int_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)int_hash, /* tp_hash */
0, /* tp_call */
- (reprfunc)int_repr, /* tp_str */
+ (reprfunc)int_to_decimal_string, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
diff --git a/Objects/listobject.c b/Objects/listobject.c
index a5bacf3a52..08f7880286 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -11,7 +11,7 @@
/* Ensure ob_item has room for at least newsize elements, and set
* ob_size to newsize. If newsize > ob_size on entry, the content
* of the new slots at exit is undefined heap trash; it's the caller's
- * responsiblity to overwrite them with sane values.
+ * responsibility to overwrite them with sane values.
* The number of allocated elements may grow, shrink, or stay the same.
* Failure is impossible if newsize <= self.allocated on entry, although
* that partly relies on an assumption that the system realloc() never
@@ -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 = PyString_FromString(
"list index out of range");
+ if (indexerr == NULL)
+ return NULL;
+ }
PyErr_SetObject(PyExc_IndexError, indexerr);
return NULL;
}
@@ -447,9 +450,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 = PyString_FromString(
"list index out of range");
+ if (indexerr == NULL)
+ return NULL;
+ }
PyErr_SetObject(PyExc_IndexError, indexerr);
return NULL;
}
@@ -2270,7 +2276,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,
@@ -2293,7 +2300,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 = PyString_FromString("%r is not in list");
+ if (err_format == NULL)
+ return NULL;
+ }
+ format_tuple = PyTuple_Pack(1, v);
+ if (format_tuple == NULL)
+ return NULL;
+ err_string = PyString_Format(err_format, format_tuple);
+ Py_DECREF(format_tuple);
+ if (err_string == NULL)
+ return NULL;
+ PyErr_SetObject(PyExc_ValueError, err_string);
+ Py_DECREF(err_string);
return NULL;
}
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.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index e6edb4f586..cd86a1f9fe 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -1,13 +1,14 @@
-
-
/* Long (arbitrary precision) integer object implementation */
/* XXX The functional organization of this file is terrible */
#include "Python.h"
#include "longintrepr.h"
+#include "structseq.h"
+#include <float.h>
#include <ctype.h>
+#include <stddef.h>
/* For long multiplication, use the O(N**2) school algorithm unless
* both operands contain more than KARATSUBA_CUTOFF digits (this
@@ -30,17 +31,13 @@
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))
-/* Forward */
-static PyLongObject *long_normalize(PyLongObject *);
-static PyLongObject *mul1(PyLongObject *, wdigit);
-static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);
-static PyLongObject *divrem1(PyLongObject *, digit, digit *);
-
-#define SIGCHECK(PyTryBlock) \
- if (--_Py_Ticker < 0) { \
- _Py_Ticker = _Py_CheckInterval; \
- if (PyErr_CheckSignals()) PyTryBlock \
- }
+#define SIGCHECK(PyTryBlock) \
+ do { \
+ if (--_Py_Ticker < 0) { \
+ _Py_Ticker = _Py_CheckInterval; \
+ 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
@@ -62,16 +59,20 @@ long_normalize(register PyLongObject *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))
+
PyLongObject *
_PyLong_New(Py_ssize_t size)
{
- if (size > PY_SSIZE_T_MAX) {
- PyErr_NoMemory();
+ if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many digits in integer");
return NULL;
}
/* coverity[ampersand_in_size] */
- /* XXX(nnorwitz): This can overflow --
- PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect overflow */
+ /* XXX(nnorwitz): PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect
+ overflow */
return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
}
@@ -176,12 +177,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) {
@@ -197,8 +198,8 @@ PyLong_FromDouble(double dval)
return NULL;
frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
for (i = ndig; --i >= 0; ) {
- long bits = (long)frac;
- v->ob_digit[i] = (digit) bits;
+ digit bits = (digit)frac;
+ v->ob_digit[i] = bits;
frac = frac - (double)bits;
frac = ldexp(frac, PyLong_SHIFT);
}
@@ -219,53 +220,123 @@ PyLong_FromDouble(double dval)
#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. */
+/* Get a C 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.
+*/
long
-PyLong_AsLong(PyObject *vv)
+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 */
- if (vv == NULL || !PyLong_Check(vv)) {
- if (vv != NULL && PyInt_Check(vv))
- return PyInt_AsLong(vv);
+ *overflow = 0;
+ if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
- v = (PyLongObject *)vv;
- i = v->ob_size;
- 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;
+
+ if(PyInt_Check(vv))
+ return PyInt_AsLong(vv);
+
+ 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(PyInt_Check(vv)) {
+ res = PyInt_AsLong(vv);
+ goto exit;
+ }
+ if (!PyLong_Check(vv)) {
+ Py_DECREF(vv);
+ PyErr_SetString(PyExc_TypeError,
+ "nb_int should return int object");
+ return -1;
+ }
}
- /* Haven't lost any bits, but casting to long requires extra care
- * (see comment above).
- */
- if (x <= (unsigned long)LONG_MAX) {
- return (long)x * sign;
+
+ 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 */
+ }
}
- else if (sign < 0 && x == PY_ABS_LONG_MIN) {
- return LONG_MIN;
+ exit:
+ if (do_decref) {
+ Py_DECREF(vv);
}
- /* else overflow */
+ return res;
+}
- overflow:
- PyErr_SetString(PyExc_OverflowError,
- "long int too large to convert to int");
- return -1;
+/* Get a C long int from a long int object.
+ Returns -1 and sets an error condition if overflow occurs. */
+
+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;
}
/* Get a Py_ssize_t from a long int object.
@@ -292,7 +363,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;
}
@@ -307,7 +378,7 @@ PyLong_AsSsize_t(PyObject *vv) {
}
/* else overflow */
- overflow:
+ overflow:
PyErr_SetString(PyExc_OverflowError,
"long int too large to convert to int");
return -1;
@@ -328,7 +399,8 @@ PyLong_AsUnsignedLong(PyObject *vv)
long val = PyInt_AsLong(vv);
if (val < 0) {
PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
+ "can't convert negative value "
+ "to unsigned long");
return (unsigned long) -1;
}
return val;
@@ -341,15 +413,15 @@ PyLong_AsUnsignedLong(PyObject *vv)
x = 0;
if (i < 0) {
PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned long");
+ "can't convert negative value to unsigned long");
return (unsigned long) -1;
}
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,
- "long int too large to convert");
+ "long int too large to convert");
return (unsigned long) -1;
}
}
@@ -382,7 +454,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;
}
@@ -424,7 +496,7 @@ _PyLong_NumBits(PyObject *vv)
}
return result;
-Overflow:
+ Overflow:
PyErr_SetString(PyExc_OverflowError, "long has too many bits "
"to express in a platform size_t");
return (size_t)-1;
@@ -434,13 +506,13 @@ 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 */
- size_t ndigits; /* number of Python long digits */
+ Py_ssize_t ndigits; /* number of Python long digits */
PyLongObject* v; /* result */
- int idigit = 0; /* next free index in v->ob_digit */
+ Py_ssize_t idigit = 0; /* next free index in v->ob_digit */
if (n == 0)
return PyLong_FromLong(0L);
@@ -460,7 +532,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
is_signed = *pendbyte >= 0x80;
/* Compute numsignificantbytes. This consists of finding the most
- significant byte. Leading 0 bytes are insignficant if the number
+ significant byte. Leading 0 bytes are insignificant if the number
is positive, and leading 0xff bytes if negative. */
{
size_t i;
@@ -483,12 +555,16 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
}
/* 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. */
+ 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;
- if (ndigits > (size_t)INT_MAX)
- return PyErr_NoMemory();
- v = _PyLong_New((int)ndigits);
+ v = _PyLong_New(ndigits);
if (v == NULL)
return NULL;
@@ -517,7 +593,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
accumbits += 8;
if (accumbits >= PyLong_SHIFT) {
/* There's enough to fill a Python digit. */
- assert(idigit < (int)ndigits);
+ assert(idigit < ndigits);
v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);
++idigit;
accum >>= PyLong_SHIFT;
@@ -527,7 +603,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
}
assert(accumbits < PyLong_SHIFT);
if (accumbits) {
- assert(idigit < (int)ndigits);
+ assert(idigit < ndigits);
v->ob_digit[idigit] = (digit)accum;
++idigit;
}
@@ -543,9 +619,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 */
@@ -557,8 +633,8 @@ _PyLong_AsByteArray(PyLongObject* v,
if (Py_SIZE(v) < 0) {
ndigits = -(Py_SIZE(v));
if (!is_signed) {
- PyErr_SetString(PyExc_TypeError,
- "can't convert negative long to unsigned");
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative long to unsigned");
return -1;
}
do_twos_comp = 1;
@@ -604,8 +680,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++;
@@ -665,97 +740,12 @@ _PyLong_AsByteArray(PyLongObject* v,
return 0;
-Overflow:
+ Overflow:
PyErr_SetString(PyExc_OverflowError, "long too big to convert");
return -1;
}
-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. */
-
-double
-PyLong_AsDouble(PyObject *vv)
-{
- int e = -1;
- double x;
-
- if (vv == NULL || !PyLong_Check(vv)) {
- PyErr_BadInternalCall();
- return -1;
- }
- x = _PyLong_AsScaledDouble(vv, &e);
- if (x == -1.0 && PyErr_Occurred())
- return -1.0;
- /* 'e' initialized to -1 to silence gcc-4.0.x, but it should be
- set correctly after a successful _PyLong_AsScaledDouble() call */
- assert(e >= 0);
- if (e > INT_MAX / PyLong_SHIFT)
- goto overflow;
- errno = 0;
- x = ldexp(x, e * PyLong_SHIFT);
- if (Py_OVERFLOWED(x))
- goto overflow;
- return x;
-
-overflow:
- PyErr_SetString(PyExc_OverflowError,
- "long int too large to convert to float");
- return -1.0;
-}
-
/* Create a new long (or int) object from a C pointer */
PyObject *
@@ -830,6 +820,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. */
@@ -908,9 +899,8 @@ PyLong_FromSsize_t(Py_ssize_t ival)
{
Py_ssize_t bytes = ival;
int one = 1;
- return _PyLong_FromByteArray(
- (unsigned char *)&bytes,
- SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
+ return _PyLong_FromByteArray((unsigned char *)&bytes,
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
}
/* Create a new long int object from a C size_t. */
@@ -920,9 +910,8 @@ PyLong_FromSize_t(size_t ival)
{
size_t bytes = ival;
int one = 1;
- return _PyLong_FromByteArray(
- (unsigned char *)&bytes,
- SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+ return _PyLong_FromByteArray((unsigned char *)&bytes,
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
}
/* Get a C PY_LONG_LONG int from a long int object.
@@ -967,9 +956,8 @@ PyLong_AsLongLong(PyObject *vv)
return -1;
}
- 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)
@@ -993,9 +981,8 @@ PyLong_AsUnsignedLongLong(PyObject *vv)
return (unsigned PY_LONG_LONG)-1;
}
- 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)
@@ -1028,10 +1015,113 @@ 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;
}
+
+/* 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 (PyInt_Check(vv))
+ return PyInt_AsLong(vv);
+
+ 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(PyInt_Check(vv)) {
+ res = PyInt_AsLong(vv);
+ goto exit;
+ }
+ 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;
+}
+
#undef IS_LITTLE_ENDIAN
#endif /* HAVE_LONG_LONG */
@@ -1063,11 +1153,33 @@ convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
return 1;
}
-#define CONVERT_BINOP(v, w, a, b) \
- if (!convert_binop(v, w, a, b)) { \
- Py_INCREF(Py_NotImplemented); \
- return Py_NotImplemented; \
+#define CONVERT_BINOP(v, w, a, b) \
+ do { \
+ if (!convert_binop(v, w, a, b)) { \
+ 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. */
+
+static const unsigned char BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_digit(digit d)
+{
+ 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]
* is modified in place, by adding y to it. Carries are propagated as far as
@@ -1121,33 +1233,41 @@ v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
return borrow;
}
-/* Multiply by a single digit, ignoring the sign. */
-
-static PyLongObject *
-mul1(PyLongObject *a, wdigit n)
+/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put
+ * result in z[0:m], and return the d bits shifted out of the top.
+ */
+static digit
+v_lshift(digit *z, digit *a, Py_ssize_t m, int d)
{
- return muladd1(a, n, (digit)0);
-}
+ Py_ssize_t i;
+ digit carry = 0;
-/* Multiply by a single digit and add a single digit, ignoring the sign. */
+ 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;
+}
-static PyLongObject *
-muladd1(PyLongObject *a, wdigit n, wdigit extra)
+/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put
+ * result in z[0:m], and return the d bits shifted out of the bottom.
+ */
+static digit
+v_rshift(digit *z, digit *a, Py_ssize_t m, int d)
{
- Py_ssize_t size_a = ABS(Py_SIZE(a));
- PyLongObject *z = _PyLong_New(size_a+1);
- twodigits carry = extra;
Py_ssize_t i;
+ digit carry = 0;
+ digit mask = ((digit)1 << d) - 1U;
- if (z == NULL)
- return NULL;
- for (i = 0; i < size_a; ++i) {
- carry += (twodigits)a->ob_digit[i] * n;
- z->ob_digit[i] = (digit) (carry & PyLong_MASK);
- carry >>= PyLong_SHIFT;
+ 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);
}
- z->ob_digit[i] = (digit) carry;
- return long_normalize(z);
+ return carry;
}
/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
@@ -1166,7 +1286,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;
}
@@ -1191,6 +1311,123 @@ 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, int addL)
+{
+ PyLongObject *scratch, *a;
+ PyObject *str;
+ Py_ssize_t size, strlen, size_a, i, j;
+ digit *pout, *pin, rem, tenpow;
+ char *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 = (addL != 0) + negative +
+ 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
+ tenpow = 10;
+ rem = pout[size-1];
+ while (rem >= tenpow) {
+ tenpow *= 10;
+ strlen++;
+ }
+ str = PyString_FromStringAndSize(NULL, strlen);
+ if (str == NULL) {
+ Py_DECREF(scratch);
+ return NULL;
+ }
+
+ /* fill the string right-to-left */
+ p = PyString_AS_STRING(str) + strlen;
+ *p = '\0';
+ if (addL)
+ *--p = 'L';
+ /* 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 == PyString_AS_STRING(str));
+ Py_DECREF(scratch);
+ return (PyObject *)str;
+}
+
/* Convert the long to a string object with given base,
appending a base prefix of 0[box] if base is 2, 8 or 16.
Add a trailing "L" if addL is non-zero.
@@ -1207,6 +1444,9 @@ _PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
int bits;
char sign = '\0';
+ if (base == 10)
+ return long_to_decimal_string((PyObject *)a, addL);
+
if (a == NULL || !PyLong_Check(a)) {
PyErr_BadInternalCall();
return NULL;
@@ -1263,8 +1503,7 @@ _PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
*--p = cdigit;
accumbits -= basebits;
accum >>= basebits;
- } while (i < size_a-1 ? accumbits >= basebits :
- accum > 0);
+ } while (i < size_a-1 ? accumbits >= basebits : accum > 0);
}
}
else {
@@ -1278,7 +1517,7 @@ _PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
digit powbase = base; /* powbase == base ** power */
int power = 1;
for (;;) {
- unsigned long newpow = powbase * (unsigned long)base;
+ twodigits newpow = powbase * (twodigits)base;
if (newpow >> PyLong_SHIFT)
/* doesn't fit in a digit */
break;
@@ -1297,15 +1536,15 @@ _PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
do {
int ntostore = power;
digit rem = inplace_divrem1(scratch->ob_digit,
- pin, size, powbase);
+ 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;
- })
+ Py_DECREF(scratch);
+ Py_DECREF(str);
+ return NULL;
+ });
/* Break rem into digits. */
assert(ntostore > 0);
@@ -1519,14 +1758,15 @@ case number of Python digits needed to hold it is the smallest integer n s.t.
PyLong_BASE**n >= B**N [taking logs to base PyLong_BASE]
n >= log(B**N)/log(PyLong_BASE) = N * log(B)/log(PyLong_BASE)
-The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so we can compute
-this quickly. A Python long with that much space is reserved near the start,
-and the result is computed into it.
+The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so
+we can compute this quickly. A Python long with that much space is reserved
+near the start, and the result is computed into it.
The input string is actually treated as being in base base**i (i.e., i digits
are processed at a time), where two more static arrays hold:
- convwidth_base[base] = the largest integer i such that base**i <= PyLong_BASE
+ convwidth_base[base] = the largest integer i such that
+ base**i <= PyLong_BASE
convmultmax_base[base] = base ** convwidth_base[base]
The first of these is the largest i such that i consecutive input digits
@@ -1550,33 +1790,34 @@ where `N` is the number of input digits in base `B`. This is computed via
size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
below. Two numeric concerns are how much space this can waste, and whether
-the computed result can be too small. To be concrete, assume PyLong_BASE = 2**15,
-which is the default (and it's unlikely anyone changes that).
+the computed result can be too small. To be concrete, assume PyLong_BASE =
+2**15, which is the default (and it's unlikely anyone changes that).
-Waste isn't a problem: provided the first input digit isn't 0, the difference
+Waste isn't a problem: provided the first input digit isn't 0, the difference
between the worst-case input with N digits and the smallest input with N
-digits is about a factor of B, but B is small compared to PyLong_BASE so at most
-one allocated Python digit can remain unused on that count. If
-N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating that
-and adding 1 returns a result 1 larger than necessary. However, that can't
-happen: whenever B is a power of 2, long_from_binary_base() is called
-instead, and it's impossible for B**i to be an integer power of 2**15 when
-B is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be
+digits is about a factor of B, but B is small compared to PyLong_BASE so at
+most one allocated Python digit can remain unused on that count. If
+N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating
+that and adding 1 returns a result 1 larger than necessary. However, that
+can't happen: whenever B is a power of 2, long_from_binary_base() is called
+instead, and it's impossible for B**i to be an integer power of 2**15 when B
+is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be
an exact integer when B is not a power of 2, since B**i has a prime factor
other than 2 in that case, but (2**15)**j's only prime factor is 2).
-The computed result can be too small if the true value of N*log(B)/log(PyLong_BASE)
-is a little bit larger than an exact integer, but due to roundoff errors (in
-computing log(B), log(PyLong_BASE), their quotient, and/or multiplying that by N)
-yields a numeric result a little less than that integer. Unfortunately, "how
-close can a transcendental function get to an integer over some range?"
-questions are generally theoretically intractable. Computer analysis via
-continued fractions is practical: expand log(B)/log(PyLong_BASE) via continued
-fractions, giving a sequence i/j of "the best" rational approximations. Then
-j*log(B)/log(PyLong_BASE) is approximately equal to (the integer) i. This shows that
-we can get very close to being in trouble, but very rarely. For example,
-76573 is a denominator in one of the continued-fraction approximations to
-log(10)/log(2**15), and indeed:
+The computed result can be too small if the true value of
+N*log(B)/log(PyLong_BASE) is a little bit larger than an exact integer, but
+due to roundoff errors (in computing log(B), log(PyLong_BASE), their quotient,
+and/or multiplying that by N) yields a numeric result a little less than that
+integer. Unfortunately, "how close can a transcendental function get to an
+integer over some range?" questions are generally theoretically intractable.
+Computer analysis via continued fractions is practical: expand
+log(B)/log(PyLong_BASE) via continued fractions, giving a sequence i/j of "the
+best" rational approximations. Then j*log(B)/log(PyLong_BASE) is
+approximately equal to (the integer) i. This shows that we can get very close
+to being in trouble, but very rarely. For example, 76573 is a denominator in
+one of the continued-fraction approximations to log(10)/log(2**15), and
+indeed:
>>> log(10)/log(2**15)*76573
16958.000000654003
@@ -1607,8 +1848,8 @@ digit beyond the first.
twodigits convmax = base;
int i = 1;
- log_base_PyLong_BASE[base] = log((double)base) /
- log((double)PyLong_BASE);
+ log_base_PyLong_BASE[base] = (log((double)base) /
+ log((double)PyLong_BASE));
for (;;) {
twodigits next = convmax * base;
if (next > PyLong_BASE)
@@ -1652,7 +1893,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 +
- _PyLong_DigitValue[Py_CHARMASK(*str)]);
+ _PyLong_DigitValue[Py_CHARMASK(*str)]);
assert(c < PyLong_BASE);
}
@@ -1717,7 +1958,7 @@ digit beyond the first.
*pend = str;
return (PyObject *) z;
- onError:
+ onError:
Py_XDECREF(z);
slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
strobj = PyString_FromStringAndSize(orig_str, slen);
@@ -1758,8 +1999,6 @@ PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
static PyLongObject *x_divrem
(PyLongObject *, PyLongObject *, PyLongObject **);
static PyObject *long_long(PyObject *v);
-static int long_divrem(PyLongObject *, PyLongObject *,
- PyLongObject **, PyLongObject **);
/* Long division with remainder, top-level routine */
@@ -1814,104 +2053,278 @@ long_divrem(PyLongObject *a, PyLongObject *b,
return 0;
}
-/* Unsigned long division with remainder -- the algorithm */
+/* Unsigned long division with remainder -- the algorithm. The arguments v1
+ and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */
static PyLongObject *
x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
{
- Py_ssize_t size_v = ABS(Py_SIZE(v1)), size_w = ABS(Py_SIZE(w1));
- digit d = (digit) ((twodigits)PyLong_BASE / (w1->ob_digit[size_w-1] + 1));
- PyLongObject *v = mul1(v1, d);
- PyLongObject *w = mul1(w1, d);
- PyLongObject *a;
- Py_ssize_t j, k;
-
- if (v == NULL || w == NULL) {
- Py_XDECREF(v);
- Py_XDECREF(w);
+ 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;
}
- assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
- assert(Py_REFCNT(v) == 1); /* Since v will be used as accumulator! */
- assert(size_w == ABS(Py_SIZE(w))); /* That's how d was calculated */
+ /* 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++;
+ }
- size_v = ABS(Py_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;
- a = _PyLong_New(k + 1);
-
- for (j = size_v; a != NULL && k >= 0; --j, --k) {
- digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
- twodigits q;
- stwodigits carry = 0;
- Py_ssize_t i;
+ 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);
- a = NULL;
- break;
- })
- if (vj == w->ob_digit[size_w-1])
- q = PyLong_MASK;
- else
- q = (((twodigits)vj << PyLong_SHIFT) + v->ob_digit[j-1]) /
- w->ob_digit[size_w-1];
-
- while (w->ob_digit[size_w-2]*q >
- ((
- ((twodigits)vj << PyLong_SHIFT)
- + v->ob_digit[j-1]
- - q*w->ob_digit[size_w-1]
- ) << PyLong_SHIFT)
- + v->ob_digit[j-2])
+ 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;
-
- for (i = 0; i < size_w && i+k < size_v; ++i) {
- twodigits z = w->ob_digit[i] * q;
- digit zz = (digit) (z >> PyLong_SHIFT);
- carry += v->ob_digit[i+k] - z
- + ((twodigits)zz << PyLong_SHIFT);
- v->ob_digit[i+k] = (digit)(carry & PyLong_MASK);
- carry = Py_ARITHMETIC_RIGHT_SHIFT(BASE_TWODIGITS_TYPE,
- carry, PyLong_SHIFT);
- carry -= zz;
+ r += wm1;
+ if (r >= PyLong_BASE)
+ break;
}
-
- if (i+k < size_v) {
- carry += v->ob_digit[i+k];
- v->ob_digit[i+k] = 0;
+ 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);
}
- if (carry == 0)
- a->ob_digit[k] = (digit) q;
- else {
- assert(carry == -1);
- a->ob_digit[k] = (digit) q-1;
+ /* 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+k < size_v; ++i) {
- carry += v->ob_digit[i+k] + w->ob_digit[i];
- v->ob_digit[i+k] = (digit)(carry & PyLong_MASK);
- carry = Py_ARITHMETIC_RIGHT_SHIFT(
- BASE_TWODIGITS_TYPE,
- carry, PyLong_SHIFT);
+ for (i = 0; i < size_w; ++i) {
+ carry += vk[i] + w0[i];
+ vk[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
}
+ --q;
}
- } /* for j, k */
- if (a == NULL)
- *prem = NULL;
- else {
- a = long_normalize(a);
- *prem = divrem1(v, d, &d);
- /* d receives the (unused) remainder */
- if (*prem == NULL) {
- Py_DECREF(a);
- a = NULL;
- }
+ /* 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);
- Py_DECREF(w);
- return a;
+
+ *prem = long_normalize(w);
+ 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,
+ (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;
+}
+
+/* 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, (int)exponent);
}
/* Methods */
@@ -1940,10 +2353,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));
@@ -1952,7 +2362,7 @@ long_compare(PyLongObject *a, PyLongObject *b)
if (i < 0)
sign = 0;
else {
- sign = (int)a->ob_digit[i] - (int)b->ob_digit[i];
+ sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];
if (Py_SIZE(a) < 0)
sign = -sign;
}
@@ -1977,14 +2387,12 @@ long_hash(PyLongObject *v)
sign = -1;
i = -(i);
}
-#define LONG_BIT_PyLong_SHIFT (8*sizeof(long) - PyLong_SHIFT)
/* 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 << PyLong_SHIFT) & ~PyLong_MASK) |
- ((x >> LONG_BIT_PyLong_SHIFT) & PyLong_MASK);
+ 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
@@ -1992,11 +2400,10 @@ long_hash(PyLongObject *v)
if (x < v->ob_digit[i])
x++;
}
-#undef LONG_BIT_PyLong_SHIFT
x = x * sign;
- if (x == -1)
- x = -2;
- return x;
+ if (x == (unsigned long)-1)
+ x = (unsigned long)-2;
+ return (long)x;
}
@@ -2014,8 +2421,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)
@@ -2050,8 +2457,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: */
@@ -2173,9 +2580,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);
@@ -2211,9 +2618,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;
@@ -2237,7 +2644,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;
@@ -2426,7 +2836,7 @@ k_mul(PyLongObject *a, PyLongObject *b)
return long_normalize(ret);
- fail:
+ fail:
Py_XDECREF(ret);
Py_XDECREF(ah);
Py_XDECREF(al);
@@ -2485,7 +2895,7 @@ ah*bh and al*bl too.
* of slices, each with a->ob_size digits, and multiply the slices by a,
* one at a time. This gives k_mul balanced inputs to work with, and is
* also cache-friendly (we compute one double-width slice of the result
- * at a time, then move on, never bactracking except for the helpful
+ * at a time, then move on, never backtracking except for the helpful
* single-width slice overlap between successive partial sums).
*/
static PyLongObject *
@@ -2536,7 +2946,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;
@@ -2655,50 +3065,271 @@ long_classic_div(PyObject *v, PyObject *w)
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 *v, PyObject *w)
{
- PyLongObject *a, *b;
- 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;
CONVERT_BINOP(v, w, &a, &b);
- ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
- bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
- failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred();
- Py_DECREF(a);
- Py_DECREF(b);
- 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);
- if (bd == 0.0) {
- PyErr_SetString(PyExc_ZeroDivisionError,
- "long division or modulo by zero");
- return NULL;
- }
+ /*
+ 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.
- /* 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)
+ 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 (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 < 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;
- return PyFloat_FromDouble(ad);
+ result = ldexp(dx, (int)shift);
+
+ success:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return PyFloat_FromDouble(negate ? -result : result);
-overflow:
+ underflow_or_zero:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return PyFloat_FromDouble(negate ? -0.0 : 0.0);
+
+ overflow:
PyErr_SetString(PyExc_OverflowError,
- "long/long too large for a float");
+ "integer division result too large for a float");
+ error:
+ Py_DECREF(a);
+ Py_DECREF(b);
return NULL;
-
}
static PyObject *
@@ -2782,7 +3413,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 {
@@ -2848,26 +3479,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) */
@@ -2875,10 +3508,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
for (i = Py_SIZE(b) - 1; i >= 0; --i) {
digit bi = b->ob_digit[i];
- for (j = 1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
- MULT(z, z, z)
+ for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
+ MULT(z, z, z);
if (bi & j)
- MULT(z, a, z)
+ MULT(z, a, z);
}
}
}
@@ -2887,7 +3520,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];
@@ -2895,9 +3528,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);
}
}
}
@@ -2912,13 +3545,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]);
@@ -2974,7 +3607,7 @@ long_abs(PyLongObject *v)
static int
long_nonzero(PyLongObject *v)
{
- return ABS(Py_SIZE(v)) != 0;
+ return Py_SIZE(v) != 0;
}
static PyObject *
@@ -2982,8 +3615,7 @@ long_rshift(PyLongObject *v, PyLongObject *w)
{
PyLongObject *a, *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;
CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
@@ -3002,8 +3634,7 @@ long_rshift(PyLongObject *v, PyLongObject *w)
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) {
@@ -3031,12 +3662,11 @@ long_rshift(PyLongObject *v, PyLongObject *w)
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:
Py_DECREF(a);
Py_DECREF(b);
return (PyObject *) z;
@@ -3049,27 +3679,21 @@ long_lshift(PyObject *v, PyObject *w)
/* This version due to Tim Peters */
PyLongObject *a, *b;
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;
CONVERT_BINOP(v, w, &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(a->ob_size);
newsize = oldsize + wordshift;
@@ -3093,119 +3717,152 @@ long_lshift(PyObject *v, PyObject *w)
else
assert(!accum);
z = long_normalize(z);
-lshift_error:
+ lshift_error:
Py_DECREF(a);
Py_DECREF(b);
return (PyObject *) 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 */
static PyObject *
long_bitwise(PyLongObject *a,
int op, /* '&', '|', '^' */
- PyLongObject *b)
+ PyLongObject *b)
{
- digit maska, maskb; /* 0 or PyLong_MASK */
- int negz;
- Py_ssize_t size_a, size_b, size_z;
+ int nega, negb, negz;
+ Py_ssize_t size_a, size_b, size_z, i;
PyLongObject *z;
- int i;
- 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 *) z;
- v = long_invert(z);
- Py_DECREF(z);
- return v;
+ return (PyObject *)long_normalize(z);
}
static PyObject *
@@ -3279,13 +3936,13 @@ long_int(PyObject *v)
x = PyLong_AsLong(v);
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
- PyErr_Clear();
- if (PyLong_CheckExact(v)) {
- Py_INCREF(v);
- return v;
- }
- else
- return _PyLong_Copy((PyLongObject *)v);
+ PyErr_Clear();
+ if (PyLong_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+ else
+ return _PyLong_Copy((PyLongObject *)v);
}
else
return NULL;
@@ -3338,7 +3995,7 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* Since PyLong_FromString doesn't have a length parameter,
* check here for possible NULs in the string. */
char *string = PyString_AS_STRING(x);
- if (strlen(string) != PyString_Size(x)) {
+ if (strlen(string) != (size_t)PyString_Size(x)) {
/* create a repr() of the input string,
* just like PyLong_FromString does. */
PyObject *srepr;
@@ -3346,8 +4003,8 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (srepr == NULL)
return NULL;
PyErr_Format(PyExc_ValueError,
- "invalid literal for long() with base %d: %s",
- base, PyString_AS_STRING(srepr));
+ "invalid literal for long() with base %d: %s",
+ base, PyString_AS_STRING(srepr));
Py_DECREF(srepr);
return NULL;
}
@@ -3361,7 +4018,7 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
#endif
else {
PyErr_SetString(PyExc_TypeError,
- "long() can't convert non-string with explicit base");
+ "long() can't convert non-string with explicit base");
return NULL;
}
}
@@ -3405,8 +4062,13 @@ long_getnewargs(PyLongObject *v)
}
static PyObject *
-long_getN(PyLongObject *v, void *context) {
- return PyLong_FromLong((Py_intptr_t)context);
+long_get0(PyLongObject *v, void *context) {
+ return PyLong_FromLong(0L);
+}
+
+static PyObject *
+long_get1(PyLongObject *v, void *context) {
+ return PyLong_FromLong(1L);
}
static PyObject *
@@ -3444,12 +4106,74 @@ long_sizeof(PyLongObject *v)
{
Py_ssize_t res;
- res = v->ob_type->tp_basicsize;
- if (v->ob_size != 0)
- res += abs(v->ob_size) * sizeof(digit);
+ res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit);
return PyInt_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 PyInt_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 PyInt_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;
+}
+
+PyDoc_STRVAR(long_bit_length_doc,
+"long.bit_length() -> int or long\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37L)\n\
+'0b100101'\n\
+>>> (37L).bit_length()\n\
+6");
+
#if 0
static PyObject *
long_is_finite(PyObject *v)
@@ -3461,6 +4185,8 @@ long_is_finite(PyObject *v)
static PyMethodDef long_methods[] = {
{"conjugate", (PyCFunction)long_long, METH_NOARGS,
"Returns self, the complex conjugate of any long."},
+ {"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."},
@@ -3480,17 +4206,17 @@ static PyGetSetDef long_getset[] = {
"the real part of a complex number",
NULL},
{"imag",
- (getter)long_getN, (setter)NULL,
+ (getter)long_get0, (setter)NULL,
"the imaginary part of a complex number",
- (void*)0},
+ NULL},
{"numerator",
(getter)long_long, (setter)NULL,
"the numerator of a rational number in lowest terms",
NULL},
{"denominator",
- (getter)long_getN, (setter)NULL,
+ (getter)long_get1, (setter)NULL,
"the denominator of a rational number in lowest terms",
- (void*)1},
+ NULL},
{NULL} /* Sentinel */
};
@@ -3504,52 +4230,52 @@ 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_classic_div, /*nb_divide*/
- 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_nonzero, /*tp_nonzero*/
- (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_coerce, /*nb_coerce*/
- long_int, /*nb_int*/
- long_long, /*nb_long*/
- long_float, /*nb_float*/
- long_oct, /*nb_oct*/
- long_hex, /*nb_hex*/
- 0, /* nb_inplace_add */
- 0, /* nb_inplace_subtract */
- 0, /* nb_inplace_multiply */
- 0, /* nb_inplace_divide */
- 0, /* nb_inplace_remainder */
- 0, /* nb_inplace_power */
- 0, /* nb_inplace_lshift */
- 0, /* nb_inplace_rshift */
- 0, /* nb_inplace_and */
- 0, /* nb_inplace_xor */
- 0, /* nb_inplace_or */
- 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_classic_div, /*nb_divide*/
+ 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_nonzero, /*tp_nonzero*/
+ (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_coerce, /*nb_coerce*/
+ long_int, /*nb_int*/
+ long_long, /*nb_long*/
+ long_float, /*nb_float*/
+ long_oct, /*nb_oct*/
+ long_hex, /*nb_hex*/
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ 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 = {
PyObject_HEAD_INIT(&PyType_Type)
0, /* ob_size */
"long", /* tp_name */
- sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */
+ offsetof(PyLongObject, ob_digit), /* tp_basicsize */
sizeof(digit), /* tp_itemsize */
long_dealloc, /* tp_dealloc */
0, /* tp_print */
@@ -3567,7 +4293,7 @@ PyTypeObject PyLong_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
- Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -3586,5 +4312,54 @@ PyTypeObject PyLong_Type = {
0, /* tp_init */
0, /* tp_alloc */
long_new, /* tp_new */
- PyObject_Del, /* tp_free */
+ PyObject_Del, /* tp_free */
};
+
+static PyTypeObject Long_InfoType;
+
+PyDoc_STRVAR(long_info__doc__,
+"sys.long_info\n\
+\n\
+A struct sequence that holds information about Python's\n\
+internal representation of integers. The attributes are read only.");
+
+static PyStructSequence_Field long_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}
+};
+
+static PyStructSequence_Desc long_info_desc = {
+ "sys.long_info", /* name */
+ long_info__doc__, /* doc */
+ long_info_fields, /* fields */
+ 2 /* number of fields */
+};
+
+PyObject *
+PyLong_GetInfo(void)
+{
+ PyObject* long_info;
+ int field = 0;
+ long_info = PyStructSequence_New(&Long_InfoType);
+ if (long_info == NULL)
+ return NULL;
+ PyStructSequence_SET_ITEM(long_info, field++,
+ PyInt_FromLong(PyLong_SHIFT));
+ PyStructSequence_SET_ITEM(long_info, field++,
+ PyInt_FromLong(sizeof(digit)));
+ if (PyErr_Occurred()) {
+ Py_CLEAR(long_info);
+ return NULL;
+ }
+ return long_info;
+}
+
+int
+_PyLong_Init(void)
+{
+ /* initialize long_info */
+ if (Long_InfoType.tp_name == 0)
+ PyStructSequence_InitType(&Long_InfoType, &long_info_desc);
+ return 1;
+}
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
new file mode 100644
index 0000000000..2bac266ea7
--- /dev/null
+++ b/Objects/memoryobject.c
@@ -0,0 +1,842 @@
+
+/* Memoryview object implementation */
+
+#include "Python.h"
+
+static Py_ssize_t
+get_shape0(Py_buffer *buf)
+{
+ if (buf->shape != NULL)
+ return buf->shape[0];
+ if (buf->ndim == 0)
+ return 1;
+ PyErr_SetString(PyExc_TypeError,
+ "exported buffer does not have any shape information associated "
+ "to it");
+ return -1;
+}
+
+static void
+dup_buffer(Py_buffer *dest, Py_buffer *src)
+{
+ *dest = *src;
+ if (src->ndim == 1 && src->shape != NULL) {
+ dest->shape = &(dest->smalltable[0]);
+ dest->shape[0] = get_shape0(src);
+ }
+ if (src->ndim == 1 && src->strides != NULL) {
+ dest->strides = &(dest->smalltable[1]);
+ dest->strides[0] = src->strides[0];
+ }
+}
+
+static int
+memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
+{
+ int res = 0;
+ if (self->view.obj != NULL)
+ res = PyObject_GetBuffer(self->view.obj, view, flags);
+ if (view)
+ dup_buffer(view, &self->view);
+ return res;
+}
+
+static void
+memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
+{
+ PyBuffer_Release(view);
+}
+
+PyDoc_STRVAR(memory_doc,
+"memoryview(object)\n\
+\n\
+Create a new memoryview object which references the given object.");
+
+PyObject *
+PyMemoryView_FromBuffer(Py_buffer *info)
+{
+ PyMemoryViewObject *mview;
+
+ mview = (PyMemoryViewObject *)
+ PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mview == NULL)
+ return NULL;
+ mview->base = NULL;
+ dup_buffer(&mview->view, info);
+ /* NOTE: mview->view.obj should already have been incref'ed as
+ part of PyBuffer_FillInfo(). */
+ _PyObject_GC_TRACK(mview);
+ return (PyObject *)mview;
+}
+
+PyObject *
+PyMemoryView_FromObject(PyObject *base)
+{
+ PyMemoryViewObject *mview;
+ Py_buffer view;
+
+ if (!PyObject_CheckBuffer(base)) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot make memory view because object does "
+ "not have the buffer interface");
+ return NULL;
+ }
+
+ if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
+ return NULL;
+
+ mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
+ if (mview == NULL) {
+ PyBuffer_Release(&view);
+ return NULL;
+ }
+
+ mview->base = base;
+ Py_INCREF(base);
+ return (PyObject *)mview;
+}
+
+static PyObject *
+memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
+{
+ PyObject *obj;
+ static char *kwlist[] = {"object", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
+ &obj)) {
+ return NULL;
+ }
+
+ return PyMemoryView_FromObject(obj);
+}
+
+
+static void
+_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
+ Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
+{
+ int k;
+ Py_ssize_t outstride;
+
+ if (nd==0) {
+ memcpy(dest, src, itemsize);
+ }
+ else if (nd == 1) {
+ for (k = 0; k<shape[0]; k++) {
+ memcpy(dest, src, itemsize);
+ dest += itemsize;
+ src += strides[0];
+ }
+ }
+ else {
+ if (fort == 'F') {
+ /* Copy first dimension first,
+ second dimension second, etc...
+ Set up the recursive loop backwards so that final
+ dimension is actually copied last.
+ */
+ outstride = itemsize;
+ for (k=1; k<nd-1;k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[nd-1]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape,
+ strides, itemsize, fort);
+ dest += outstride;
+ src += strides[nd-1];
+ }
+ }
+
+ else {
+ /* Copy last dimension first,
+ second-to-last dimension second, etc.
+ Set up the recursion so that the
+ first dimension is copied last
+ */
+ outstride = itemsize;
+ for (k=1; k < nd; k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[0]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape+1,
+ strides+1, itemsize,
+ fort);
+ dest += outstride;
+ src += strides[0];
+ }
+ }
+ }
+ return;
+}
+
+static int
+_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
+{
+ Py_ssize_t *indices;
+ int k;
+ Py_ssize_t elements;
+ char *ptr;
+ void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
+
+ if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ for (k=0; k<view->ndim;k++) {
+ indices[k] = 0;
+ }
+
+ elements = 1;
+ for (k=0; k<view->ndim; k++) {
+ elements *= view->shape[k];
+ }
+ if (fort == 'F') {
+ func = _Py_add_one_to_index_F;
+ }
+ else {
+ func = _Py_add_one_to_index_C;
+ }
+ while (elements--) {
+ func(view->ndim, indices, view->shape);
+ ptr = PyBuffer_GetPointer(view, indices);
+ memcpy(dest, ptr, view->itemsize);
+ dest += view->itemsize;
+ }
+
+ PyMem_Free(indices);
+ return 0;
+}
+
+/*
+ Get a the data from an object as a contiguous chunk of memory (in
+ either 'C' or 'F'ortran order) even if it means copying it into a
+ separate memory area.
+
+ Returns a new reference to a Memory view object. If no copy is needed,
+ the memory view object points to the original memory and holds a
+ lock on the original. If a copy is needed, then the memory view object
+ points to a brand-new Bytes object (and holds a memory lock on it).
+
+ buffertype
+
+ PyBUF_READ buffer only needs to be read-only
+ PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
+ PyBUF_SHADOW buffer needs to be writable so shadow it with
+ a contiguous buffer if it is not. The view will point to
+ the shadow buffer which can be written to and then
+ will be copied back into the other buffer when the memory
+ view is de-allocated. While the shadow buffer is
+ being used, it will have an exclusive write lock on
+ the original buffer.
+ */
+
+PyObject *
+PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
+{
+ PyMemoryViewObject *mem;
+ PyObject *bytes;
+ Py_buffer *view;
+ int flags;
+ char *dest;
+
+ if (!PyObject_CheckBuffer(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "object does not have the buffer interface");
+ return NULL;
+ }
+
+ mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mem == NULL)
+ return NULL;
+
+ view = &mem->view;
+ flags = PyBUF_FULL_RO;
+ switch(buffertype) {
+ case PyBUF_WRITE:
+ flags = PyBUF_FULL;
+ break;
+ }
+
+ if (PyObject_GetBuffer(obj, view, flags) != 0) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+
+ if (PyBuffer_IsContiguous(view, fort)) {
+ /* no copy needed */
+ Py_INCREF(obj);
+ mem->base = obj;
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
+ }
+ /* otherwise a copy is needed */
+ if (buffertype == PyBUF_WRITE) {
+ Py_DECREF(mem);
+ PyErr_SetString(PyExc_BufferError,
+ "writable contiguous buffer requested "
+ "for a non-contiguousobject.");
+ return NULL;
+ }
+ bytes = PyBytes_FromStringAndSize(NULL, view->len);
+ if (bytes == NULL) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+ dest = PyBytes_AS_STRING(bytes);
+ /* different copying strategy depending on whether
+ or not any pointer de-referencing is needed
+ */
+ /* strided or in-direct copy */
+ if (view->suboffsets==NULL) {
+ _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
+ view->strides, view->itemsize, fort);
+ }
+ else {
+ if (_indirect_copy_nd(dest, view, fort) < 0) {
+ Py_DECREF(bytes);
+ Py_DECREF(mem);
+ return NULL;
+ }
+ }
+ if (buffertype == PyBUF_SHADOW) {
+ /* return a shadowed memory-view object */
+ view->buf = dest;
+ mem->base = PyTuple_Pack(2, obj, bytes);
+ Py_DECREF(bytes);
+ if (mem->base == NULL) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+ }
+ else {
+ PyBuffer_Release(view); /* XXX ? */
+ /* steal the reference */
+ mem->base = bytes;
+ }
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
+}
+
+
+static PyObject *
+memory_format_get(PyMemoryViewObject *self)
+{
+ return PyString_FromString(self->view.format);
+}
+
+static PyObject *
+memory_itemsize_get(PyMemoryViewObject *self)
+{
+ return PyLong_FromSsize_t(self->view.itemsize);
+}
+
+static PyObject *
+_IntTupleFromSsizet(int len, Py_ssize_t *vals)
+{
+ int i;
+ PyObject *o;
+ PyObject *intTuple;
+
+ if (vals == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ intTuple = PyTuple_New(len);
+ if (!intTuple) return NULL;
+ for(i=0; i<len; i++) {
+ o = PyLong_FromSsize_t(vals[i]);
+ if (!o) {
+ Py_DECREF(intTuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(intTuple, i, o);
+ }
+ return intTuple;
+}
+
+static PyObject *
+memory_shape_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
+}
+
+static PyObject *
+memory_strides_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
+}
+
+static PyObject *
+memory_suboffsets_get(PyMemoryViewObject *self)
+{
+ return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
+}
+
+static PyObject *
+memory_readonly_get(PyMemoryViewObject *self)
+{
+ return PyBool_FromLong(self->view.readonly);
+}
+
+static PyObject *
+memory_ndim_get(PyMemoryViewObject *self)
+{
+ return PyLong_FromLong(self->view.ndim);
+}
+
+static PyGetSetDef memory_getsetlist[] ={
+ {"format", (getter)memory_format_get, NULL, NULL},
+ {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
+ {"shape", (getter)memory_shape_get, NULL, NULL},
+ {"strides", (getter)memory_strides_get, NULL, NULL},
+ {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
+ {"readonly", (getter)memory_readonly_get, NULL, NULL},
+ {"ndim", (getter)memory_ndim_get, NULL, NULL},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+static PyObject *
+memory_tobytes(PyMemoryViewObject *self, PyObject *noargs)
+{
+ Py_buffer view;
+ PyObject *res;
+
+ if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_SIMPLE) < 0)
+ return NULL;
+
+ res = PyBytes_FromStringAndSize(NULL, view.len);
+ PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
+ PyBuffer_Release(&view);
+ return res;
+}
+
+/* TODO: rewrite this function using the struct module to unpack
+ each buffer item */
+
+static PyObject *
+memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
+{
+ Py_buffer *view = &(mem->view);
+ Py_ssize_t i;
+ PyObject *res, *item;
+ char *buf;
+
+ if (strcmp(view->format, "B") || view->itemsize != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports byte views");
+ return NULL;
+ }
+ if (view->ndim != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports one-dimensional objects");
+ return NULL;
+ }
+ res = PyList_New(view->len);
+ if (res == NULL)
+ return NULL;
+ buf = view->buf;
+ for (i = 0; i < view->len; i++) {
+ item = PyInt_FromLong((unsigned char) *buf);
+ if (item == NULL) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ PyList_SET_ITEM(res, i, item);
+ buf++;
+ }
+ return res;
+}
+
+static PyMethodDef memory_methods[] = {
+ {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+ {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static void
+memory_dealloc(PyMemoryViewObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ if (self->view.obj != NULL) {
+ if (self->base && PyTuple_Check(self->base)) {
+ /* Special case when first element is generic object
+ with buffer interface and the second element is a
+ contiguous "shadow" that must be copied back into
+ the data areay of the first tuple element before
+ releasing the buffer on the first element.
+ */
+
+ PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
+ PyTuple_GET_ITEM(self->base,1));
+
+ /* The view member should have readonly == -1 in
+ this instance indicating that the memory can
+ be "locked" and was locked and will be unlocked
+ again after this call.
+ */
+ PyBuffer_Release(&(self->view));
+ }
+ else {
+ PyBuffer_Release(&(self->view));
+ }
+ Py_CLEAR(self->base);
+ }
+ PyObject_GC_Del(self);
+}
+
+static PyObject *
+memory_repr(PyMemoryViewObject *self)
+{
+ return PyString_FromFormat("<memory at %p>", self);
+}
+
+/* Sequence methods */
+static Py_ssize_t
+memory_length(PyMemoryViewObject *self)
+{
+ return get_shape0(&self->view);
+}
+
+/* Alternate version of memory_subcript that only accepts indices.
+ Used by PySeqIter_New().
+*/
+static PyObject *
+memory_item(PyMemoryViewObject *self, Py_ssize_t result)
+{
+ Py_buffer *view = &(self->view);
+
+ if (view->ndim == 0) {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
+ if (view->ndim == 1) {
+ /* Return a bytes object */
+ char *ptr;
+ ptr = (char *)view->buf;
+ if (result < 0) {
+ result += get_shape0(view);
+ }
+ if ((result < 0) || (result >= get_shape0(view))) {
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return NULL;
+ }
+ if (view->strides == NULL)
+ ptr += view->itemsize * result;
+ else
+ ptr += view->strides[0] * result;
+ if (view->suboffsets != NULL &&
+ view->suboffsets[0] >= 0) {
+ ptr = *((char **)ptr) + view->suboffsets[0];
+ }
+ return PyBytes_FromStringAndSize(ptr, view->itemsize);
+ } else {
+ /* Return a new memory-view object */
+ Py_buffer newview;
+ memset(&newview, 0, sizeof(newview));
+ /* XXX: This needs to be fixed so it actually returns a sub-view */
+ return PyMemoryView_FromBuffer(&newview);
+ }
+}
+
+/*
+ mem[obj] returns a bytes object holding the data for one element if
+ obj fully indexes the memory view or another memory-view object
+ if it does not.
+
+ 0-d memory-view objects can be referenced using ... or () but
+ not with anything else.
+ */
+static PyObject *
+memory_subscript(PyMemoryViewObject *self, PyObject *key)
+{
+ Py_buffer *view;
+ view = &(self->view);
+
+ if (view->ndim == 0) {
+ if (key == Py_Ellipsis ||
+ (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
+ }
+ if (PyIndex_Check(key)) {
+ Py_ssize_t result;
+ result = PyNumber_AsSsize_t(key, NULL);
+ if (result == -1 && PyErr_Occurred())
+ return NULL;
+ return memory_item(self, result);
+ }
+ else if (PySlice_Check(key)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (step == 1 && view->ndim == 1) {
+ Py_buffer newview;
+ void *newbuf = (char *) view->buf
+ + start * view->itemsize;
+ int newflags = view->readonly
+ ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
+
+ /* XXX There should be an API to create a subbuffer */
+ if (view->obj != NULL) {
+ if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
+ return NULL;
+ }
+ else {
+ newview = *view;
+ }
+ newview.buf = newbuf;
+ newview.len = slicelength * newview.itemsize;
+ newview.format = view->format;
+ newview.shape = &(newview.smalltable[0]);
+ newview.shape[0] = slicelength;
+ newview.strides = &(newview.itemsize);
+ return PyMemoryView_FromBuffer(&newview);
+ }
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "cannot index memory using \"%.200s\"",
+ key->ob_type->tp_name);
+ return NULL;
+}
+
+
+/* Need to support assigning memory if we can */
+static int
+memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
+{
+ Py_ssize_t start, len, bytelen;
+ Py_buffer srcview;
+ Py_buffer *view = &(self->view);
+ char *srcbuf, *destbuf;
+
+ if (view->readonly) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot modify read-only memory");
+ return -1;
+ }
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot delete memory");
+ return -1;
+ }
+ if (view->ndim != 1) {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return -1;
+ }
+ if (PyIndex_Check(key)) {
+ start = PyNumber_AsSsize_t(key, NULL);
+ if (start == -1 && PyErr_Occurred())
+ return -1;
+ if (start < 0) {
+ start += get_shape0(view);
+ }
+ if ((start < 0) || (start >= get_shape0(view))) {
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return -1;
+ }
+ len = 1;
+ }
+ else if (PySlice_Check(key)) {
+ Py_ssize_t stop, step;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ &start, &stop, &step, &len) < 0) {
+ return -1;
+ }
+ if (step != 1) {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ return -1;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "cannot index memory using \"%.200s\"",
+ key->ob_type->tp_name);
+ return -1;
+ }
+ if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
+ return -1;
+ }
+ /* XXX should we allow assignment of different item sizes
+ as long as the byte length is the same?
+ (e.g. assign 2 shorts to a 4-byte slice) */
+ if (srcview.itemsize != view->itemsize) {
+ PyErr_Format(PyExc_TypeError,
+ "mismatching item sizes for \"%.200s\" and \"%.200s\"",
+ view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
+ goto _error;
+ }
+ bytelen = len * view->itemsize;
+ if (bytelen != srcview.len) {
+ PyErr_SetString(PyExc_ValueError,
+ "cannot modify size of memoryview object");
+ goto _error;
+ }
+ /* Do the actual copy */
+ destbuf = (char *) view->buf + start * view->itemsize;
+ srcbuf = (char *) srcview.buf;
+ if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
+ /* No overlapping */
+ memcpy(destbuf, srcbuf, bytelen);
+ else
+ memmove(destbuf, srcbuf, bytelen);
+
+ PyBuffer_Release(&srcview);
+ return 0;
+
+_error:
+ PyBuffer_Release(&srcview);
+ return -1;
+}
+
+static PyObject *
+memory_richcompare(PyObject *v, PyObject *w, int op)
+{
+ Py_buffer vv, ww;
+ int equal = 0;
+ PyObject *res;
+
+ vv.obj = NULL;
+ ww.obj = NULL;
+ if (op != Py_EQ && op != Py_NE)
+ goto _notimpl;
+ if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+ if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+
+ if (vv.itemsize != ww.itemsize || vv.len != ww.len)
+ goto _end;
+
+ equal = !memcmp(vv.buf, ww.buf, vv.len);
+
+_end:
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+
+_notimpl:
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+
+static int
+memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
+{
+ if (self->base != NULL)
+ Py_VISIT(self->base);
+ if (self->view.obj != NULL)
+ Py_VISIT(self->view.obj);
+ return 0;
+}
+
+static int
+memory_clear(PyMemoryViewObject *self)
+{
+ Py_CLEAR(self->base);
+ PyBuffer_Release(&self->view);
+ return 0;
+}
+
+
+/* As mapping */
+static PyMappingMethods memory_as_mapping = {
+ (lenfunc)memory_length, /* mp_length */
+ (binaryfunc)memory_subscript, /* mp_subscript */
+ (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
+};
+
+static PySequenceMethods memory_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)memory_item, /* sq_item */
+};
+
+/* Buffer methods */
+static PyBufferProcs memory_as_buffer = {
+ 0, /* bf_getreadbuffer */
+ 0, /* bf_getwritebuffer */
+ 0, /* bf_getsegcount */
+ 0, /* bf_getcharbuffer */
+ (getbufferproc)memory_getbuf, /* bf_getbuffer */
+ (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
+};
+
+
+PyTypeObject PyMemoryView_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "memoryview",
+ sizeof(PyMemoryViewObject),
+ 0,
+ (destructor)memory_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)memory_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &memory_as_sequence, /* tp_as_sequence */
+ &memory_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &memory_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
+ memory_doc, /* tp_doc */
+ (traverseproc)memory_traverse, /* tp_traverse */
+ (inquiry)memory_clear, /* tp_clear */
+ memory_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ memory_methods, /* tp_methods */
+ 0, /* tp_members */
+ memory_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ memory_new, /* tp_new */
+};
diff --git a/Objects/object.c b/Objects/object.c
index 424f353ef5..94a18d37db 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -82,24 +82,29 @@ static PyTypeObject *type_list;
garbage itself. If unlist_types_without_objects
is set, they will be removed from the type_list
once the last object is deallocated. */
-int unlist_types_without_objects;
-extern int tuple_zero_allocs, fast_tuple_allocs;
-extern int quick_int_allocs, quick_neg_int_allocs;
-extern int null_strings, one_strings;
+static int unlist_types_without_objects;
+extern Py_ssize_t tuple_zero_allocs, fast_tuple_allocs;
+extern Py_ssize_t quick_int_allocs, quick_neg_int_allocs;
+extern Py_ssize_t null_strings, one_strings;
void
dump_counts(FILE* f)
{
PyTypeObject *tp;
for (tp = type_list; tp; tp = tp->tp_next)
- fprintf(f, "%s alloc'd: %d, freed: %d, max in use: %d\n",
+ 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: %d, empty: %d\n",
+ 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: %d, neg: %d\n",
+ 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: %d, 1-strings: %d\n",
+ fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, "
+ "1-strings: %" PY_FORMAT_SIZE_T "d\n",
null_strings, one_strings);
}
@@ -483,12 +488,6 @@ PyObject_Unicode(PyObject *v)
return v;
}
- /* Try the __unicode__ method */
- if (unicodestr == NULL) {
- unicodestr= PyString_InternFromString("__unicode__");
- if (unicodestr == NULL)
- return NULL;
- }
if (PyInstance_Check(v)) {
/* We're an instance of a classic class */
/* Try __unicode__ from the instance -- alas we have no type */
@@ -503,16 +502,15 @@ PyObject_Unicode(PyObject *v)
}
}
else {
- /* Not a classic class instance, try __unicode__ from type */
- /* _PyType_Lookup doesn't create a reference */
- func = _PyType_Lookup(Py_TYPE(v), unicodestr);
+ /* Not a classic class instance, try __unicode__. */
+ func = _PyObject_LookupSpecial(v, "__unicode__", &unicodestr);
if (func != NULL) {
unicode_method_found = 1;
- res = PyObject_CallFunctionObjArgs(func, v, NULL);
- }
- else {
- PyErr_Clear();
+ res = PyObject_CallFunctionObjArgs(func, NULL);
+ Py_DECREF(func);
}
+ else if (PyErr_Occurred())
+ return NULL;
}
/* Didn't find __unicode__ */
@@ -1027,15 +1025,18 @@ _Py_HashDouble(double v)
* 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 */
- 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;
@@ -1074,23 +1075,15 @@ _Py_HashDouble(double v)
long
_Py_HashPointer(void *p)
{
-#if SIZEOF_LONG >= SIZEOF_VOID_P
- return (long)p;
-#else
- /* convert to a Python long and hash that */
- PyObject* longobj;
long x;
-
- if ((longobj = PyLong_FromVoidPtr(p)) == NULL) {
- x = -1;
- goto finally;
- }
- x = PyObject_Hash(longobj);
-
-finally:
- Py_XDECREF(longobj);
+ 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;
-#endif
}
long
@@ -1307,10 +1300,24 @@ PyObject_SelfIter(PyObject *obj)
return obj;
}
+/* Helper used when the __next__ method is removed from a type:
+ tp_iternext is never NULL and can be safely called without checking
+ on every iteration.
+ */
+
+PyObject *
+_PyObject_NextNotImplemented(PyObject *self)
+{
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not iterable",
+ Py_TYPE(self)->tp_name);
+ return NULL;
+}
+
/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
PyObject *
-PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
+_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
{
PyTypeObject *tp = Py_TYPE(obj);
PyObject *descr = NULL;
@@ -1388,36 +1395,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) {
@@ -1440,8 +1448,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;
@@ -1487,27 +1502,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);
@@ -1529,6 +1546,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 */
@@ -1881,13 +1905,26 @@ static PyObject *
_dir_object(PyObject *obj)
{
PyObject *result = NULL;
- PyObject *dirfunc = PyObject_GetAttrString((PyObject *)obj->ob_type,
- "__dir__");
+ static PyObject *dir_str = NULL;
+ PyObject *dirfunc;
assert(obj);
+ if (PyInstance_Check(obj)) {
+ dirfunc = PyObject_GetAttrString(obj, "__dir__");
+ if (dirfunc == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ else {
+ dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str);
+ if (PyErr_Occurred())
+ return NULL;
+ }
if (dirfunc == NULL) {
/* use default implementation */
- PyErr_Clear();
if (PyModule_Check(obj))
result = _specialized_dir_module(obj);
else if (PyType_Check(obj) || PyClass_Check(obj))
@@ -1897,7 +1934,7 @@ _dir_object(PyObject *obj)
}
else {
/* use __dir__ */
- result = PyObject_CallFunctionObjArgs(dirfunc, obj, NULL);
+ result = PyObject_CallFunctionObjArgs(dirfunc, NULL);
Py_DECREF(dirfunc);
if (result == NULL)
return NULL;
@@ -2104,6 +2141,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyProperty_Type) < 0)
Py_FatalError("Can't initialize property type");
+ if (PyType_Ready(&PyMemoryView_Type) < 0)
+ Py_FatalError("Can't initialize memoryview type");
+
if (PyType_Ready(&PyTuple_Type) < 0)
Py_FatalError("Can't initialize tuple type");
@@ -2151,6 +2191,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyMemberDescr_Type) < 0)
Py_FatalError("Can't initialize member descriptor type");
+
+ if (PyType_Ready(&PyFile_Type) < 0)
+ Py_FatalError("Can't initialize file type");
}
@@ -2259,6 +2302,10 @@ _Py_GetObjects(PyObject *self, PyObject *args)
#endif
+/* Hack to force loading of capsule.o */
+PyTypeObject *_Py_capsule_hack = &PyCapsule_Type;
+
+
/* Hack to force loading of cobject.o */
PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index f3297f2e22..483847cad2 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -2,6 +2,21 @@
#ifdef WITH_PYMALLOC
+#ifdef WITH_VALGRIND
+#include <valgrind/valgrind.h>
+
+/* If we're using GCC, use __builtin_expect() to reduce overhead of
+ the valgrind checks */
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+# define UNLIKELY(value) __builtin_expect((value), 0)
+#else
+# define UNLIKELY(value) (value)
+#endif
+
+/* -1 indicates that we haven't checked that we're running on valgrind yet. */
+static int running_on_valgrind = -1;
+#endif
+
/* An object allocator for Python.
Here is an introduction to the layers of the Python memory architecture,
@@ -234,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 "" */
@@ -389,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
@@ -667,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
@@ -694,7 +717,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
@@ -728,6 +751,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
@@ -923,10 +953,18 @@ 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;
+#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 +1159,9 @@ PyObject_Free(void *p)
return;
}
+#ifdef WITH_VALGRIND
+redirect:
+#endif
/* We didn't allocate this address. */
free(p);
}
@@ -1137,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);
@@ -1150,6 +1194,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 +1227,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
@@ -1241,6 +1294,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,9 +1388,50 @@ 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(const void *p)
+{
+ _PyObject_DebugCheckAddressApi(_PYMALLOC_OBJ_ID, p);
+}
+
+
+/* generic debug memory api, with an "id" to identify the API in use */
+void *
+_PyObject_DebugMallocApi(char id, size_t nbytes)
+{
uchar *p; /* base address of malloc'ed block */
uchar *tail; /* p + 2*SST + nbytes == pointer to tail pad bytes */
size_t total; /* nbytes + 4*SST */
@@ -1348,12 +1446,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 +1463,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 +1493,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 +1505,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;
@@ -1422,7 +1528,7 @@ _PyObject_DebugRealloc(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;
@@ -1431,26 +1537,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 +1600,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 +1628,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)
@@ -1532,11 +1655,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);
@@ -1642,7 +1765,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;
@@ -1652,7 +1775,6 @@ _PyObject_DebugMallocStats(void)
* 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;
@@ -1661,7 +1783,6 @@ _PyObject_DebugMallocStats(void)
continue;
narenas += 1;
- poolsinarena = arenas[i].ntotalpools;
numfreepools += arenas[i].nfreepools;
/* round up to pool alignment */
@@ -1700,7 +1821,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];
@@ -1715,7 +1836,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;
@@ -1758,8 +1879,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
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 6a6eb3afd1..802f45f4c4 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -362,12 +362,14 @@ static int
set_add_entry(register PySetObject *so, setentry *entry)
{
register Py_ssize_t n_used;
+ PyObject *key = entry->key;
+ long hash = entry->hash;
assert(so->fill <= so->mask); /* at least one empty slot */
n_used = so->used;
- Py_INCREF(entry->key);
- if (set_insert_key(so, entry->key, entry->hash) == -1) {
- Py_DECREF(entry->key);
+ 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))
@@ -647,6 +649,8 @@ static int
set_merge(PySetObject *so, PyObject *otherset)
{
PySetObject *other;
+ PyObject *key;
+ long hash;
register Py_ssize_t i;
register setentry *entry;
@@ -667,11 +671,13 @@ 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, entry->hash) == -1) {
- Py_DECREF(entry->key);
+ key = entry->key;
+ hash = entry->hash;
+ if (key != NULL &&
+ key != dummy) {
+ Py_INCREF(key);
+ if (set_insert_key(so, key, hash) == -1) {
+ Py_DECREF(key);
return -1;
}
}
@@ -1640,15 +1646,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;
}
@@ -1855,12 +1868,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;
@@ -1890,12 +1901,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;
@@ -1924,12 +1933,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;
}
@@ -2389,11 +2396,25 @@ test_c_api(PySetObject *so)
Py_ssize_t i;
PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
PyObject *ob = (PyObject *)so;
+ 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 = PyString_FromString("abc");
+ if (str == NULL)
+ return NULL;
+ set_clear_internal(so);
+ if (set_update_internal(so, str) == -1) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ Py_DECREF(str);
+
+ /* Exercise type/size checks */
assert(PySet_Size(ob) == 3);
assert(PySet_GET_SIZE(ob) == 3);
diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt
index 82a877465a..ab506d60f9 100644
--- a/Objects/stringlib/README.txt
+++ b/Objects/stringlib/README.txt
@@ -13,11 +13,8 @@ STRINGLIB_CHAR
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.
+ a PyObject representing the empty string, only to be used if
+ STRINGLIB_MUTABLE is 0
Py_ssize_t STRINGLIB_LEN(PyObject*)
@@ -32,3 +29,12 @@ STRINGLIB_CHAR* STRINGLIB_STR(PyObject*)
returns the pointer to the character data for the given string
object (which must be of the right type)
+
+int STRINGLIB_CHECK_EXACT(PyObject *)
+
+ returns true if the object is an instance of our type, not a subclass
+
+STRINGLIB_MUTABLE
+
+ must be 0 or 1 to tell the cpp macros in stringlib code if the object
+ being operated on is mutable or not
diff --git a/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 23bccfb01d..e231c587e4 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,19 +16,35 @@
#define FAST_COUNT 0
#define FAST_SEARCH 1
+#define FAST_RSEARCH 2
+
+#if LONG_BIT >= 128
+#define STRINGLIB_BLOOM_WIDTH 128
+#elif LONG_BIT >= 64
+#define STRINGLIB_BLOOM_WIDTH 64
+#elif LONG_BIT >= 32
+#define STRINGLIB_BLOOM_WIDTH 32
+#else
+#error "LONG_BIT is smaller than 32"
+#endif
+
+#define STRINGLIB_BLOOM_ADD(mask, ch) \
+ ((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
+#define STRINGLIB_BLOOM(mask, ch) \
+ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
Py_LOCAL_INLINE(Py_ssize_t)
fastsearch(const STRINGLIB_CHAR* s, Py_ssize_t n,
const STRINGLIB_CHAR* p, Py_ssize_t m,
- int mode)
+ Py_ssize_t maxcount, int mode)
{
- long mask;
+ unsigned long mask;
Py_ssize_t skip, count = 0;
Py_ssize_t i, j, mlast, w;
w = n - m;
- if (w < 0)
+ if (w < 0 || (mode == FAST_COUNT && maxcount == 0))
return -1;
/* look for special cases */
@@ -38,54 +54,101 @@ 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 {
+ } 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)
+ mask = 0;
+
+ if (mode != FAST_RSEARCH) {
+
+ /* create compressed boyer-moore delta 1 table */
+
+ /* process pattern[:-1] */
+ for (i = 0; i < mlast; i++) {
+ STRINGLIB_BLOOM_ADD(mask, p[i]);
+ if (p[i] == p[mlast])
+ skip = mlast - i - 1;
+ }
+ /* process pattern[-1] outside the loop */
+ STRINGLIB_BLOOM_ADD(mask, p[mlast]);
+
+ for (i = 0; i <= w; i++) {
+ /* note: using mlast in the skip path slows things down on x86 */
+ if (s[i+m-1] == p[m-1]) {
+ /* candidate match */
+ for (j = 0; j < mlast; j++)
+ if (s[i+j] != p[j])
+ break;
+ if (j == mlast) {
+ /* got a match! */
+ if (mode != FAST_COUNT)
+ return i;
+ count++;
+ if (count == maxcount)
+ return maxcount;
+ i = i + mlast;
+ continue;
+ }
+ /* miss: check if next character is part of pattern */
+ if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ i = i + m;
+ else
+ i = i + skip;
+ } else {
+ /* skip: check if next character is part of pattern */
+ if (!STRINGLIB_BLOOM(mask, s[i+m]))
+ i = i + m;
+ }
+ }
+ } else { /* FAST_RSEARCH */
+
+ /* create compressed boyer-moore delta 1 table */
+
+ /* process pattern[0] outside the loop */
+ STRINGLIB_BLOOM_ADD(mask, p[0]);
+ /* process pattern[:0:-1] */
+ for (i = mlast; i > 0; i--) {
+ STRINGLIB_BLOOM_ADD(mask, p[i]);
+ if (p[i] == p[0])
+ skip = i - 1;
+ }
+
+ for (i = w; i >= 0; i--) {
+ if (s[i] == p[0]) {
+ /* candidate match */
+ for (j = mlast; j > 0; j--)
+ if (s[i+j] != p[j])
+ break;
+ if (j == 0)
+ /* got a match! */
return i;
- count++;
- i = i + mlast;
- continue;
+ /* miss: check if previous character is part of pattern */
+ if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+ i = i - m;
+ else
+ i = i - skip;
+ } else {
+ /* skip: check if previous character is part of pattern */
+ if (i > 0 && !STRINGLIB_BLOOM(mask, s[i-1]))
+ i = i - m;
}
- /* 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;
}
}
@@ -95,10 +158,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 fbe99c75ae..ce615dcb8a 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;
@@ -32,42 +32,43 @@ 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, -1, FAST_RSEARCH);
+
+ if (pos >= 0)
+ pos += offset;
+
+ return pos;
}
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
+
Py_LOCAL_INLINE(Py_ssize_t)
stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
Py_ssize_t start, Py_ssize_t end)
{
- 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;
-
- return stringlib_find(
- str + start, end - start,
- sub, sub_len, start
- );
+ ADJUST_INDICES(start, end, str_len);
+ return stringlib_find(str + start, end - start, sub, sub_len, start);
}
Py_LOCAL_INLINE(Py_ssize_t)
@@ -75,21 +76,11 @@ 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);
}
-#if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY)
+#ifdef STRINGLIB_WANT_CONTAINS_OBJ
Py_LOCAL_INLINE(int)
stringlib_contains_obj(PyObject* str, PyObject* sub)
@@ -100,34 +91,35 @@ stringlib_contains_obj(PyObject* str, PyObject* sub)
) != -1;
}
-#endif /* STRINGLIB_STR */
-
-#ifdef FROM_UNICODE
+#endif /* STRINGLIB_WANT_CONTAINS_OBJ */
/*
This function is a helper for the "find" family (find, rfind, index,
-rindex) of unicodeobject.c file, because they all have the same
-behaviour for the arguments.
+rindex) and for count, startswith and endswith, because they all have
+the same behaviour for the arguments.
It does not touch the variables received until it knows everything
is ok.
-
-Note that we receive a pointer to the pointer of the substring object,
-so when we create that object in this function we don't DECREF it,
-because it continues living in the caller functions (those functions,
-after finishing using the substring, must DECREF it).
*/
+#define FORMAT_BUFFER_SIZE 50
+
Py_LOCAL_INLINE(int)
-_ParseTupleFinds (PyObject *args, PyObject **substring,
- Py_ssize_t *start, Py_ssize_t *end) {
- PyObject *tmp_substring;
+stringlib_parse_args_finds(const char * function_name, PyObject *args,
+ PyObject **subobj,
+ Py_ssize_t *start, Py_ssize_t *end)
+{
+ PyObject *tmp_subobj;
Py_ssize_t tmp_start = 0;
Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
PyObject *obj_start=Py_None, *obj_end=Py_None;
+ char format[FORMAT_BUFFER_SIZE] = "O|OO:";
+ size_t len = strlen(format);
- if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
- &obj_start, &obj_end))
+ strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);
+ format[FORMAT_BUFFER_SIZE - 1] = '\0';
+
+ if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end))
return 0;
/* To support None in "start" and "end" arguments, meaning
@@ -140,23 +132,44 @@ _ParseTupleFinds (PyObject *args, PyObject **substring,
if (!_PyEval_SliceIndex(obj_end, &tmp_end))
return 0;
- tmp_substring = PyUnicode_FromObject(tmp_substring);
- if (!tmp_substring)
- return 0;
-
*start = tmp_start;
*end = tmp_end;
- *substring = tmp_substring;
+ *subobj = tmp_subobj;
return 1;
}
-#endif /* FROM_UNICODE */
+#undef FORMAT_BUFFER_SIZE
-#endif /* STRINGLIB_FIND_H */
+#if STRINGLIB_IS_UNICODE
/*
-Local variables:
-c-basic-offset: 4
-indent-tabs-mode: nil
-End:
+Wraps stringlib_parse_args_finds() and additionally ensures that the
+first argument is a unicode object.
+
+Note that we receive a pointer to the pointer of the substring object,
+so when we create that object in this function we don't DECREF it,
+because it continues living in the caller functions (those functions,
+after finishing using the substring, must DECREF it).
*/
+
+Py_LOCAL_INLINE(int)
+stringlib_parse_args_finds_unicode(const char * function_name, PyObject *args,
+ PyUnicodeObject **substring,
+ Py_ssize_t *start, Py_ssize_t *end)
+{
+ PyObject *tmp_substring;
+
+ if(stringlib_parse_args_finds(function_name, args, &tmp_substring,
+ start, end)) {
+ tmp_substring = PyUnicode_FromObject(tmp_substring);
+ if (!tmp_substring)
+ return 0;
+ *substring = (PyUnicodeObject *)tmp_substring;
+ return 1;
+ }
+ return 0;
+}
+
+#endif /* STRINGLIB_IS_UNICODE */
+
+#endif /* STRINGLIB_FIND_H */
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h
index e9495c973e..c49a1042ff 100644
--- a/Objects/stringlib/formatter.h
+++ b/Objects/stringlib/formatter.h
@@ -1,6 +1,8 @@
/* implements the string, long, and float formatters. that is,
string.__format__, etc. */
+#include <locale.h>
+
/* Before including this, you must include either:
stringlib/unicodedefs.h
stringlib/stringdefs.h
@@ -9,12 +11,11 @@
FORMAT_STRING
FORMAT_LONG
FORMAT_FLOAT
+ FORMAT_COMPLEX
to be whatever you want the public names of these functions to
be. These are the only non-static functions defined here.
*/
-#define ALLOW_PARENS_FOR_SIGN 0
-
/* Raises an exception about an unknown presentation type for this
* type. */
@@ -43,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
@@ -104,9 +123,6 @@ is_sign_element(STRINGLIB_CHAR c)
{
switch (c) {
case ' ': case '+': case '-':
-#if ALLOW_PARENS_FOR_SIGN
- case '(':
-#endif
return 1;
default:
return 0;
@@ -120,10 +136,31 @@ typedef struct {
int alternate;
STRINGLIB_CHAR sign;
Py_ssize_t width;
+ int thousands_separators;
Py_ssize_t precision;
STRINGLIB_CHAR type;
} InternalFormatSpec;
+
+#if 0
+/* Occassionally useful for debugging. Should normally be commented out. */
+static void
+DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
+{
+ printf("internal format spec: fill_char %d\n", format->fill_char);
+ printf("internal format spec: align %d\n", format->align);
+ printf("internal format spec: alternate %d\n", format->alternate);
+ printf("internal format spec: sign %d\n", format->sign);
+ printf("internal format spec: width %zd\n", format->width);
+ printf("internal format spec: thousands_separators %d\n",
+ format->thousands_separators);
+ printf("internal format spec: precision %zd\n", format->precision);
+ printf("internal format spec: type %c\n", format->type);
+ printf("\n");
+}
+#endif
+
+
/*
ptr points to the start of the format_spec, end points just past its end.
fills in format with the parsed information.
@@ -134,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;
@@ -142,13 +180,15 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
/* end-ptr is used throughout this code to specify the length of
the input string */
- Py_ssize_t specified_width;
+ Py_ssize_t consumed;
+ int align_specified = 0;
format->fill_char = '\0';
- format->align = '\0';
+ format->align = default_align;
format->alternate = 0;
format->sign = '\0';
format->width = -1;
+ format->thousands_separators = 0;
format->precision = -1;
format->type = default_type;
@@ -157,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;
}
@@ -168,11 +210,6 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
if (end-ptr >= 1 && is_sign_element(ptr[0])) {
format->sign = ptr[0];
++ptr;
-#if ALLOW_PARENS_FOR_SIGN
- if (end-ptr >= 1 && ptr[0] == ')') {
- ++ptr;
- }
-#endif
}
/* If the next character is #, we're in alternate mode. This only
@@ -185,31 +222,41 @@ 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;
}
- /* XXX add error checking */
- specified_width = get_integer(&ptr, end, &format->width);
+ consumed = get_integer(&ptr, end, &format->width);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
- /* if specified_width is 0, we didn't consume any characters for
- the width. in that case, reset the width to -1, because
- get_integer() will have set it to zero */
- if (specified_width == 0) {
+ /* If consumed is 0, we didn't consume any characters for the
+ width. In that case, reset the width to -1, because
+ get_integer() will have set it to zero. -1 is how we record
+ that the width wasn't specified. */
+ if (consumed == 0)
format->width = -1;
+
+ /* Comma signifies add thousands separators */
+ if (end-ptr && ptr[0] == ',') {
+ format->thousands_separators = 1;
+ ++ptr;
}
/* Parse field precision */
if (end-ptr && ptr[0] == '.') {
++ptr;
- /* XXX add error checking */
- specified_width = get_integer(&ptr, end, &format->precision);
+ consumed = get_integer(&ptr, end, &format->precision);
+ if (consumed == -1)
+ /* Overflow error. Exception already set. */
+ return 0;
- /* not having a precision after a dot is an error */
- if (specified_width == 0) {
+ /* Not having a precision after a dot is an error. */
+ if (consumed == 0) {
PyErr_Format(PyExc_ValueError,
"Format specifier missing precision");
return 0;
@@ -217,10 +264,10 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
}
- /* Finally, parse the type field */
+ /* Finally, parse the type field. */
if (end-ptr > 1) {
- /* invalid conversion spec */
+ /* More than one char remain, invalid conversion spec. */
PyErr_Format(PyExc_ValueError, "Invalid conversion specification");
return 0;
}
@@ -230,14 +277,103 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
++ptr;
}
+ /* Do as much validating as we can, just by looking at the format
+ specifier. Do not take into account what type of formatting
+ we're doing (int, float, string). */
+
+ if (format->thousands_separators) {
+ switch (format->type) {
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'E':
+ case 'G':
+ case '%':
+ case 'F':
+ case '\0':
+ /* These are allowed. See PEP 378.*/
+ break;
+ default:
+ invalid_comma_type(format->type);
+ return 0;
+ }
+ }
+
return 1;
}
-#if defined FORMAT_FLOAT || defined FORMAT_LONG
+/* Calculate the padding needed. */
+static void
+calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align,
+ Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding,
+ Py_ssize_t *n_total)
+{
+ if (width >= 0) {
+ if (nchars > width)
+ *n_total = nchars;
+ else
+ *n_total = width;
+ }
+ else {
+ /* not specified, use all of the chars and no more */
+ *n_total = nchars;
+ }
+
+ /* Figure out how much leading space we need, based on the
+ aligning */
+ if (align == '>')
+ *n_lpadding = *n_total - nchars;
+ else if (align == '^')
+ *n_lpadding = (*n_total - nchars) / 2;
+ else if (align == '<' || align == '=')
+ *n_lpadding = 0;
+ else {
+ /* We should never have an unspecified alignment. */
+ *n_lpadding = 0;
+ assert(0);
+ }
+
+ *n_rpadding = *n_total - nchars - *n_lpadding;
+}
+
+/* Do the padding, and return a pointer to where the caller-supplied
+ content goes. */
+static STRINGLIB_CHAR *
+fill_padding(STRINGLIB_CHAR *p, Py_ssize_t nchars, STRINGLIB_CHAR fill_char,
+ Py_ssize_t n_lpadding, Py_ssize_t n_rpadding)
+{
+ /* Pad on left. */
+ if (n_lpadding)
+ STRINGLIB_FILL(p, fill_char, n_lpadding);
+
+ /* Pad on right. */
+ if (n_rpadding)
+ STRINGLIB_FILL(p + nchars + n_lpadding, fill_char, n_rpadding);
+
+ /* Pointer to the user content. */
+ return p + n_lpadding;
+}
+
+#if defined FORMAT_FLOAT || defined FORMAT_LONG || defined FORMAT_COMPLEX
/************************************************************************/
/*********** common routines for numeric formatting *********************/
/************************************************************************/
+/* Locale type codes. */
+#define LT_CURRENT_LOCALE 0
+#define LT_DEFAULT_LOCALE 1
+#define LT_NO_LOCALE 2
+
+/* Locale info needed for formatting integers and the part of floats
+ before and including the decimal. Note that locales only support
+ 8-bit chars, not unicode. */
+typedef struct {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+} LocaleInfo;
+
/* describes the layout for an integer, see the comment in
calc_number_widths() for details */
typedef struct {
@@ -245,38 +381,85 @@ typedef struct {
Py_ssize_t n_prefix;
Py_ssize_t n_spadding;
Py_ssize_t n_rpadding;
- char lsign;
- Py_ssize_t n_lsign;
- char rsign;
- Py_ssize_t n_rsign;
- Py_ssize_t n_total; /* just a convenience, it's derivable from the
- other fields */
+ char sign;
+ Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */
+ Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including
+ any grouping chars. */
+ Py_ssize_t n_decimal; /* 0 if only an integer */
+ Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part,
+ excluding the decimal itself, if
+ present. */
+
+ /* These 2 are not the widths of fields, but are needed by
+ STRINGLIB_GROUPING. */
+ Py_ssize_t n_digits; /* The number of digits before a decimal
+ or exponent. */
+ Py_ssize_t n_min_width; /* The min_width we used when we computed
+ the n_grouped_digits width. */
} NumberFieldWidths;
+
+/* Given a number of the form:
+ digits[remainder]
+ where ptr points to the start and end points to the end, find where
+ the integer part ends. This could be a decimal, an exponent, both,
+ or neither.
+ If a decimal point is present, set *has_decimal and increment
+ remainder beyond it.
+ Results are undefined (but shouldn't crash) for improperly
+ formatted strings.
+*/
+static void
+parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len,
+ Py_ssize_t *n_remainder, int *has_decimal)
+{
+ STRINGLIB_CHAR *end = ptr + len;
+ STRINGLIB_CHAR *remainder;
+
+ while (ptr<end && isdigit(*ptr))
+ ++ptr;
+ remainder = ptr;
+
+ /* Does remainder start with a decimal point? */
+ *has_decimal = ptr<end && *remainder == '.';
+
+ /* Skip the decimal point. */
+ if (*has_decimal)
+ remainder++;
+
+ *n_remainder = end - remainder;
+}
+
/* not all fields of format are used. for example, precision is
unused. should this take discrete params in order to be more clear
about what it does? or is passing a single format parameter easier
and more efficient enough to justify a little obfuscation? */
-static void
-calc_number_widths(NumberFieldWidths *spec, STRINGLIB_CHAR actual_sign,
- Py_ssize_t n_prefix, Py_ssize_t n_digits,
+static Py_ssize_t
+calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
+ STRINGLIB_CHAR sign_char, STRINGLIB_CHAR *number,
+ Py_ssize_t n_number, Py_ssize_t n_remainder,
+ int has_decimal, const LocaleInfo *locale,
const InternalFormatSpec *format)
{
+ Py_ssize_t n_non_digit_non_padding;
+ Py_ssize_t n_padding;
+
+ spec->n_digits = n_number - n_remainder - (has_decimal?1:0);
spec->n_lpadding = 0;
- spec->n_prefix = 0;
+ spec->n_prefix = n_prefix;
+ spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0;
+ spec->n_remainder = n_remainder;
spec->n_spadding = 0;
spec->n_rpadding = 0;
- spec->lsign = '\0';
- spec->n_lsign = 0;
- spec->rsign = '\0';
- spec->n_rsign = 0;
+ spec->sign = '\0';
+ spec->n_sign = 0;
/* the output will look like:
- | |
- | <lpadding> <lsign> <prefix> <spadding> <digits> <rsign> <rpadding> |
- | |
+ | |
+ | <lpadding> <sign> <prefix> <spadding> <grouped_digits> <decimal> <remainder> <rpadding> |
+ | |
- lsign and rsign are computed from format->sign and the actual
+ sign is computed from format->sign and the actual
sign of the number
prefix is given (it's for the '0x' prefix)
@@ -291,109 +474,196 @@ calc_number_widths(NumberFieldWidths *spec, STRINGLIB_CHAR actual_sign,
*/
/* compute the various parts we're going to write */
- if (format->sign == '+') {
+ switch (format->sign) {
+ case '+':
/* always put a + or - */
- spec->n_lsign = 1;
- spec->lsign = (actual_sign == '-' ? '-' : '+');
- }
-#if ALLOW_PARENS_FOR_SIGN
- else if (format->sign == '(') {
- if (actual_sign == '-') {
- spec->n_lsign = 1;
- spec->lsign = '(';
- spec->n_rsign = 1;
- spec->rsign = ')';
- }
- }
-#endif
- else if (format->sign == ' ') {
- spec->n_lsign = 1;
- spec->lsign = (actual_sign == '-' ? '-' : ' ');
- }
- else {
- /* non specified, or the default (-) */
- if (actual_sign == '-') {
- spec->n_lsign = 1;
- spec->lsign = '-';
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : '+');
+ break;
+ case ' ':
+ spec->n_sign = 1;
+ spec->sign = (sign_char == '-' ? '-' : ' ');
+ break;
+ default:
+ /* Not specified, or the default (-) */
+ if (sign_char == '-') {
+ spec->n_sign = 1;
+ spec->sign = '-';
}
}
- spec->n_prefix = n_prefix;
+ /* The number of chars used for non-digits and non-padding. */
+ n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal +
+ spec->n_remainder;
- /* now the number of padding characters */
- if (format->width == -1) {
- /* no padding at all, nothing to do */
- }
- else {
- /* see if any padding is needed */
- if (spec->n_lsign + n_digits + spec->n_rsign +
- spec->n_prefix >= format->width) {
- /* no padding needed, we're already bigger than the
- requested width */
- }
- else {
- /* determine which of left, space, or right padding is
- needed */
- Py_ssize_t padding = format->width -
- (spec->n_lsign + spec->n_prefix +
- n_digits + spec->n_rsign);
- if (format->align == '<')
- spec->n_rpadding = padding;
- else if (format->align == '>')
- spec->n_lpadding = padding;
- else if (format->align == '^') {
- spec->n_lpadding = padding / 2;
- spec->n_rpadding = padding - spec->n_lpadding;
- }
- else if (format->align == '=')
- spec->n_spadding = padding;
- else
- spec->n_lpadding = padding;
+ /* min_width can go negative, that's okay. format->width == -1 means
+ we don't care. */
+ if (format->fill_char == '0' && format->align == '=')
+ spec->n_min_width = format->width - n_non_digit_non_padding;
+ else
+ spec->n_min_width = 0;
+
+ if (spec->n_digits == 0)
+ /* This case only occurs when using 'c' formatting, we need
+ to special case it because the grouping code always wants
+ to have at least one character. */
+ spec->n_grouped_digits = 0;
+ else
+ spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL,
+ spec->n_digits,
+ spec->n_min_width,
+ locale->grouping,
+ locale->thousands_sep);
+
+ /* Given the desired width and the total of digit and non-digit
+ space we consume, see if we need any padding. format->width can
+ be negative (meaning no padding), but this code still works in
+ that case. */
+ n_padding = format->width -
+ (n_non_digit_non_padding + spec->n_grouped_digits);
+ if (n_padding > 0) {
+ /* Some padding is needed. Determine if it's left, space, or right. */
+ switch (format->align) {
+ case '<':
+ spec->n_rpadding = n_padding;
+ break;
+ case '^':
+ spec->n_lpadding = n_padding / 2;
+ spec->n_rpadding = n_padding - spec->n_lpadding;
+ break;
+ case '=':
+ spec->n_spadding = n_padding;
+ break;
+ case '>':
+ spec->n_lpadding = n_padding;
+ break;
+ default:
+ /* Shouldn't get here, but treat it as '>' */
+ spec->n_lpadding = n_padding;
+ assert(0);
+ break;
}
}
- spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix +
- spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding;
+ return spec->n_lpadding + spec->n_sign + spec->n_prefix +
+ spec->n_spadding + spec->n_grouped_digits + spec->n_decimal +
+ spec->n_remainder + spec->n_rpadding;
}
-/* fill in the non-digit parts of a numbers's string representation,
- as determined in calc_number_widths(). returns the pointer to
- where the digits go. */
-static STRINGLIB_CHAR *
-fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec,
- STRINGLIB_CHAR *prefix, Py_ssize_t n_digits,
- STRINGLIB_CHAR fill_char)
+/* Fill in the digit parts of a numbers's string representation,
+ as determined in calc_number_widths().
+ No error checking, since we know the buffer is the correct size. */
+static void
+fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec,
+ STRINGLIB_CHAR *digits, Py_ssize_t n_digits,
+ STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char,
+ LocaleInfo *locale, int toupper)
{
- STRINGLIB_CHAR *p_digits;
+ /* Used to keep track of digits, decimal, and remainder. */
+ STRINGLIB_CHAR *p = digits;
+
+#ifndef NDEBUG
+ Py_ssize_t r;
+#endif
if (spec->n_lpadding) {
- STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding);
- p_buf += spec->n_lpadding;
+ STRINGLIB_FILL(buf, fill_char, spec->n_lpadding);
+ buf += spec->n_lpadding;
}
- if (spec->n_lsign == 1) {
- *p_buf++ = spec->lsign;
+ if (spec->n_sign == 1) {
+ *buf++ = spec->sign;
}
if (spec->n_prefix) {
- memmove(p_buf,
+ memmove(buf,
prefix,
spec->n_prefix * sizeof(STRINGLIB_CHAR));
- p_buf += spec->n_prefix;
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_prefix; ++t)
+ buf[t] = STRINGLIB_TOUPPER(buf[t]);
+ }
+ buf += spec->n_prefix;
}
if (spec->n_spadding) {
- STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding);
- p_buf += spec->n_spadding;
+ STRINGLIB_FILL(buf, fill_char, spec->n_spadding);
+ buf += spec->n_spadding;
}
- p_digits = p_buf;
- p_buf += n_digits;
- if (spec->n_rsign == 1) {
- *p_buf++ = spec->rsign;
+
+ /* Only for type 'c' special case, it has no digits. */
+ if (spec->n_digits != 0) {
+ /* Fill the digits with InsertThousandsGrouping. */
+#ifndef NDEBUG
+ r =
+#endif
+ STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits,
+ spec->n_digits, spec->n_min_width,
+ locale->grouping, locale->thousands_sep);
+#ifndef NDEBUG
+ assert(r == spec->n_grouped_digits);
+#endif
+ p += spec->n_digits;
+ }
+ if (toupper) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_grouped_digits; ++t)
+ buf[t] = STRINGLIB_TOUPPER(buf[t]);
}
+ buf += spec->n_grouped_digits;
+
+ if (spec->n_decimal) {
+ Py_ssize_t t;
+ for (t = 0; t < spec->n_decimal; ++t)
+ buf[t] = locale->decimal_point[t];
+ buf += spec->n_decimal;
+ p += 1;
+ }
+
+ if (spec->n_remainder) {
+ memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR));
+ buf += spec->n_remainder;
+ p += spec->n_remainder;
+ }
+
if (spec->n_rpadding) {
- STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding);
- p_buf += spec->n_rpadding;
+ STRINGLIB_FILL(buf, fill_char, spec->n_rpadding);
+ buf += spec->n_rpadding;
}
- return p_digits;
}
-#endif /* FORMAT_FLOAT || FORMAT_LONG */
+
+static char no_grouping[1] = {CHAR_MAX};
+
+/* Find the decimal point character(s?), thousands_separator(s?), and
+ grouping description, either for the current locale if type is
+ LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or
+ none if LT_NO_LOCALE. */
+static void
+get_locale_info(int type, LocaleInfo *locale_info)
+{
+ switch (type) {
+ case LT_CURRENT_LOCALE: {
+ struct lconv *locale_data = localeconv();
+ locale_info->decimal_point = locale_data->decimal_point;
+ locale_info->thousands_sep = locale_data->thousands_sep;
+ locale_info->grouping = locale_data->grouping;
+ break;
+ }
+ case LT_DEFAULT_LOCALE:
+ locale_info->decimal_point = ".";
+ locale_info->thousands_sep = ",";
+ locale_info->grouping = "\3"; /* Group every 3 characters. The
+ (implicit) trailing 0 means repeat
+ infinitely. */
+ break;
+ case LT_NO_LOCALE:
+ locale_info->decimal_point = ".";
+ locale_info->thousands_sep = "";
+ locale_info->grouping = no_grouping;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+#endif /* FORMAT_FLOAT || FORMAT_LONG || FORMAT_COMPLEX */
/************************************************************************/
/*********** string formatting ******************************************/
@@ -402,10 +672,10 @@ fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec,
static PyObject *
format_string_internal(PyObject *value, const InternalFormatSpec *format)
{
- Py_ssize_t width; /* total field width */
Py_ssize_t lpad;
- STRINGLIB_CHAR *dst;
- STRINGLIB_CHAR *src = STRINGLIB_STR(value);
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+ STRINGLIB_CHAR *p;
Py_ssize_t len = STRINGLIB_LEN(value);
PyObject *result = NULL;
@@ -438,56 +708,20 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format)
len = format->precision;
}
- if (format->width >= 0) {
- width = format->width;
-
- /* but use at least len characters */
- if (len > width) {
- width = len;
- }
- }
- else {
- /* not specified, use all of the chars and no more */
- width = len;
- }
+ calc_padding(len, format->width, format->align, &lpad, &rpad, &total);
/* allocate the resulting string */
- result = STRINGLIB_NEW(NULL, width);
+ result = STRINGLIB_NEW(NULL, total);
if (result == NULL)
goto done;
- /* now write into that space */
- dst = STRINGLIB_STR(result);
+ /* Write into that space. First the padding. */
+ p = fill_padding(STRINGLIB_STR(result), len,
+ format->fill_char=='\0'?' ':format->fill_char,
+ lpad, rpad);
- /* figure out how much leading space we need, based on the
- aligning */
- if (format->align == '>')
- lpad = width - len;
- else if (format->align == '^')
- lpad = (width - len) / 2;
- else
- lpad = 0;
-
- /* if right aligning, increment the destination allow space on the
- left */
- memcpy(dst + lpad, src, len * sizeof(STRINGLIB_CHAR));
-
- /* do any padding */
- if (width > len) {
- STRINGLIB_CHAR fill_char = format->fill_char;
- if (fill_char == '\0') {
- /* use the default, if not specified */
- fill_char = ' ';
- }
-
- /* pad on left */
- if (lpad)
- STRINGLIB_FILL(dst, fill_char, lpad);
-
- /* pad on right */
- if (width - len - lpad)
- STRINGLIB_FILL(dst + len + lpad, fill_char, width - len - lpad);
- }
+ /* Then the source string. */
+ memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR));
done:
return result;
@@ -510,19 +744,21 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
PyObject *tmp = NULL;
STRINGLIB_CHAR *pnumeric_chars;
STRINGLIB_CHAR numeric_char;
- STRINGLIB_CHAR sign = '\0';
- STRINGLIB_CHAR *p;
+ STRINGLIB_CHAR sign_char = '\0';
Py_ssize_t n_digits; /* count of digits need from the computed
string */
- Py_ssize_t n_leading_chars;
- Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to
- allocate, used for 'n'
- formatting. */
+ Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which
+ produces non-digits */
Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */
+ Py_ssize_t n_total;
STRINGLIB_CHAR *prefix = NULL;
NumberFieldWidths spec;
long x;
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale;
+
/* no precision allowed on integers */
if (format->precision != -1) {
PyErr_SetString(PyExc_ValueError,
@@ -530,7 +766,6 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
goto done;
}
-
/* special case for character formatting */
if (format->type == 'c') {
/* error to specify a sign */
@@ -541,6 +776,14 @@ 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 */
@@ -565,6 +808,13 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
numeric_char = (STRINGLIB_CHAR)x;
pnumeric_chars = &numeric_char;
n_digits = 1;
+
+ /* As a sort-of hack, we tell calc_number_widths that we only
+ have "remainder" characters. calc_number_widths thinks
+ these are characters that don't get formatted, only copied
+ into the output string. We do this for 'c' formatting,
+ because the characters are likely to be non-digits. */
+ n_remainder = 1;
}
else {
int base;
@@ -616,8 +866,8 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
/* Is a sign character present in the output? If so, remember it
and skip it */
- sign = pnumeric_chars[0];
- if (sign == '-') {
+ if (pnumeric_chars[0] == '-') {
+ sign_char = pnumeric_chars[0];
++prefix;
++leading_chars_to_skip;
}
@@ -627,70 +877,26 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
pnumeric_chars += leading_chars_to_skip;
}
- if (format->type == 'n')
- /* Compute how many additional chars we need to allocate
- to hold the thousands grouping. */
- STRINGLIB_GROUPING(NULL, n_digits, n_digits,
- 0, &n_grouping_chars, 0);
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
- /* Calculate the widths of the various leading and trailing parts */
- calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars,
- format);
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars,
+ n_digits, n_remainder, 0, &locale, format);
- /* Allocate a new string to hold the result */
- result = STRINGLIB_NEW(NULL, spec.n_total);
+ /* Allocate the memory. */
+ result = STRINGLIB_NEW(NULL, n_total);
if (!result)
goto done;
- p = STRINGLIB_STR(result);
-
- /* XXX There is too much magic here regarding the internals of
- spec and the location of the prefix and digits. It would be
- better if calc_number_widths returned a number of logical
- offsets into the buffer, and those were used. Maybe in a
- future code cleanup. */
-
- /* Fill in the digit parts */
- n_leading_chars = spec.n_lpadding + spec.n_lsign +
- spec.n_prefix + spec.n_spadding;
- memmove(p + n_leading_chars,
- pnumeric_chars,
- n_digits * sizeof(STRINGLIB_CHAR));
-
- /* If type is 'X', convert the filled in digits to uppercase */
- if (format->type == 'X') {
- Py_ssize_t t;
- for (t = 0; t < n_digits; ++t)
- p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]);
- }
-
- /* Insert the grouping, if any, after the uppercasing of the digits, so
- we can ensure that grouping chars won't be affected. */
- if (n_grouping_chars) {
- /* We know this can't fail, since we've already
- reserved enough space. */
- STRINGLIB_CHAR *pstart = p + n_leading_chars;
-#ifndef NDEBUG
- int r =
-#endif
- STRINGLIB_GROUPING(pstart, n_digits, n_digits,
- spec.n_total+n_grouping_chars-n_leading_chars,
- NULL, 0);
- assert(r);
- }
-
- /* Fill in the non-digit parts (padding, sign, etc.) */
- fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars,
- format->fill_char == '\0' ? ' ' : format->fill_char);
-
- /* If type is 'X', uppercase the prefix. This has to be done after the
- prefix is filled in by fill_non_digits */
- if (format->type == 'X') {
- Py_ssize_t t;
- for (t = 0; t < n_prefix; ++t)
- p[t + spec.n_lpadding + spec.n_lsign] =
- STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]);
- }
+ /* Populate the memory. */
+ fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits,
+ prefix, format->fill_char == '\0' ? ' ' : format->fill_char,
+ &locale, format->type == 'X');
done:
Py_XDECREF(tmp);
@@ -704,64 +910,46 @@ done:
#ifdef FORMAT_FLOAT
#if STRINGLIB_IS_UNICODE
-/* taken from unicodeobject.c */
-static Py_ssize_t
-strtounicode(Py_UNICODE *buffer, const char *charbuffer)
+static void
+strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len)
{
- register Py_ssize_t i;
- Py_ssize_t len = strlen(charbuffer);
- for (i = len - 1; i >= 0; --i)
- buffer[i] = (Py_UNICODE) charbuffer[i];
-
- return len;
+ Py_ssize_t i;
+ for (i = 0; i < len; ++i)
+ buffer[i] = (Py_UNICODE)charbuffer[i];
}
#endif
-/* see FORMATBUFLEN in unicodeobject.c */
-#define FLOAT_FORMATBUFLEN 120
-
/* much of this is taken from unicodeobject.c */
static PyObject *
format_float_internal(PyObject *value,
const InternalFormatSpec *format)
{
- /* fmt = '%.' + `prec` + `type` + '%%'
- worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/
- char fmt[20];
-
- /* taken from unicodeobject.c */
- /* Worst case length calc to ensure no buffer overrun:
-
- 'g' formats:
- fmt = %#.<prec>g
- buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
- for any double rep.)
- len = 1 + prec + 1 + 2 + 5 = 9 + prec
-
- 'f' formats:
- buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
- len = 1 + 50 + 1 + prec = 52 + prec
-
- If prec=0 the effective precision is 1 (the leading digit is
- always given), therefore increase the length by one.
-
- */
- char charbuf[FLOAT_FORMATBUFLEN];
+ char *buf = NULL; /* buffer returned from PyOS_double_to_string */
Py_ssize_t n_digits;
- double x;
+ Py_ssize_t n_remainder;
+ Py_ssize_t n_total;
+ int has_decimal;
+ double val;
Py_ssize_t precision = format->precision;
- PyObject *result = NULL;
- STRINGLIB_CHAR sign;
- char* trailing = "";
+ Py_ssize_t default_precision = 6;
+ STRINGLIB_CHAR type = format->type;
+ int add_pct = 0;
STRINGLIB_CHAR *p;
NumberFieldWidths spec;
- STRINGLIB_CHAR type = format->type;
+ int flags = 0;
+ PyObject *result = NULL;
+ STRINGLIB_CHAR sign_char = '\0';
+ int float_type; /* Used to see if we have a nan, inf, or regular float. */
#if STRINGLIB_IS_UNICODE
- Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN];
+ Py_UNICODE *unicode_tmp = NULL;
#endif
- /* alternate is not allowed on floats. */
+ /* Locale settings, either from the actual locale or
+ 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 "
@@ -769,89 +957,333 @@ format_float_internal(PyObject *value,
goto done;
}
- /* first, do the conversion as 8-bit chars, using the platform's
- snprintf. then, if needed, convert to unicode. */
-
- /* 'F' is the same as 'f', per the PEP */
- if (type == 'F')
- type = 'f';
+ if (type == '\0') {
+ /* Omitted type specifier. This is like 'g' but with at least one
+ digit after the decimal point, and different default precision.*/
+ type = 'g';
+ default_precision = PyFloat_STR_PRECISION;
+ flags |= Py_DTSF_ADD_DOT_0;
+ }
- x = PyFloat_AsDouble(value);
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
- if (x == -1.0 && PyErr_Occurred())
+ val = PyFloat_AsDouble(value);
+ if (val == -1.0 && PyErr_Occurred())
goto done;
if (type == '%') {
type = 'f';
- x *= 100;
- trailing = "%";
+ val *= 100;
+ add_pct = 1;
}
if (precision < 0)
- precision = 6;
- if (type == 'f' && fabs(x) >= 1e50)
- type = 'g';
+ precision = default_precision;
+
+ /* Cast "type", because if we're in unicode we need to pass a
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ buf = PyOS_double_to_string(val, (char)type, precision, flags,
+ &float_type);
+ if (buf == NULL)
+ goto done;
+ n_digits = strlen(buf);
+
+ if (add_pct) {
+ /* We know that buf has a trailing zero (since we just called
+ strlen() on it), and we don't use that fact any more. So we
+ can just write over the trailing zero. */
+ buf[n_digits] = '%';
+ n_digits += 1;
+ }
- /* 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 */
- PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision,
- (char)type);
-
- /* do the actual formatting */
- PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x);
-
- /* adding trailing to fmt with PyOS_snprintf doesn't work, not
- sure why. we'll just concatentate it here, no harm done. we
- know we can't have a buffer overflow from the fmt size
- analysis */
- strcat(charbuf, trailing);
-
- /* rather than duplicate the code for snprintf for both unicode
- and 8 bit strings, we just use the 8 bit version and then
- convert to unicode in a separate code path. that's probably
- the lesser of 2 evils. */
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
#if STRINGLIB_IS_UNICODE
- n_digits = strtounicode(unicodebuf, charbuf);
- p = unicodebuf;
+ unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE));
+ if (unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(unicode_tmp, buf, n_digits);
+ p = unicode_tmp;
#else
- /* compute the length. I believe this is done because the return
- value from snprintf above is unreliable */
- n_digits = strlen(charbuf);
- p = charbuf;
+ p = buf;
#endif
- /* is a sign character present in the output? if so, remember it
+ /* Is a sign character present in the output? If so, remember it
and skip it */
- sign = p[0];
- if (sign == '-') {
+ if (*p == '-') {
+ sign_char = *p;
++p;
--n_digits;
}
- calc_number_widths(&spec, sign, 0, n_digits, format);
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(p, n_digits, &n_remainder, &has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
- /* allocate a string with enough space */
- result = STRINGLIB_NEW(NULL, spec.n_total);
+ /* Calculate how much memory we'll need. */
+ n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits,
+ n_remainder, has_decimal, &locale, format);
+
+ /* Allocate the memory. */
+ result = STRINGLIB_NEW(NULL, n_total);
if (result == NULL)
goto done;
- /* Fill in the non-digit parts (padding, sign, etc.) */
- fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits,
- format->fill_char == '\0' ? ' ' : format->fill_char);
-
- /* fill in the digit parts */
- memmove(STRINGLIB_STR(result) +
- (spec.n_lpadding + spec.n_lsign + spec.n_spadding),
- p,
- n_digits * sizeof(STRINGLIB_CHAR));
+ /* Populate the memory. */
+ fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL,
+ format->fill_char == '\0' ? ' ' : format->fill_char, &locale,
+ 0);
done:
+ PyMem_Free(buf);
+#if STRINGLIB_IS_UNICODE
+ PyMem_Free(unicode_tmp);
+#endif
return result;
}
#endif /* FORMAT_FLOAT */
/************************************************************************/
+/*********** complex formatting *****************************************/
+/************************************************************************/
+
+#ifdef FORMAT_COMPLEX
+
+static PyObject *
+format_complex_internal(PyObject *value,
+ const InternalFormatSpec *format)
+{
+ double re;
+ double im;
+ char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */
+ char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */
+
+ InternalFormatSpec tmp_format = *format;
+ Py_ssize_t n_re_digits;
+ Py_ssize_t n_im_digits;
+ Py_ssize_t n_re_remainder;
+ Py_ssize_t n_im_remainder;
+ Py_ssize_t n_re_total;
+ Py_ssize_t n_im_total;
+ int re_has_decimal;
+ int im_has_decimal;
+ Py_ssize_t precision = format->precision;
+ Py_ssize_t default_precision = 6;
+ STRINGLIB_CHAR type = format->type;
+ STRINGLIB_CHAR *p_re;
+ STRINGLIB_CHAR *p_im;
+ NumberFieldWidths re_spec;
+ NumberFieldWidths im_spec;
+ int flags = 0;
+ PyObject *result = NULL;
+ STRINGLIB_CHAR *p;
+ STRINGLIB_CHAR re_sign_char = '\0';
+ STRINGLIB_CHAR im_sign_char = '\0';
+ int re_float_type; /* Used to see if we have a nan, inf, or regular float. */
+ int im_float_type;
+ int add_parens = 0;
+ int skip_re = 0;
+ Py_ssize_t lpad;
+ Py_ssize_t rpad;
+ Py_ssize_t total;
+
+#if STRINGLIB_IS_UNICODE
+ Py_UNICODE *re_unicode_tmp = NULL;
+ Py_UNICODE *im_unicode_tmp = NULL;
+#endif
+
+ /* Locale settings, either from the actual locale or
+ from a hard-code pseudo-locale */
+ LocaleInfo locale;
+
+ /* Alternate is not allowed on complex. */
+ if (format->alternate) {
+ PyErr_SetString(PyExc_ValueError,
+ "Alternate form (#) not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ /* Neither is zero pading. */
+ if (format->fill_char == '0') {
+ PyErr_SetString(PyExc_ValueError,
+ "Zero padding is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ /* Neither is '=' alignment . */
+ if (format->align == '=') {
+ PyErr_SetString(PyExc_ValueError,
+ "'=' alignment flag is not allowed in complex format "
+ "specifier");
+ goto done;
+ }
+
+ re = PyComplex_RealAsDouble(value);
+ if (re == -1.0 && PyErr_Occurred())
+ goto done;
+ im = PyComplex_ImagAsDouble(value);
+ if (im == -1.0 && PyErr_Occurred())
+ goto done;
+
+ if (type == '\0') {
+ /* Omitted type specifier. Should be like str(self). */
+ type = 'g';
+ default_precision = PyFloat_STR_PRECISION;
+ if (re == 0.0 && copysign(1.0, re) == 1.0)
+ skip_re = 1;
+ else
+ add_parens = 1;
+ }
+
+ if (type == 'n')
+ /* 'n' is the same as 'g', except for the locale used to
+ format the result. We take care of that later. */
+ type = 'g';
+
+ if (precision < 0)
+ precision = default_precision;
+
+ /* Cast "type", because if we're in unicode we need to pass a
+ 8-bit char. This is safe, because we've restricted what "type"
+ can be. */
+ re_buf = PyOS_double_to_string(re, (char)type, precision, flags,
+ &re_float_type);
+ if (re_buf == NULL)
+ goto done;
+ im_buf = PyOS_double_to_string(im, (char)type, precision, flags,
+ &im_float_type);
+ if (im_buf == NULL)
+ goto done;
+
+ n_re_digits = strlen(re_buf);
+ n_im_digits = strlen(im_buf);
+
+ /* Since there is no unicode version of PyOS_double_to_string,
+ just use the 8 bit version and then convert to unicode. */
+#if STRINGLIB_IS_UNICODE
+ re_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_re_digits)*sizeof(Py_UNICODE));
+ if (re_unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(re_unicode_tmp, re_buf, n_re_digits);
+ p_re = re_unicode_tmp;
+
+ im_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_im_digits)*sizeof(Py_UNICODE));
+ if (im_unicode_tmp == NULL) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ strtounicode(im_unicode_tmp, im_buf, n_im_digits);
+ p_im = im_unicode_tmp;
+#else
+ p_re = re_buf;
+ p_im = im_buf;
+#endif
+
+ /* Is a sign character present in the output? If so, remember it
+ and skip it */
+ if (*p_re == '-') {
+ re_sign_char = *p_re;
+ ++p_re;
+ --n_re_digits;
+ }
+ if (*p_im == '-') {
+ im_sign_char = *p_im;
+ ++p_im;
+ --n_im_digits;
+ }
+
+ /* Determine if we have any "remainder" (after the digits, might include
+ decimal or exponent or both (or neither)) */
+ parse_number(p_re, n_re_digits, &n_re_remainder, &re_has_decimal);
+ parse_number(p_im, n_im_digits, &n_im_remainder, &im_has_decimal);
+
+ /* Determine the grouping, separator, and decimal point, if any. */
+ get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE :
+ (format->thousands_separators ?
+ LT_DEFAULT_LOCALE :
+ LT_NO_LOCALE),
+ &locale);
+
+ /* Turn off any padding. We'll do it later after we've composed
+ the numbers without padding. */
+ tmp_format.fill_char = '\0';
+ tmp_format.align = '<';
+ tmp_format.width = -1;
+
+ /* Calculate how much memory we'll need. */
+ n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, p_re,
+ n_re_digits, n_re_remainder,
+ re_has_decimal, &locale, &tmp_format);
+
+ /* Same formatting, but always include a sign, unless the real part is
+ * going to be omitted, in which case we use whatever sign convention was
+ * requested by the original format. */
+ if (!skip_re)
+ tmp_format.sign = '+';
+ n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im,
+ n_im_digits, n_im_remainder,
+ im_has_decimal, &locale, &tmp_format);
+
+ if (skip_re)
+ n_re_total = 0;
+
+ /* Add 1 for the 'j', and optionally 2 for parens. */
+ calc_padding(n_re_total + n_im_total + 1 + add_parens * 2,
+ format->width, format->align, &lpad, &rpad, &total);
+
+ result = STRINGLIB_NEW(NULL, total);
+ if (result == NULL)
+ goto done;
+
+ /* Populate the memory. First, the padding. */
+ p = fill_padding(STRINGLIB_STR(result),
+ n_re_total + n_im_total + 1 + add_parens * 2,
+ format->fill_char=='\0' ? ' ' : format->fill_char,
+ lpad, rpad);
+
+ if (add_parens)
+ *p++ = '(';
+
+ if (!skip_re) {
+ fill_number(p, &re_spec, p_re, n_re_digits, NULL, 0, &locale, 0);
+ p += n_re_total;
+ }
+ fill_number(p, &im_spec, p_im, n_im_digits, NULL, 0, &locale, 0);
+ p += n_im_total;
+ *p++ = 'j';
+
+ if (add_parens)
+ *p++ = ')';
+
+done:
+ PyMem_Free(re_buf);
+ PyMem_Free(im_buf);
+#if STRINGLIB_IS_UNICODE
+ PyMem_Free(re_unicode_tmp);
+ PyMem_Free(im_unicode_tmp);
+#endif
+ return result;
+}
+#endif /* FORMAT_COMPLEX */
+
+/************************************************************************/
/*********** built in formatters ****************************************/
/************************************************************************/
PyObject *
@@ -871,7 +1303,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? */
@@ -911,7 +1343,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? */
@@ -1022,16 +1454,12 @@ 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? */
switch (format.type) {
- case '\0':
- /* 'Z' means like 'g', but with at least one decimal. See
- PyOS_ascii_formatd */
- format.type = 'Z';
- /* Deliberate fall through to the next case statement */
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
case 'e':
case 'E':
case 'f':
@@ -1054,3 +1482,50 @@ done:
return result;
}
#endif /* FORMAT_FLOAT */
+
+#ifdef FORMAT_COMPLEX
+PyObject *
+FORMAT_COMPLEX(PyObject *obj,
+ STRINGLIB_CHAR *format_spec,
+ Py_ssize_t format_spec_len)
+{
+ PyObject *result = NULL;
+ InternalFormatSpec format;
+
+ /* check for the special case of zero length format spec, make
+ it equivalent to str(obj) */
+ if (format_spec_len == 0) {
+ result = STRINGLIB_TOSTR(obj);
+ goto done;
+ }
+
+ /* parse the format_spec */
+ if (!parse_internal_render_format_spec(format_spec,
+ format_spec_len,
+ &format, '\0', '>'))
+ goto done;
+
+ /* type conversion? */
+ switch (format.type) {
+ case '\0': /* No format code: like 'g', but with at least one decimal. */
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'n':
+ /* no conversion, already a complex. do the formatting */
+ result = format_complex_internal(obj, &format);
+ break;
+
+ default:
+ /* unknown */
+ unknown_presentation_type(format.type, obj->ob_type->tp_name);
+ goto done;
+ }
+
+done:
+ return result;
+}
+#endif /* FORMAT_COMPLEX */
diff --git a/Objects/stringlib/localeutil.h b/Objects/stringlib/localeutil.h
index 9730c6714f..f548133875 100644
--- a/Objects/stringlib/localeutil.h
+++ b/Objects/stringlib/localeutil.h
@@ -5,126 +5,208 @@
#include <locale.h>
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+typedef struct {
+ const char *grouping;
+ char previous;
+ Py_ssize_t i; /* Where we're currently pointing in grouping. */
+} GroupGenerator;
+
+static void
+_GroupGenerator_init(GroupGenerator *self, const char *grouping)
+{
+ self->grouping = grouping;
+ self->i = 0;
+ self->previous = 0;
+}
+
+/* Returns the next grouping, or 0 to signify end. */
+static Py_ssize_t
+_GroupGenerator_next(GroupGenerator *self)
+{
+ /* Note that we don't really do much error checking here. If a
+ grouping string contains just CHAR_MAX, for example, then just
+ terminate the generator. That shouldn't happen, but at least we
+ fail gracefully. */
+ switch (self->grouping[self->i]) {
+ case 0:
+ return self->previous;
+ case CHAR_MAX:
+ /* Stop the generator. */
+ return 0;
+ default: {
+ char ch = self->grouping[self->i];
+ self->previous = ch;
+ self->i++;
+ return (Py_ssize_t)ch;
+ }
+ }
+}
+
+/* Fill in some digits, leading zeros, and thousands separator. All
+ are optional, depending on when we're called. */
+static void
+fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
+ Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,
+ Py_ssize_t thousands_sep_len)
+{
+#if STRINGLIB_IS_UNICODE
+ Py_ssize_t i;
+#endif
+
+ if (thousands_sep) {
+ *buffer_end -= thousands_sep_len;
+
+ /* Copy the thousands_sep chars into the buffer. */
+#if STRINGLIB_IS_UNICODE
+ /* Convert from the char's of the thousands_sep from
+ the locale into unicode. */
+ for (i = 0; i < thousands_sep_len; ++i)
+ (*buffer_end)[i] = thousands_sep[i];
+#else
+ /* No conversion, just memcpy the thousands_sep. */
+ memcpy(*buffer_end, thousands_sep, thousands_sep_len);
+#endif
+ }
+
+ *buffer_end -= n_chars;
+ *digits_end -= n_chars;
+ memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR));
+
+ *buffer_end -= n_zeros;
+ STRINGLIB_FILL(*buffer_end, '0', n_zeros);
+}
+
/**
* _Py_InsertThousandsGrouping:
* @buffer: A pointer to the start of a string.
- * @n_buffer: The length of the string.
+ * @n_buffer: Number of characters in @buffer.
+ * @digits: A pointer to the digits we're reading from. If count
+ * is non-NULL, this is unused.
* @n_digits: The number of digits in the string, in which we want
* to put the grouping chars.
- * @buf_size: The maximum size of the buffer pointed to by buffer.
- * @count: If non-NULL, points to a variable that will receive the
- * number of characters we need to insert (and no formatting
- * will actually occur).
- * @append_zero_char: If non-zero, put a trailing zero at the end of
- * of the resulting string, if and only if we modified the
- * string.
+ * @min_width: The minimum width of the digits in the output string.
+ * Output will be zero-padded on the left to fill.
+ * @grouping: see definition in localeconv().
+ * @thousands_sep: see definition in localeconv().
*
- * Inserts thousand grouping characters (as defined in the current
- * locale) into the string between buffer and buffer+n_digits. If
- * count is non-NULL, don't do any formatting, just count the number
- * of characters to insert. This is used by the caller to
- * appropriately resize the buffer, if needed. If count is non-NULL,
- * buffer can be NULL (it is not dereferenced at all in that case).
+ * There are 2 modes: counting and filling. If @buffer is NULL,
+ * we are in counting mode, else filling mode.
+ * If counting, the required buffer size is returned.
+ * If filling, we know the buffer will be large enough, so we don't
+ * need to pass in the buffer size.
+ * Inserts thousand grouping characters (as defined by grouping and
+ * thousands_sep) into the string between buffer and buffer+n_digits.
*
* Return value: 0 on error, else 1. Note that no error can occur if
* count is non-NULL.
*
* This name won't be used, the includer of this file should define
* it to be the actual function name, based on unicode or string.
+ *
+ * As closely as possible, this code mimics the logic in decimal.py's
+ _insert_thousands_sep().
**/
-int
+Py_ssize_t
_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
Py_ssize_t n_buffer,
+ STRINGLIB_CHAR *digits,
Py_ssize_t n_digits,
- Py_ssize_t buf_size,
- Py_ssize_t *count,
- int append_zero_char)
+ Py_ssize_t min_width,
+ const char *grouping,
+ const char *thousands_sep)
{
- struct lconv *locale_data = localeconv();
- const char *grouping = locale_data->grouping;
- const char *thousands_sep = locale_data->thousands_sep;
+ Py_ssize_t count = 0;
+ Py_ssize_t n_zeros;
+ int loop_broken = 0;
+ int use_separator = 0; /* First time through, don't append the
+ separator. They only go between
+ groups. */
+ STRINGLIB_CHAR *buffer_end = NULL;
+ STRINGLIB_CHAR *digits_end = NULL;
+ Py_ssize_t l;
+ Py_ssize_t n_chars;
Py_ssize_t thousands_sep_len = strlen(thousands_sep);
- STRINGLIB_CHAR *pend = NULL; /* current end of buffer */
- STRINGLIB_CHAR *pmax = NULL; /* max of buffer */
- char current_grouping;
Py_ssize_t remaining = n_digits; /* Number of chars remaining to
be looked at */
+ /* A generator that returns all of the grouping widths, until it
+ returns 0. */
+ GroupGenerator groupgen;
+ _GroupGenerator_init(&groupgen, grouping);
- /* Initialize the character count, if we're just counting. */
- if (count)
- *count = 0;
- else {
- /* We're not just counting, we're modifying buffer */
- pend = buffer + n_buffer;
- pmax = buffer + buf_size;
+ if (buffer) {
+ buffer_end = buffer + n_buffer;
+ digits_end = digits + n_digits;
}
- /* Starting at the end and working right-to-left, keep track of
- what grouping needs to be added and insert that. */
- current_grouping = *grouping++;
+ while ((l = _GroupGenerator_next(&groupgen)) > 0) {
+ l = MIN(l, MAX(MAX(remaining, min_width), 1));
+ n_zeros = MAX(0, l - remaining);
+ n_chars = MAX(0, MIN(remaining, l));
- /* If the first character is 0, perform no grouping at all. */
- if (current_grouping == 0)
- return 1;
+ /* Use n_zero zero's and n_chars chars */
- while (remaining > current_grouping) {
- /* Always leave buffer and pend valid at the end of this
- loop, since we might leave with a return statement. */
+ /* Count only, don't do anything. */
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
- remaining -= current_grouping;
- if (count) {
- /* We're only counting, not touching the memory. */
- *count += thousands_sep_len;
+ if (buffer) {
+ /* Copy into the output buffer. */
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,
+ use_separator ? thousands_sep : NULL, thousands_sep_len);
}
- else {
- /* Do the formatting. */
- STRINGLIB_CHAR *plast = buffer + remaining;
+ /* Use a separator next time. */
+ use_separator = 1;
- /* Is there room to insert thousands_sep_len chars? */
- if (pmax - pend < thousands_sep_len)
- /* No room. */
- return 0;
+ remaining -= n_chars;
+ min_width -= l;
- /* Move the rest of the string down. */
- memmove(plast + thousands_sep_len,
- plast,
- (pend - plast) * sizeof(STRINGLIB_CHAR));
- /* Copy the thousands_sep chars into the buffer. */
-#if STRINGLIB_IS_UNICODE
- /* Convert from the char's of the thousands_sep from
- the locale into unicode. */
- {
- Py_ssize_t i;
- for (i = 0; i < thousands_sep_len; ++i)
- plast[i] = thousands_sep[i];
- }
-#else
- /* No conversion, just memcpy the thousands_sep. */
- memcpy(plast, thousands_sep, thousands_sep_len);
-#endif
+ if (remaining <= 0 && min_width <= 0) {
+ loop_broken = 1;
+ break;
}
+ min_width -= thousands_sep_len;
+ }
+ if (!loop_broken) {
+ /* We left the loop without using a break statement. */
- /* Adjust end pointer. */
- pend += thousands_sep_len;
+ l = MAX(MAX(remaining, min_width), 1);
+ n_zeros = MAX(0, l - remaining);
+ n_chars = MAX(0, MIN(remaining, l));
- /* Move to the next grouping character, unless we're
- repeating (which is designated by a grouping of 0). */
- if (*grouping != 0) {
- current_grouping = *grouping++;
- if (current_grouping == CHAR_MAX)
- /* We're done. */
- break;
+ /* Use n_zero zero's and n_chars chars */
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
+ if (buffer) {
+ /* Copy into the output buffer. */
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,
+ use_separator ? thousands_sep : NULL, thousands_sep_len);
}
}
- if (append_zero_char) {
- /* Append a zero character to mark the end of the string,
- if there's room. */
- if (pend - (buffer + remaining) < 1)
- /* No room, error. */
- return 0;
- *pend = 0;
- }
- return 1;
+ return count;
+}
+
+/**
+ * _Py_InsertThousandsGroupingLocale:
+ * @buffer: A pointer to the start of a string.
+ * @n_digits: The number of digits in the string, in which we want
+ * to put the grouping chars.
+ *
+ * Reads thee current locale and calls _Py_InsertThousandsGrouping().
+ **/
+Py_ssize_t
+_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,
+ Py_ssize_t n_buffer,
+ STRINGLIB_CHAR *digits,
+ Py_ssize_t n_digits,
+ Py_ssize_t min_width)
+{
+ struct lconv *locale_data = localeconv();
+ const char *grouping = locale_data->grouping;
+ const char *thousands_sep = locale_data->thousands_sep;
+
+ return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,
+ min_width, grouping, thousands_sep);
}
#endif /* STRINGLIB_LOCALEUTIL_H */
diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h
index 20c75077b4..0170bddbf0 100644
--- a/Objects/stringlib/partition.h
+++ b/Objects/stringlib/partition.h
@@ -8,10 +8,10 @@
#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;
@@ -25,15 +25,21 @@ stringlib_partition(
if (!out)
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) {
+#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;
}
@@ -52,13 +58,13 @@ stringlib_partition(
}
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, j;
+ Py_ssize_t pos;
if (sep_len == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
@@ -69,21 +75,21 @@ 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, -1, FAST_RSEARCH);
if (pos < 0) {
+#if STRINGLIB_MUTABLE
+ PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
+ PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
+ PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
+#else
Py_INCREF(STRINGLIB_EMPTY);
PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
Py_INCREF(STRINGLIB_EMPTY);
PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
Py_INCREF(str_obj);
PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
+#endif
return out;
}
@@ -102,10 +108,3 @@ stringlib_rpartition(
}
#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..60e77674f0
--- /dev/null
+++ b/Objects/stringlib/split.h
@@ -0,0 +1,394 @@
+/* stringlib: split implementation */
+
+#ifndef STRINGLIB_SPLIT_H
+#define STRINGLIB_SPLIT_H
+
+#ifndef STRINGLIB_FASTSEARCH_H
+#error must include "stringlib/fastsearch.h" before including this module
+#endif
+
+/* Overallocate the initial list to reduce the number of reallocs for small
+ split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
+ resizes, to sizes 4, 8, then 16. Most observed string splits are for human
+ text (roughly 11 words per line) and field delimited data (usually 1-10
+ fields). For large strings the split algorithms are bandwidth limited
+ so increasing the preallocation likely will not improve things.*/
+
+#define MAX_PREALLOC 12
+
+/* 5 splits gives 6 elements */
+#define PREALLOC_SIZE(maxsplit) \
+ (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
+
+#define SPLIT_APPEND(data, left, right) \
+ sub = STRINGLIB_NEW((data) + (left), \
+ (right) - (left)); \
+ if (sub == NULL) \
+ goto onError; \
+ if (PyList_Append(list, sub)) { \
+ Py_DECREF(sub); \
+ goto onError; \
+ } \
+ else \
+ Py_DECREF(sub);
+
+#define SPLIT_ADD(data, left, right) { \
+ sub = STRINGLIB_NEW((data) + (left), \
+ (right) - (left)); \
+ if (sub == NULL) \
+ goto onError; \
+ if (count < MAX_PREALLOC) { \
+ PyList_SET_ITEM(list, count, sub); \
+ } else { \
+ if (PyList_Append(list, sub)) { \
+ Py_DECREF(sub); \
+ goto onError; \
+ } \
+ else \
+ Py_DECREF(sub); \
+ } \
+ count++; }
+
+
+/* Always force the list to the expected size. */
+#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_whitespace(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while (maxcount-- > 0) {
+ while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+ i++;
+ if (i == str_len) break;
+ j = i; i++;
+ while (i < str_len && !STRINGLIB_ISSPACE(str[i]))
+ i++;
+#ifndef STRINGLIB_MUTABLE
+ if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No whitespace in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ break;
+ }
+#endif
+ SPLIT_ADD(str, j, i);
+ }
+
+ if (i < str_len) {
+ /* Only occurs when maxcount was reached */
+ /* Skip any remaining whitespace and copy to end of string */
+ while (i < str_len && STRINGLIB_ISSPACE(str[i]))
+ i++;
+ if (i != str_len)
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split_char(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR ch,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while ((j < str_len) && (maxcount-- > 0)) {
+ for(; j < str_len; j++) {
+ /* I found that using memchr makes no difference */
+ if (str[j] == ch) {
+ SPLIT_ADD(str, i, j);
+ i = j = j + 1;
+ break;
+ }
+ }
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* ch not in str_obj, so just use str_obj as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ if (i <= str_len) {
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_split(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, pos, count=0;
+ PyObject *list, *sub;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+ else if (sep_len == 1)
+ return stringlib_split_char(str_obj, str, str_len, sep[0], maxcount);
+
+ list = PyList_New(PREALLOC_SIZE(maxcount));
+ if (list == NULL)
+ return NULL;
+
+ i = j = 0;
+ while (maxcount-- > 0) {
+ pos = fastsearch(str+i, str_len-i, sep, sep_len, -1, FAST_SEARCH);
+ if (pos < 0)
+ break;
+ j = i + pos;
+ SPLIT_ADD(str, i, j);
+ i = j + sep_len;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No match in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ {
+ SPLIT_ADD(str, i, str_len);
+ }
+ FIX_PREALLOC_SIZE(list);
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_whitespace(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = str_len - 1;
+ while (maxcount-- > 0) {
+ while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+ i--;
+ if (i < 0) break;
+ j = i; i--;
+ while (i >= 0 && !STRINGLIB_ISSPACE(str[i]))
+ i--;
+#ifndef STRINGLIB_MUTABLE
+ if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No whitespace in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ break;
+ }
+#endif
+ SPLIT_ADD(str, i + 1, j + 1);
+ }
+
+ if (i >= 0) {
+ /* Only occurs when maxcount was reached */
+ /* Skip any remaining whitespace and copy to beginning of string */
+ while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
+ i--;
+ if (i >= 0)
+ SPLIT_ADD(str, 0, i + 1);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit_char(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR ch,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t i, j, count=0;
+ PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ i = j = str_len - 1;
+ while ((i >= 0) && (maxcount-- > 0)) {
+ for(; i >= 0; i--) {
+ if (str[i] == ch) {
+ SPLIT_ADD(str, i + 1, j + 1);
+ j = i = i - 1;
+ break;
+ }
+ }
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* ch not in str_obj, so just use str_obj as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ if (j >= -1) {
+ SPLIT_ADD(str, 0, j + 1);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_rsplit(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
+ Py_ssize_t maxcount)
+{
+ Py_ssize_t j, pos, count=0;
+ PyObject *list, *sub;
+
+ if (sep_len == 0) {
+ PyErr_SetString(PyExc_ValueError, "empty separator");
+ return NULL;
+ }
+ else if (sep_len == 1)
+ return stringlib_rsplit_char(str_obj, str, str_len, sep[0], maxcount);
+
+ list = PyList_New(PREALLOC_SIZE(maxcount));
+ if (list == NULL)
+ return NULL;
+
+ j = str_len;
+ while (maxcount-- > 0) {
+ pos = fastsearch(str, j, sep, sep_len, -1, FAST_RSEARCH);
+ if (pos < 0)
+ break;
+ SPLIT_ADD(str, pos + sep_len, j);
+ j = pos;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No match in str_obj, so just use it as list[0] */
+ Py_INCREF(str_obj);
+ PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
+ count++;
+ } else
+#endif
+ {
+ SPLIT_ADD(str, 0, j);
+ }
+ FIX_PREALLOC_SIZE(list);
+ if (PyList_Reverse(list) < 0)
+ goto onError;
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+Py_LOCAL_INLINE(PyObject *)
+stringlib_splitlines(PyObject* str_obj,
+ const STRINGLIB_CHAR* str, Py_ssize_t str_len,
+ int keepends)
+{
+ /* This does not use the preallocated list because splitlines is
+ usually run with hundreds of newlines. The overhead of
+ switching between PyList_SET_ITEM and append causes about a
+ 2-3% slowdown for that common case. A smarter implementation
+ could move the if check out, so the SET_ITEMs are done first
+ and the appends only done when the prealloc buffer is full.
+ That's too much work for little gain.*/
+
+ register Py_ssize_t i;
+ register Py_ssize_t j;
+ PyObject *list = PyList_New(0);
+ PyObject *sub;
+
+ if (list == NULL)
+ return NULL;
+
+ for (i = j = 0; i < str_len; ) {
+ Py_ssize_t eol;
+
+ /* Find a line and append it */
+ while (i < str_len && !STRINGLIB_ISLINEBREAK(str[i]))
+ i++;
+
+ /* Skip the line break reading CRLF as one line break */
+ eol = i;
+ if (i < str_len) {
+ if (str[i] == '\r' && i + 1 < str_len && str[i+1] == '\n')
+ i += 2;
+ else
+ i++;
+ if (keepends)
+ eol = i;
+ }
+#ifndef STRINGLIB_MUTABLE
+ if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
+ /* No linebreak in str_obj, so just use it as list[0] */
+ if (PyList_Append(list, str_obj))
+ goto onError;
+ break;
+ }
+#endif
+ SPLIT_APPEND(str, j, eol);
+ j = i;
+ }
+ return list;
+
+ onError:
+ Py_DECREF(list);
+ return NULL;
+}
+
+#endif
diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h
index 70438660d6..075fa1dee9 100644
--- a/Objects/stringlib/string_format.h
+++ b/Objects/stringlib/string_format.h
@@ -6,7 +6,7 @@
*/
-/* Defines for Python 2.6 compatability */
+/* Defines for Python 2.6 compatibility */
#if PY_VERSION_HEX < 0x03000000
#define PyLong_FromSsize_t _PyLong_FromSsize_t
#endif
@@ -31,10 +31,23 @@ typedef struct {
} SubString;
+typedef enum {
+ ANS_INIT,
+ ANS_AUTO,
+ ANS_MANUAL
+} AutoNumberState; /* Keep track if we're auto-numbering fields */
+
+/* Keeps track of our auto-numbering state, and which number field we're on */
+typedef struct {
+ AutoNumberState an_state;
+ int an_field_number;
+} AutoNumber;
+
+
/* forward declaration for recursion */
static PyObject *
build_string(SubString *input, PyObject *args, PyObject *kwargs,
- int recursion_depth);
+ int recursion_depth, AutoNumber *auto_number);
@@ -42,6 +55,13 @@ build_string(SubString *input, PyObject *args, PyObject *kwargs,
/************************** Utility functions ************************/
/************************************************************************/
+static void
+AutoNumber_Init(AutoNumber *auto_number)
+{
+ auto_number->an_state = ANS_INIT;
+ auto_number->an_field_number = 0;
+}
+
/* fill in a SubString from a pointer and length */
Py_LOCAL_INLINE(void)
SubString_init(SubString *str, STRINGLIB_CHAR *p, Py_ssize_t len)
@@ -74,6 +94,32 @@ SubString_new_object_or_empty(SubString *str)
return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
}
+/* Return 1 if an error has been detected switching between automatic
+ field numbering and manual field specification, else return 0. Set
+ ValueError on error. */
+static int
+autonumber_state_error(AutoNumberState state, int field_name_is_empty)
+{
+ if (state == ANS_MANUAL) {
+ if (field_name_is_empty) {
+ PyErr_SetString(PyExc_ValueError, "cannot switch from "
+ "manual field specification to "
+ "automatic field numbering");
+ return 1;
+ }
+ }
+ else {
+ if (!field_name_is_empty) {
+ PyErr_SetString(PyExc_ValueError, "cannot switch from "
+ "automatic field numbering to "
+ "manual field specification");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
/************************************************************************/
/*********** Output string management functions ****************/
/************************************************************************/
@@ -355,11 +401,14 @@ FieldNameIterator_next(FieldNameIterator *self, int *is_attribute,
*/
static int
field_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first,
- Py_ssize_t *first_idx, FieldNameIterator *rest)
+ Py_ssize_t *first_idx, FieldNameIterator *rest,
+ AutoNumber *auto_number)
{
STRINGLIB_CHAR c;
STRINGLIB_CHAR *p = ptr;
STRINGLIB_CHAR *end = ptr + len;
+ int field_name_is_empty;
+ int using_numeric_index;
/* find the part up until the first '.' or '[' */
while (p < end) {
@@ -385,15 +434,41 @@ field_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first,
if (*first_idx == -1 && PyErr_Occurred())
return 0;
- /* zero length string is an error */
- if (first->ptr >= first->end) {
- PyErr_SetString(PyExc_ValueError, "empty field name");
- goto error;
+ field_name_is_empty = first->ptr >= first->end;
+
+ /* If the field name is omitted or if we have a numeric index
+ specified, then we're doing numeric indexing into args. */
+ using_numeric_index = field_name_is_empty || *first_idx != -1;
+
+ /* We always get here exactly one time for each field we're
+ processing. And we get here in field order (counting by left
+ braces). So this is the perfect place to handle automatic field
+ numbering if the field name is omitted. */
+
+ /* Check if we need to do the auto-numbering. It's not needed if
+ we're called from string.Format routines, because it's handled
+ in that class by itself. */
+ if (auto_number) {
+ /* Initialize our auto numbering state if this is the first
+ time we're either auto-numbering or manually numbering. */
+ if (auto_number->an_state == ANS_INIT && using_numeric_index)
+ auto_number->an_state = field_name_is_empty ?
+ ANS_AUTO : ANS_MANUAL;
+
+ /* Make sure our state is consistent with what we're doing
+ this time through. Only check if we're using a numeric
+ index. */
+ if (using_numeric_index)
+ if (autonumber_state_error(auto_number->an_state,
+ field_name_is_empty))
+ return 0;
+ /* Zero length field means we want to do auto-numbering of the
+ fields. */
+ if (field_name_is_empty)
+ *first_idx = (auto_number->an_field_number)++;
}
return 1;
-error:
- return 0;
}
@@ -403,7 +478,8 @@ error:
the entire input string.
*/
static PyObject *
-get_field_object(SubString *input, PyObject *args, PyObject *kwargs)
+get_field_object(SubString *input, PyObject *args, PyObject *kwargs,
+ AutoNumber *auto_number)
{
PyObject *obj = NULL;
int ok;
@@ -414,7 +490,7 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs)
FieldNameIterator rest;
if (!field_name_split(input->ptr, input->end - input->ptr, &first,
- &index, &rest)) {
+ &index, &rest, auto_number)) {
goto error;
}
@@ -562,14 +638,18 @@ static int
parse_field(SubString *str, SubString *field_name, SubString *format_spec,
STRINGLIB_CHAR *conversion)
{
+ /* Note this function works if the field name is zero length,
+ which is good. Zero length field names are handled later, in
+ field_name_split. */
+
STRINGLIB_CHAR c = 0;
/* initialize these, as they may be empty */
*conversion = '\0';
SubString_init(format_spec, NULL, 0);
- /* search for the field name. it's terminated by the end of the
- string, or a ':' or '!' */
+ /* Search for the field name. it's terminated by the end of
+ the string, or a ':' or '!' */
field_name->ptr = str->ptr;
while (str->ptr < str->end) {
switch (c = *(str->ptr++)) {
@@ -612,15 +692,12 @@ parse_field(SubString *str, SubString *field_name, SubString *format_spec,
}
}
}
-
- return 1;
-
}
- else {
+ else
/* end of string, there's no format_spec or conversion */
field_name->end = str->ptr;
- return 1;
- }
+
+ return 1;
}
/************************************************************************/
@@ -647,8 +724,8 @@ MarkupIterator_init(MarkupIterator *self, STRINGLIB_CHAR *ptr, Py_ssize_t len)
string (or something to be expanded) */
static int
MarkupIterator_next(MarkupIterator *self, SubString *literal,
- SubString *field_name, SubString *format_spec,
- STRINGLIB_CHAR *conversion,
+ int *field_present, SubString *field_name,
+ SubString *format_spec, STRINGLIB_CHAR *conversion,
int *format_spec_needs_expanding)
{
int at_end;
@@ -664,6 +741,7 @@ MarkupIterator_next(MarkupIterator *self, SubString *literal,
SubString_init(format_spec, NULL, 0);
*conversion = '\0';
*format_spec_needs_expanding = 0;
+ *field_present = 0;
/* No more input, end of iterator. This is the normal exit
path. */
@@ -725,6 +803,7 @@ MarkupIterator_next(MarkupIterator *self, SubString *literal,
/* this is markup, find the end of the string by counting nested
braces. note that this prohibits escaped braces, so that
format_specs cannot have braces in them. */
+ *field_present = 1;
count = 1;
start = self->str.ptr;
@@ -749,13 +828,6 @@ MarkupIterator_next(MarkupIterator *self, SubString *literal,
if (parse_field(&s, field_name, format_spec, conversion) == 0)
return 0;
- /* a zero length field_name is an error */
- if (field_name->ptr == field_name->end) {
- PyErr_SetString(PyExc_ValueError, "zero length field name "
- "in format");
- return 0;
- }
-
/* success */
return 2;
}
@@ -803,13 +875,17 @@ do_conversion(PyObject *obj, STRINGLIB_CHAR conversion)
compute the result and write it to output.
format_spec_needs_expanding is an optimization. if it's false,
just output the string directly, otherwise recursively expand the
- format_spec string. */
+ format_spec string.
+
+ field_name is allowed to be zero length, in which case we
+ are doing auto field numbering.
+*/
static int
output_markup(SubString *field_name, SubString *format_spec,
int format_spec_needs_expanding, STRINGLIB_CHAR conversion,
OutputString *output, PyObject *args, PyObject *kwargs,
- int recursion_depth)
+ int recursion_depth, AutoNumber *auto_number)
{
PyObject *tmp = NULL;
PyObject *fieldobj = NULL;
@@ -818,7 +894,7 @@ output_markup(SubString *field_name, SubString *format_spec,
int result = 0;
/* convert field_name to an object */
- fieldobj = get_field_object(field_name, args, kwargs);
+ fieldobj = get_field_object(field_name, args, kwargs, auto_number);
if (fieldobj == NULL)
goto done;
@@ -835,7 +911,8 @@ output_markup(SubString *field_name, SubString *format_spec,
/* if needed, recurively compute the format_spec */
if (format_spec_needs_expanding) {
- tmp = build_string(format_spec, args, kwargs, recursion_depth-1);
+ tmp = build_string(format_spec, args, kwargs, recursion_depth-1,
+ auto_number);
if (tmp == NULL)
goto done;
@@ -869,26 +946,28 @@ done:
*/
static int
do_markup(SubString *input, PyObject *args, PyObject *kwargs,
- OutputString *output, int recursion_depth)
+ OutputString *output, int recursion_depth, AutoNumber *auto_number)
{
MarkupIterator iter;
int format_spec_needs_expanding;
int result;
+ int field_present;
SubString literal;
SubString field_name;
SubString format_spec;
STRINGLIB_CHAR conversion;
MarkupIterator_init(&iter, input->ptr, input->end - input->ptr);
- while ((result = MarkupIterator_next(&iter, &literal, &field_name,
- &format_spec, &conversion,
+ while ((result = MarkupIterator_next(&iter, &literal, &field_present,
+ &field_name, &format_spec,
+ &conversion,
&format_spec_needs_expanding)) == 2) {
if (!output_data(output, literal.ptr, literal.end - literal.ptr))
return 0;
- if (field_name.ptr != field_name.end)
+ if (field_present)
if (!output_markup(&field_name, &format_spec,
format_spec_needs_expanding, conversion, output,
- args, kwargs, recursion_depth))
+ args, kwargs, recursion_depth, auto_number))
return 0;
}
return result;
@@ -901,7 +980,7 @@ do_markup(SubString *input, PyObject *args, PyObject *kwargs,
*/
static PyObject *
build_string(SubString *input, PyObject *args, PyObject *kwargs,
- int recursion_depth)
+ int recursion_depth, AutoNumber *auto_number)
{
OutputString output;
PyObject *result = NULL;
@@ -923,7 +1002,8 @@ build_string(SubString *input, PyObject *args, PyObject *kwargs,
INITIAL_SIZE_INCREMENT))
goto done;
- if (!do_markup(input, args, kwargs, &output, recursion_depth)) {
+ if (!do_markup(input, args, kwargs, &output, recursion_depth,
+ auto_number)) {
goto done;
}
@@ -957,8 +1037,11 @@ do_string_format(PyObject *self, PyObject *args, PyObject *kwargs)
*/
int recursion_depth = 2;
+ AutoNumber auto_number;
+
+ AutoNumber_Init(&auto_number);
SubString_init(&input, STRINGLIB_STR(self), STRINGLIB_LEN(self));
- return build_string(&input, args, kwargs, recursion_depth);
+ return build_string(&input, args, kwargs, recursion_depth, &auto_number);
}
@@ -1003,8 +1086,9 @@ formatteriter_next(formatteriterobject *it)
SubString format_spec;
STRINGLIB_CHAR conversion;
int format_spec_needs_expanding;
- int result = MarkupIterator_next(&it->it_markup, &literal, &field_name,
- &format_spec, &conversion,
+ int field_present;
+ int result = MarkupIterator_next(&it->it_markup, &literal, &field_present,
+ &field_name, &format_spec, &conversion,
&format_spec_needs_expanding);
/* all of the SubString objects point into it->str, so no
@@ -1019,7 +1103,6 @@ formatteriter_next(formatteriterobject *it)
PyObject *format_spec_str = NULL;
PyObject *conversion_str = NULL;
PyObject *tuple = NULL;
- int has_field = field_name.ptr != field_name.end;
literal_str = SubString_new_object(&literal);
if (literal_str == NULL)
@@ -1031,7 +1114,7 @@ formatteriter_next(formatteriterobject *it)
/* if field_name is non-zero length, return a string for
format_spec (even if zero length), else return None */
- format_spec_str = (has_field ?
+ format_spec_str = (field_present ?
SubString_new_object_or_empty :
SubString_new_object)(&format_spec);
if (format_spec_str == NULL)
@@ -1255,9 +1338,11 @@ formatter_field_name_split(STRINGLIB_OBJECT *self)
Py_INCREF(self);
it->str = self;
+ /* Pass in auto_number = NULL. We'll return an empty string for
+ first_obj in that case. */
if (!field_name_split(STRINGLIB_STR(self),
STRINGLIB_LEN(self),
- &first, &first_idx, &it->it_field))
+ &first, &first_idx, &it->it_field, NULL))
goto done;
/* first becomes an integer, if possible; else a string */
diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h
index daaa2e2b0f..84e461628e 100644
--- a/Objects/stringlib/stringdefs.h
+++ b/Objects/stringlib/stringdefs.h
@@ -11,18 +11,23 @@
#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 toupper
-#define STRINGLIB_TOLOWER tolower
+#define STRINGLIB_TOUPPER Py_TOUPPER
+#define STRINGLIB_TOLOWER Py_TOLOWER
#define STRINGLIB_FILL memset
#define STRINGLIB_STR PyString_AS_STRING
#define STRINGLIB_LEN PyString_GET_SIZE
#define STRINGLIB_NEW PyString_FromStringAndSize
#define STRINGLIB_RESIZE _PyString_Resize
#define STRINGLIB_CHECK PyString_Check
-#define STRINGLIB_CMP memcmp
+#define STRINGLIB_CHECK_EXACT PyString_CheckExact
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_GROUPING _PyString_InsertThousandsGrouping
+#define STRINGLIB_GROUPING_LOCALE _PyString_InsertThousandsGroupingLocale
+
+#define STRINGLIB_WANT_CONTAINS_OBJ 1
#endif /* !STRINGLIB_STRINGDEFS_H */
diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h
index 4390e2229a..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. */
@@ -25,10 +18,10 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
size_t i, j;
PyObject *u;
int tabsize = 8;
-
+
if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
return NULL;
-
+
/* First pass: determine size of output string */
i = j = 0;
e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
@@ -55,20 +48,20 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
}
}
}
-
+
if ((i + j) > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError, "result is too long");
return NULL;
}
-
+
/* Second pass: create output string and fill it */
u = STRINGLIB_NEW(NULL, i + j);
if (!u)
return NULL;
-
+
j = 0;
q = STRINGLIB_STR(u);
-
+
for (p = STRINGLIB_STR(self); p < e; p++)
if (*p == '\t') {
if (tabsize > 0) {
@@ -84,7 +77,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args)
if (*p == '\n' || *p == '\r')
j = 0;
}
-
+
return u;
}
@@ -110,16 +103,16 @@ pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
}
u = STRINGLIB_NEW(NULL,
- left + STRINGLIB_LEN(self) + right);
+ left + STRINGLIB_LEN(self) + right);
if (u) {
if (left)
memset(STRINGLIB_STR(u), fill, left);
Py_MEMCPY(STRINGLIB_STR(u) + left,
- STRINGLIB_STR(self),
- STRINGLIB_LEN(self));
+ STRINGLIB_STR(self),
+ STRINGLIB_LEN(self));
if (right)
memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self),
- fill, right);
+ fill, right);
}
return u;
@@ -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 8f87fe0f7d..dd814f6c90 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
@@ -21,6 +23,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
#if PY_VERSION_HEX < 0x03000000
@@ -31,23 +34,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 */
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index e37b579ec5..693f7733d9 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -4,9 +4,10 @@
#include "Python.h"
#include <ctype.h>
+#include <stddef.h>
#ifdef COUNT_ALLOCS
-int null_strings, one_strings;
+Py_ssize_t null_strings, one_strings;
#endif
static PyStringObject *characters[UCHAR_MAX + 1];
@@ -22,11 +23,15 @@ static PyStringObject *nullstring;
*/
static PyObject *interned;
-/*
- For both PyString_FromString() and PyString_FromStringAndSize(), the
- parameter `size' denotes number of characters to allocate, not counting any
- null terminating character.
+/* PyStringObject_SIZE gives the basic size of a string; any memory allocation
+ for a string of length n should request PyStringObject_SIZE + n bytes.
+
+ Using PyStringObject_SIZE instead of sizeof(PyStringObject) saves
+ 3 bytes per string allocation on a typical system.
+*/
+#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1)
+/*
For PyString_FromString(), the parameter `str' points to a null-terminated
string containing exactly `size' bytes.
@@ -43,8 +48,8 @@ static PyObject *interned;
The PyObject member `op->ob_size', which denotes the number of "extra
items" in a variable-size object, will contain the number of bytes
- allocated for string data, not counting the null terminating character. It
- is therefore equal to the equal to the `size' parameter (for
+ allocated for string data, not counting the null terminating character.
+ It is therefore equal to the `size' parameter (for
PyString_FromStringAndSize()) or the length of the string in the `str'
parameter (for PyString_FromString()).
*/
@@ -74,13 +79,13 @@ PyString_FromStringAndSize(const char *str, Py_ssize_t size)
return (PyObject *)op;
}
- if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
PyErr_SetString(PyExc_OverflowError, "string is too large");
return NULL;
}
/* Inline PyObject_NewVar */
- op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
@@ -114,7 +119,7 @@ PyString_FromString(const char *str)
assert(str != NULL);
size = strlen(str);
- if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
PyErr_SetString(PyExc_OverflowError,
"string is too long for a Python string");
return NULL;
@@ -135,7 +140,7 @@ PyString_FromString(const char *str)
}
/* Inline PyObject_NewVar */
- op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
@@ -180,6 +185,9 @@ PyString_FromFormatV(const char *format, va_list vargs)
/* step 1: figure out how large a buffer we need */
for (f = format; *f; f++) {
if (*f == '%') {
+#ifdef HAVE_LONG_LONG
+ int longlongflag = 0;
+#endif
const char* p = f;
while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
;
@@ -187,9 +195,21 @@ PyString_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':
@@ -200,10 +220,21 @@ PyString_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. */
- n += 20;
+#ifdef HAVE_LONG_LONG
+ /* Need at most
+ ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+ plus 1 for the sign. 53/22 is an upper
+ bound for log10(256). */
+ if (longlongflag)
+ n += 2 + (SIZEOF_LONG_LONG*53-1) / 22;
+ else
+#endif
+ /* 20 bytes is enough to hold a 64-bit
+ integer. Decimal takes the most
+ space. This isn't enough for
+ octal. */
+ n += 20;
+
break;
case 's':
s = va_arg(count, char*);
@@ -246,6 +277,9 @@ PyString_FromFormatV(const char *format, va_list vargs)
const char* p = f++;
Py_ssize_t i;
int longflag = 0;
+#ifdef HAVE_LONG_LONG
+ int longlongflag = 0;
+#endif
int size_tflag = 0;
/* parse the width.precision part (we're only
interested in the precision value, if any) */
@@ -260,14 +294,22 @@ PyString_FromFormatV(const char *format, va_list vargs)
}
while (*f && *f != '%' && !isalpha(Py_CHARMASK(*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 %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')) {
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
size_tflag = 1;
++f;
}
@@ -279,6 +321,11 @@ PyString_FromFormatV(const char *format, va_list vargs)
case 'd':
if (longflag)
sprintf(s, "%ld", va_arg(vargs, long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "d",
+ va_arg(vargs, PY_LONG_LONG));
+#endif
else if (size_tflag)
sprintf(s, "%" PY_FORMAT_SIZE_T "d",
va_arg(vargs, Py_ssize_t));
@@ -290,6 +337,11 @@ PyString_FromFormatV(const char *format, va_list vargs)
if (longflag)
sprintf(s, "%lu",
va_arg(vargs, unsigned long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "u",
+ va_arg(vargs, PY_LONG_LONG));
+#endif
else if (size_tflag)
sprintf(s, "%" PY_FORMAT_SIZE_T "u",
va_arg(vargs, size_t));
@@ -339,7 +391,8 @@ PyString_FromFormatV(const char *format, va_list vargs)
}
end:
- _PyString_Resize(&string, s - PyString_AS_STRING(string));
+ if (_PyString_Resize(&string, s - PyString_AS_STRING(string)))
+ return NULL;
return string;
}
@@ -687,12 +740,12 @@ PyObject *PyString_DecodeEscape(const char *s,
default:
*p++ = '\\';
s--;
- goto non_esc; /* an arbitry number of unescaped
+ goto non_esc; /* an arbitrary number of unescaped
UTF-8 bytes may follow. */
}
}
- if (p-buf < newlen)
- _PyString_Resize(&v, p - buf);
+ if (p-buf < newlen && _PyString_Resize(&v, p - buf))
+ goto failed;
return v;
failed:
Py_DECREF(v);
@@ -785,6 +838,7 @@ PyString_AsStringAndSize(register PyObject *obj,
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/partition.h"
+#include "stringlib/split.h"
#define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
#include "stringlib/localeutil.h"
@@ -920,8 +974,8 @@ PyString_Repr(PyObject *obj, int smartquotes)
assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote;
*p = '\0';
- _PyString_Resize(
- &v, (p - PyString_AS_STRING(v)));
+ if (_PyString_Resize(&v, (p - PyString_AS_STRING(v))))
+ return NULL;
return v;
}
}
@@ -994,12 +1048,12 @@ string_concat(register PyStringObject *a, register PyObject *bb)
}
/* Inline PyObject_NewVar */
- if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) {
+ if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) {
PyErr_SetString(PyExc_OverflowError,
"strings are too large to concat");
return NULL;
}
- op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
@@ -1036,13 +1090,12 @@ string_repeat(register PyStringObject *a, register Py_ssize_t n)
return (PyObject *)a;
}
nbytes = (size_t)size;
- if (nbytes + sizeof(PyStringObject) <= nbytes) {
+ if (nbytes + PyStringObject_SIZE <= nbytes) {
PyErr_SetString(PyExc_OverflowError,
"repeated string is too long");
return NULL;
}
- op = (PyStringObject *)
- PyObject_MALLOC(sizeof(PyStringObject) + nbytes);
+ op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes);
if (op == NULL)
return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
@@ -1370,145 +1423,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_APPEND(data, left, right) \
- str = PyString_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 = PyString_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<len && isspace(Py_CHARMASK(s[i]))) i++; }
-#define SKIP_NONSPACE(s, i, len) { while (i<len && !isspace(Py_CHARMASK(s[i]))) i++; }
-#define RSKIP_SPACE(s, i) { while (i>=0 && isspace(Py_CHARMASK(s[i]))) i--; }
-#define RSKIP_NONSPACE(s, i) { while (i>=0 && !isspace(Py_CHARMASK(s[i]))) i--; }
-
-Py_LOCAL_INLINE(PyObject *)
-split_whitespace(PyStringObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
-{
- const char *s = PyString_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 && PyString_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(PyStringObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- const char *s = PyString_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<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 == 0 && count == 0 && PyString_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 (i <= len) {
- SPLIT_ADD(s, i, len);
- }
- FIX_PREALLOC_SIZE(list);
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
PyDoc_STRVAR(split__doc__,
"S.split([sep [,maxsplit]]) -> list of strings\n\
\n\
@@ -1521,20 +1435,17 @@ from the result.");
static PyObject *
string_split(PyStringObject *self, PyObject *args)
{
- Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
- Py_ssize_t maxsplit = -1, count=0;
+ Py_ssize_t len = PyString_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
const char *s = PyString_AS_STRING(self), *sub;
- PyObject *list, *str, *subobj = Py_None;
-#ifdef USE_FAST
- Py_ssize_t pos;
-#endif
+ PyObject *subobj = Py_None;
if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return split_whitespace(self, len, maxsplit);
+ return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
@@ -1546,46 +1457,7 @@ string_split(PyStringObject *self, PyObject *args)
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- return NULL;
- }
- else if (n == 1)
- return split_char(self, len, sub[0], maxsplit);
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL)
- 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);
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
+ return stringlib_split((PyObject*) self, s, len, sub, n, maxsplit);
}
PyDoc_STRVAR(partition__doc__,
@@ -1650,90 +1522,6 @@ string_rpartition(PyStringObject *self, PyObject *sep_obj)
);
}
-Py_LOCAL_INLINE(PyObject *)
-rsplit_whitespace(PyStringObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
-{
- const char *s = PyString_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 && PyString_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(PyStringObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- const char *s = PyString_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 && PyString_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__,
"S.rsplit([sep [,maxsplit]]) -> list of strings\n\
\n\
@@ -1746,17 +1534,17 @@ is a separator.");
static PyObject *
string_rsplit(PyStringObject *self, PyObject *args)
{
- Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
- Py_ssize_t maxsplit = -1, count=0;
- const char *s, *sub;
- PyObject *list, *str, *subobj = Py_None;
+ Py_ssize_t len = PyString_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyString_AS_STRING(self), *sub;
+ PyObject *subobj = Py_None;
if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return rsplit_whitespace(self, len, maxsplit);
+ return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
@@ -1768,40 +1556,7 @@ string_rsplit(PyStringObject *self, PyObject *args)
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- return NULL;
- }
- else if (n == 1)
- return rsplit_char(self, len, sub[0], maxsplit);
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL)
- return NULL;
-
- j = len;
- i = j - n;
-
- s = PyString_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;
- return list;
-
-onError:
- Py_DECREF(list);
- return NULL;
+ return stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit);
}
@@ -1916,20 +1671,20 @@ _PyString_Join(PyObject *sep, PyObject *x)
return string_join((PyStringObject *)sep, x);
}
-Py_LOCAL_INLINE(void)
-string_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)
string_find_internal(PyStringObject *self, PyObject *args, int dir)
@@ -1938,19 +1693,9 @@ string_find_internal(PyStringObject *self, PyObject *args, int dir)
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))
+ if (!stringlib_parse_args_finds("find/rfind/index/rindex",
+ args, &subobj, &start, &end))
return -2;
if (PyString_Check(subobj)) {
@@ -2362,8 +2107,7 @@ string_count(PyStringObject *self, PyObject *args)
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))
+ if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
return NULL;
if (PyString_Check(sub_obj)) {
@@ -2383,10 +2127,10 @@ string_count(PyStringObject *self, PyObject *args)
else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
return NULL;
- string_adjust_indices(&start, &end, PyString_GET_SIZE(self));
+ ADJUST_INDICES(start, end, PyString_GET_SIZE(self));
return PyInt_FromSsize_t(
- stringlib_count(str + start, end - start, sub, sub_len)
+ stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
);
}
@@ -2543,15 +2287,12 @@ string_translate(PyStringObject *self, PyObject *args)
return input_obj;
}
/* Fix the size of the resulting string */
- if (inlen > 0)
- _PyString_Resize(&result, output - output_start);
+ if (inlen > 0 && _PyString_Resize(&result, output - output_start))
+ return NULL;
return result;
}
-#define FORWARD 1
-#define REVERSE -1
-
/* find and count characters and substrings */
#define findchar(target, target_len, c) \
@@ -2587,93 +2328,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 */
@@ -2794,10 +2448,9 @@ replace_delete_substring(PyStringObject *self,
self_len = PyString_GET_SIZE(self);
self_s = PyString_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 */
@@ -2816,9 +2469,9 @@ replace_delete_substring(PyStringObject *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;
@@ -2894,9 +2547,9 @@ replace_substring_in_place(PyStringObject *self,
self_s = PyString_AS_STRING(self);
self_len = PyString_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);
@@ -2916,9 +2569,9 @@ replace_substring_in_place(PyStringObject *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);
@@ -3010,9 +2663,10 @@ replace_substring(PyStringObject *self,
self_s = PyString_AS_STRING(self);
self_len = PyString_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);
@@ -3039,9 +2693,9 @@ replace_substring(PyStringObject *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;
@@ -3211,7 +2865,7 @@ _string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start,
return -1;
str = PyString_AS_STRING(self);
- string_adjust_indices(&start, &end, len);
+ ADJUST_INDICES(start, end, len);
if (direction < 0) {
/* startswith */
@@ -3247,8 +2901,7 @@ string_startswith(PyStringObject *self, PyObject *args)
PyObject *subobj;
int result;
- if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
@@ -3265,8 +2918,12 @@ string_startswith(PyStringObject *self, PyObject *args)
Py_RETURN_FALSE;
}
result = _string_tailmatch(self, subobj, start, end, -1);
- if (result == -1)
+ if (result == -1) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
return NULL;
+ }
else
return PyBool_FromLong(result);
}
@@ -3288,8 +2945,7 @@ string_endswith(PyStringObject *self, PyObject *args)
PyObject *subobj;
int result;
- if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
@@ -3306,8 +2962,12 @@ string_endswith(PyStringObject *self, PyObject *args)
Py_RETURN_FALSE;
}
result = _string_tailmatch(self, subobj, start, end, +1);
- if (result == -1)
+ if (result == -1) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
return NULL;
+ }
else
return PyBool_FromLong(result);
}
@@ -3324,13 +2984,15 @@ a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
codecs.register_error that is able to handle UnicodeEncodeErrors.");
static PyObject *
-string_encode(PyStringObject *self, PyObject *args)
+string_encode(PyStringObject *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 = PyString_AsEncodedObject((PyObject *)self, encoding, errors);
if (v == NULL)
@@ -3361,13 +3023,15 @@ as well as any other name registered with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");
static PyObject *
-string_decode(PyStringObject *self, PyObject *args)
+string_decode(PyStringObject *self, PyObject *args, PyObject *kwargs)
{
+ static char *kwlist[] = {"encoding", "errors", 0};
char *encoding = NULL;
char *errors = NULL;
PyObject *v;
- if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+ kwlist, &encoding, &errors))
return NULL;
v = PyString_AsDecodedObject((PyObject *)self, encoding, errors);
if (v == NULL)
@@ -3875,62 +3539,15 @@ is given and true.");
static PyObject*
string_splitlines(PyStringObject *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 = PyString_AS_STRING(self);
- len = PyString_GET_SIZE(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;
- }
- SPLIT_APPEND(data, j, eol);
- j = i;
- }
- if (j < len) {
- SPLIT_APPEND(data, j, len);
- }
-
- return list;
-
- onError:
- Py_XDECREF(list);
- return NULL;
+ return stringlib_splitlines(
+ (PyObject*) self, PyString_AS_STRING(self), PyString_GET_SIZE(self),
+ keepends
+ );
}
PyDoc_STRVAR(sizeof__doc__,
@@ -3940,15 +3557,10 @@ static PyObject *
string_sizeof(PyStringObject *v)
{
Py_ssize_t res;
- res = sizeof(PyStringObject) + v->ob_size * v->ob_type->tp_itemsize;
+ res = PyStringObject_SIZE + PyString_GET_SIZE(v) * Py_TYPE(v)->tp_itemsize;
return PyInt_FromSsize_t(res);
}
-#undef SPLIT_APPEND
-#undef SPLIT_ADD
-#undef MAX_PREALLOC
-#undef PREALLOC_SIZE
-
static PyObject *
string_getnewargs(PyStringObject *v)
{
@@ -3961,7 +3573,8 @@ string_getnewargs(PyStringObject *v)
PyDoc_STRVAR(format__doc__,
"S.format(*args, **kwargs) -> string\n\
\n\
-");
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
static PyObject *
string__format__(PyObject* self, PyObject* args)
@@ -3995,7 +3608,7 @@ done:
PyDoc_STRVAR(p_format__doc__,
"S.__format__(format_spec) -> string\n\
\n\
-");
+Return a formatted version of S as described by format_spec.");
static PyMethodDef
@@ -4045,8 +3658,8 @@ string_methods[] = {
{"__format__", (PyCFunction) string__format__, METH_VARARGS, p_format__doc__},
{"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
{"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
- {"encode", (PyCFunction)string_encode, METH_VARARGS, encode__doc__},
- {"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__},
+ {"encode", (PyCFunction)string_encode, METH_VARARGS | METH_KEYWORDS, encode__doc__},
+ {"decode", (PyCFunction)string_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
{"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS,
expandtabs__doc__},
{"splitlines", (PyCFunction)string_splitlines, METH_VARARGS,
@@ -4179,7 +3792,7 @@ If the argument is a string, the return value is the same object.");
PyTypeObject PyString_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"str",
- sizeof(PyStringObject),
+ PyStringObject_SIZE,
sizeof(char),
string_dealloc, /* tp_dealloc */
(printfunc)string_print, /* tp_print */
@@ -4275,7 +3888,7 @@ _PyString_Resize(PyObject **pv, Py_ssize_t newsize)
_Py_DEC_REFTOTAL;
_Py_ForgetReference(v);
*pv = (PyObject *)
- PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize);
+ PyObject_REALLOC((char *)v, PyStringObject_SIZE + newsize);
if (*pv == NULL) {
PyObject_Del(v);
PyErr_NoMemory();
@@ -4320,63 +3933,33 @@ getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx)
#define F_ALT (1<<3)
#define F_ZERO (1<<4)
-Py_LOCAL_INLINE(int)
-formatfloat(char *buf, size_t buflen, int flags,
- int prec, int type, PyObject *v)
+/* Returns a new reference to a PyString object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
{
- /* fmt = '%#.' + `prec` + `type`
- worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/
- char fmt[20];
+ char *p;
+ PyObject *result;
double x;
+
x = PyFloat_AsDouble(v);
if (x == -1.0 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "float argument required, "
"not %.200s", Py_TYPE(v)->tp_name);
- return -1;
+ return NULL;
}
+
if (prec < 0)
prec = 6;
-#if SIZEOF_INT > 4
- /* make sure that the decimal representation of precision really does
- need at most 10 digits: platforms with sizeof(int) == 8 exist! */
- if (prec > 0x7fffffff) {
- PyErr_SetString(PyExc_OverflowError,
- "outrageously large precision "
- "for formatted float");
- return -1;
- }
-#endif
-
- if (type == 'f' && fabs(x) >= 1e50)
- type = 'g';
- /* Worst case length calc to ensure no buffer overrun:
-
- 'g' formats:
- fmt = %#.<prec>g
- buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
- for any double rep.)
- len = 1 + prec + 1 + 2 + 5 = 9 + prec
-
- 'f' formats:
- buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
- len = 1 + 50 + 1 + prec = 52 + prec
- If prec=0 the effective precision is 1 (the leading digit is
- always given), therefore increase the length by one.
+ p = PyOS_double_to_string(x, type, prec,
+ (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
- */
- if (((type == 'g' || type == 'G') &&
- buflen <= (size_t)10 + (size_t)prec) ||
- (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
- PyErr_SetString(PyExc_OverflowError,
- "formatted float is too long (precision too large?)");
- return -1;
- }
- PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c",
- (flags&F_ALT) ? "#" : "",
- prec, type);
- PyOS_ascii_formatd(buf, buflen, fmt, x);
- return (int)strlen(buf);
+ if (p == NULL)
+ return NULL;
+ result = PyString_FromStringAndSize(p, strlen(p));
+ PyMem_Free(p);
+ return result;
}
/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
@@ -4616,7 +4199,7 @@ formatchar(char *buf, size_t buflen, PyObject *v)
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
- FORMATBUFLEN is the length of the buffer in which the floats, ints, &
+ FORMATBUFLEN is the length of the buffer in which the ints &
chars are formatted. XXX This is a magic number. Each formatting
routine does bounds checking to ensure no overflow, but a better
solution may be to malloc a buffer of appropriate size for each
@@ -4664,7 +4247,7 @@ PyString_Format(PyObject *format, PyObject *args)
if (--rescnt < 0) {
rescnt = fmtcnt + 100;
reslen += rescnt;
- if (_PyString_Resize(&result, reslen) < 0)
+ if (_PyString_Resize(&result, reslen))
return NULL;
res = PyString_AS_STRING(result)
+ reslen - rescnt;
@@ -4686,7 +4269,7 @@ PyString_Format(PyObject *format, PyObject *args)
int sign;
Py_ssize_t len;
char formatbuf[FORMATBUFLEN];
- /* For format{float,int,char}() */
+ /* For format{int,char}() */
#ifdef Py_USING_UNICODE
char *fmt_start = fmt;
Py_ssize_t argidx_start = argidx;
@@ -4937,13 +4520,11 @@ PyString_Format(PyObject *format, PyObject *args)
case 'F':
case 'g':
case 'G':
- if (c == 'F')
- c = 'f';
- pbuf = formatbuf;
- len = formatfloat(pbuf, sizeof(formatbuf),
- flags, prec, c, v);
- if (len < 0)
+ temp = formatfloat(v, flags, prec, c);
+ if (temp == NULL)
goto error;
+ pbuf = PyString_AS_STRING(temp);
+ len = PyString_GET_SIZE(temp);
sign = 1;
if (flags & F_ZERO)
fill = '0';
@@ -4993,7 +4574,7 @@ PyString_Format(PyObject *format, PyObject *args)
Py_XDECREF(temp);
return PyErr_NoMemory();
}
- if (_PyString_Resize(&result, reslen) < 0) {
+ if (_PyString_Resize(&result, reslen)) {
Py_XDECREF(temp);
return NULL;
}
@@ -5061,7 +4642,8 @@ PyString_Format(PyObject *format, PyObject *args)
if (args_owned) {
Py_DECREF(args);
}
- _PyString_Resize(&result, reslen - rescnt);
+ if (_PyString_Resize(&result, reslen - rescnt))
+ return NULL;
return result;
#ifdef Py_USING_UNICODE
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index bbc78f4ddb..3249cccdb7 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -19,10 +19,32 @@ static PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
static int numfree[PyTuple_MAXSAVESIZE];
#endif
#ifdef COUNT_ALLOCS
-int fast_tuple_allocs;
-int tuple_zero_allocs;
+Py_ssize_t fast_tuple_allocs;
+Py_ssize_t tuple_zero_allocs;
#endif
+/* Debug statistic to count GC tracking of tuples.
+ Please note that tuples are only untracked when considered by the GC, and
+ many of them will be dead before. Therefore, a tracking rate close to 100%
+ does not necessarily prove that the heuristic is inefficient.
+*/
+#ifdef SHOW_TRACK_COUNT
+static Py_ssize_t count_untracked = 0;
+static Py_ssize_t count_tracked = 0;
+
+static void
+show_track(void)
+{
+ fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n",
+ count_tracked + count_untracked);
+ fprintf(stderr, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T
+ "d\n", count_tracked);
+ fprintf(stderr, "%.2f%% tuple tracking rate\n\n",
+ (100.0*count_tracked/(count_untracked+count_tracked)));
+}
+#endif
+
+
PyObject *
PyTuple_New(register Py_ssize_t size)
{
@@ -64,7 +86,6 @@ PyTuple_New(register Py_ssize_t size)
{
return PyErr_NoMemory();
}
- nbytes += sizeof(PyTupleObject) - sizeof(PyObject *);
op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
if (op == NULL)
@@ -79,6 +100,9 @@ PyTuple_New(register Py_ssize_t size)
Py_INCREF(op); /* extra INCREF so that this is never freed */
}
#endif
+#ifdef SHOW_TRACK_COUNT
+ count_tracked++;
+#endif
_PyObject_GC_TRACK(op);
return (PyObject *) op;
}
@@ -131,6 +155,32 @@ PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
return 0;
}
+void
+_PyTuple_MaybeUntrack(PyObject *op)
+{
+ PyTupleObject *t;
+ Py_ssize_t i, n;
+
+ if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
+ return;
+ t = (PyTupleObject *) op;
+ n = Py_SIZE(t);
+ for (i = 0; i < n; i++) {
+ PyObject *elt = PyTuple_GET_ITEM(t, i);
+ /* Tuple with NULL elements aren't
+ fully constructed, don't untrack
+ them yet. */
+ if (!elt ||
+ _PyObject_GC_MAY_BE_TRACKED(elt))
+ return;
+ }
+#ifdef SHOW_TRACK_COUNT
+ count_tracked--;
+ count_untracked++;
+#endif
+ _PyObject_GC_UNTRACK(op);
+}
+
PyObject *
PyTuple_Pack(Py_ssize_t n, ...)
{
@@ -483,7 +533,7 @@ tupleindex(PyTupleObject *self, PyObject *args)
else if (cmp < 0)
return NULL;
}
- PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in list");
+ PyErr_SetString(PyExc_ValueError, "tuple.index(x): x not in tuple");
return NULL;
}
@@ -824,7 +874,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++) {
@@ -880,6 +931,9 @@ PyTuple_Fini(void)
(void)PyTuple_ClearFreeList();
#endif
+#ifdef SHOW_TRACK_COUNT
+ show_track();
+#endif
}
/*********************** Tuple Iterator **************************/
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 4c972648ae..49c7e071e9 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -188,8 +188,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},
@@ -307,10 +307,13 @@ 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 itself 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__");
+ PyErr_SetString(PyExc_AttributeError, "__abstractmethods__");
return NULL;
}
Py_XINCREF(mod);
@@ -324,8 +327,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_SetString(PyExc_AttributeError, "__abstractmethods__");
+ return -1;
+ }
+ }
if (res == 0) {
PyType_Modified(type);
if (value && PyObject_IsTrue(value)) {
@@ -586,14 +598,6 @@ type___instancecheck__(PyObject *type, PyObject *inst)
static PyObject *
-type_get_instancecheck(PyObject *type, void *context)
-{
- static PyMethodDef ml = {"__instancecheck__",
- type___instancecheck__, METH_O };
- return PyCFunction_New(&ml, type);
-}
-
-static PyObject *
type___subclasscheck__(PyObject *type, PyObject *inst)
{
switch (_PyObject_RealIsSubclass(inst, type)) {
@@ -606,13 +610,6 @@ type___subclasscheck__(PyObject *type, PyObject *inst)
}
}
-static PyObject *
-type_get_subclasscheck(PyObject *type, void *context)
-{
- static PyMethodDef ml = {"__subclasscheck__",
- type___subclasscheck__, METH_O };
- return PyCFunction_New(&ml, type);
-}
static PyGetSetDef type_getsets[] = {
{"__name__", (getter)type_name, (setter)type_set_name, NULL},
@@ -622,8 +619,6 @@ static PyGetSetDef type_getsets[] = {
(setter)type_set_abstractmethods, NULL},
{"__dict__", (getter)type_dict, NULL, NULL},
{"__doc__", (getter)type_get_doc, NULL, NULL},
- {"__instancecheck__", (getter)type_get_instancecheck, NULL, NULL},
- {"__subclasscheck__", (getter)type_get_subclasscheck, NULL, NULL},
{0}
};
@@ -988,7 +983,7 @@ subtype_dealloc(PyObject *self)
/* Clear slots up to the nearest base with a different tp_dealloc */
base = type;
- while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
+ while (base->tp_dealloc == subtype_dealloc) {
if (Py_SIZE(base))
clear_slots(base, self);
base = base->tp_base;
@@ -1059,7 +1054,7 @@ subtype_dealloc(PyObject *self)
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
+ then. But we're already deleting self. Double deallocation is
a subtle disaster.
Q. Why the bizarre (net-zero) manipulation of
@@ -1174,6 +1169,8 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
when the _PyType_Lookup() call fails;
- lookup_method() always raises an exception upon errors.
+
+ - _PyObject_LookupSpecial() exported for the benefit of other places.
*/
static PyObject *
@@ -1206,6 +1203,13 @@ lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
return res;
}
+PyObject *
+_PyObject_LookupSpecial(PyObject *self, char *attrstr, PyObject **attrobj)
+{
+ assert(!PyInstance_Check(self));
+ return lookup_maybe(self, attrstr, attrobj);
+}
+
/* A variation of PyObject_CallMethod that uses lookup_method()
instead of PyObject_GetAttrString(). This uses the same convention
as lookup_method to cache the interned name string object. */
@@ -2305,6 +2309,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
Py_TPFLAGS_BASETYPE;
if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
+ if (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER)
+ type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
/* It's a new-style number unless it specifically inherits any
old-style numeric behavior */
@@ -2658,6 +2664,10 @@ static PyMethodDef type_methods[] = {
PyDoc_STR("mro() -> list\nreturn a type's method resolution order")},
{"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS,
PyDoc_STR("__subclasses__() -> list of immediate subclasses")},
+ {"__instancecheck__", type___instancecheck__, METH_O,
+ PyDoc_STR("__instancecheck__() -> bool\ncheck if an object is an instance")},
+ {"__subclasscheck__", type___subclasscheck__, METH_O,
+ PyDoc_STR("__subclasscheck__() -> bool\ncheck if a class is a subclass")},
{0}
};
@@ -3001,10 +3011,7 @@ 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);
size = base->tp_basicsize;
if (a->tp_dictoffset == size && b->tp_dictoffset == size)
size += sizeof(PyObject *);
@@ -3415,30 +3422,46 @@ object_format(PyObject *self, PyObject *args)
PyObject *format_spec;
PyObject *self_as_str = NULL;
PyObject *result = NULL;
- PyObject *format_meth = NULL;
+ Py_ssize_t format_len;
if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
return NULL;
+#ifdef Py_USING_UNICODE
if (PyUnicode_Check(format_spec)) {
+ format_len = PyUnicode_GET_SIZE(format_spec);
self_as_str = PyObject_Unicode(self);
} else if (PyString_Check(format_spec)) {
+#else
+ if (PyString_Check(format_spec)) {
+#endif
+ format_len = PyString_GET_SIZE(format_spec);
self_as_str = PyObject_Str(self);
} else {
- PyErr_SetString(PyExc_TypeError, "argument to __format__ must be unicode or str");
+ PyErr_SetString(PyExc_TypeError,
+ "argument to __format__ must be unicode or str");
return NULL;
}
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);
+ /* Issue 7994: If we're converting to a string, we
+ should reject format specifications */
+ if (format_len > 0) {
+ if (PyErr_WarnEx(PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty format "
+ "string is deprecated", 1) < 0) {
+ goto done;
+ }
+ /* Eventually this will become an error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to object.__format__");
+ goto done;
+ */
}
+ result = PyObject_Format(self_as_str, format_spec);
}
+done:
Py_XDECREF(self_as_str);
- Py_XDECREF(format_meth);
return result;
}
@@ -3467,7 +3490,7 @@ static PyMethodDef object_methods[] = {
{"__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")},
+ PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")},
{0}
};
@@ -3593,6 +3616,8 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp)
return 0;
}
+#define BUFFER_FLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER)
+
static void
inherit_special(PyTypeObject *type, PyTypeObject *base)
{
@@ -3600,9 +3625,9 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
/* Special flag magic */
if (!type->tp_as_buffer && base->tp_as_buffer) {
- type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
+ type->tp_flags &= ~BUFFER_FLAGS;
type->tp_flags |=
- base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
+ base->tp_flags & BUFFER_FLAGS;
}
if (!type->tp_as_sequence && base->tp_as_sequence) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
@@ -5985,7 +6010,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, ""),
@@ -6094,8 +6119,12 @@ update_one_slot(PyTypeObject *type, slotdef *p)
}
do {
descr = _PyType_Lookup(type, p->name_strobj);
- if (descr == NULL)
+ 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)
@@ -6114,7 +6143,7 @@ update_one_slot(PyTypeObject *type, slotdef *p)
else if (Py_TYPE(descr) == &PyCFunction_Type &&
PyCFunction_GET_FUNCTION(descr) ==
(PyCFunction)tp_new_wrapper &&
- strcmp(p->name, "__new__") == 0)
+ ptr == (void**)&type->tp_new)
{
/* The __new__ wrapper is not a wrapper descriptor,
so must be special-cased differently.
@@ -6134,7 +6163,7 @@ update_one_slot(PyTypeObject *type, slotdef *p)
point out a bug in this reasoning a beer. */
}
else if (descr == Py_None &&
- strcmp(p->name, "__hash__") == 0) {
+ ptr == (void**)&type->tp_hash) {
/* We specifically allow __hash__ to be set to None
to prevent inheritance of the default
implementation from object.__hash__ */
@@ -6316,7 +6345,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *name,
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 encountered wins. Since
slotdef entries are sorted by the offset of the slot in the
PyHeapTypeObject, this gives us some control over disambiguating
between competing slots: the members of PyHeapTypeObject are listed
diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c
index 78c40b5212..9c439a76db 100644
--- a/Objects/unicodectype.c
+++ b/Objects/unicodectype.c
@@ -20,6 +20,7 @@
#define TITLE_MASK 0x40
#define UPPER_MASK 0x80
#define NODELTA_MASK 0x100
+#define NUMERIC_MASK 0x200
typedef struct {
const Py_UNICODE upper;
@@ -39,37 +40,17 @@ gettyperecord(Py_UNICODE code)
#ifdef Py_UNICODE_WIDE
if (code >= 0x110000)
- index = 0;
+ index = 0;
else
#endif
{
- index = index1[(code>>SHIFT)];
- index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
+ index = index1[(code>>SHIFT)];
+ index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
}
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. */
@@ -79,10 +60,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;
}
@@ -110,7 +91,7 @@ int _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
{
if (_PyUnicode_ToDecimalDigit(ch) < 0)
- return 0;
+ return 0;
return 1;
}
@@ -127,575 +108,22 @@ int _PyUnicode_ToDigit(Py_UNICODE ch)
int _PyUnicode_IsDigit(Py_UNICODE ch)
{
if (_PyUnicode_ToDigit(ch) < 0)
- return 0;
+ return 0;
return 1;
}
/* 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;
}
#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. */
@@ -724,9 +152,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;
}
@@ -738,9 +166,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;
}
@@ -759,11 +187,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/unicodeobject.c b/Objects/unicodeobject.c
index d8dab672b6..b2332a5360 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -115,9 +115,9 @@ static char unicode_default_encoding[100];
/* 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,
@@ -147,8 +147,10 @@ const unsigned char _Py_ascii_whitespace[] = {
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 */
@@ -190,11 +192,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(mask, ch) ((mask & (1 << ((ch) & 0x1F))))
+#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)] : \
@@ -204,12 +217,12 @@ 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;
for (i = 0; i < len; i++)
- mask |= (1 << (ptr[i] & 0x1F));
+ BLOOM_ADD(mask, ptr[i]);
return mask;
}
@@ -280,7 +293,7 @@ int unicode_resize(register PyUnicodeObject *unicode,
}
/* We allocate one more byte to make sure the string is
- Ux0000 terminated -- XXX is this needed ?
+ Ux0000 terminated; some code relies on that.
XXX This allocator could further be enhanced by assuring that the
free list never reduces its size below 1.
@@ -527,6 +540,60 @@ PyObject *PyUnicode_FromString(const char *u)
#ifdef HAVE_WCHAR_H
+#if (Py_UNICODE_SIZE == 2) && defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
+# define CONVERT_WCHAR_TO_SURROGATES
+#endif
+
+#ifdef CONVERT_WCHAR_TO_SURROGATES
+
+/* Here sizeof(wchar_t) is 4 but Py_UNICODE_SIZE == 2, so we need
+ to convert from UTF32 to UTF16. */
+
+PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
+ Py_ssize_t size)
+{
+ PyUnicodeObject *unicode;
+ register Py_ssize_t i;
+ Py_ssize_t alloc;
+ const wchar_t *orig_w;
+
+ if (w == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
+ alloc = size;
+ orig_w = w;
+ for (i = size; i > 0; i--) {
+ if (*w > 0xFFFF)
+ alloc++;
+ w++;
+ }
+ w = orig_w;
+ unicode = _PyUnicode_New(alloc);
+ if (!unicode)
+ return NULL;
+
+ /* Copy the wchar_t data into the new object */
+ {
+ register Py_UNICODE *u;
+ u = PyUnicode_AS_UNICODE(unicode);
+ for (i = size; i > 0; i--) {
+ if (*w > 0xFFFF) {
+ wchar_t ordinal = *w++;
+ ordinal -= 0x10000;
+ *u++ = 0xD800 | (ordinal >> 10);
+ *u++ = 0xDC00 | (ordinal & 0x3FF);
+ }
+ else
+ *u++ = *w++;
+ }
+ }
+ return (PyObject *)unicode;
+}
+
+#else
+
PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
Py_ssize_t size)
{
@@ -557,6 +624,10 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
return (PyObject *)unicode;
}
+#endif /* CONVERT_WCHAR_TO_SURROGATES */
+
+#undef CONVERT_WCHAR_TO_SURROGATES
+
static void
makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c)
{
@@ -681,7 +752,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
case 's':
{
/* UTF-8 */
- unsigned char *s = va_arg(count, unsigned char*);
+ const char *s = va_arg(count, const char*);
PyObject *str = PyUnicode_DecodeUTF8(s, strlen(s), "replace");
if (!str)
goto fail;
@@ -1408,69 +1479,81 @@ int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler
/* --- UTF-7 Codec -------------------------------------------------------- */
-/* see RFC2152 for details */
+/* See RFC2152 for details. We encode conservatively and decode liberally. */
-static
-char utf7_special[128] = {
- /* indicate whether a UTF-7 character is special i.e. cannot be directly
- encoded:
- 0 - not special
- 1 - special
- 2 - whitespace (optional)
- 3 - RFC2152 Set O (optional) */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 1, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0,
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3,
- 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1,
+/* Three simple macros defining base-64. */
-};
+/* Is c a base-64 character? */
+
+#define IS_BASE64(c) \
+ (isalnum(c) || (c) == '+' || (c) == '/')
-/* Note: The comparison (c) <= 0 is a trick to work-around gcc
- warnings about the comparison always being false; since
- utf7_special[0] is 1, we can safely make that one comparison
- true */
+/* given that c is a base-64 character, what is its base-64 value? */
-#define SPECIAL(c, encodeO, encodeWS) \
- ((c) > 127 || (c) <= 0 || utf7_special[(c)] == 1 || \
- (encodeWS && (utf7_special[(c)] == 2)) || \
- (encodeO && (utf7_special[(c)] == 3)))
+#define FROM_BASE64(c) \
+ (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' : \
+ ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 26 : \
+ ((c) >= '0' && (c) <= '9') ? (c) - '0' + 52 : \
+ (c) == '+' ? 62 : 63)
-#define B64(n) \
+/* What is the base-64 character of the bottom 6 bits of n? */
+
+#define TO_BASE64(n) \
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f])
-#define B64CHAR(c) \
- (isalnum(c) || (c) == '+' || (c) == '/')
-#define UB64(c) \
- ((c) == '+' ? 62 : (c) == '/' ? 63 : (c) >= 'a' ? \
- (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4 )
-
-#define ENCODE(out, ch, bits) \
- while (bits >= 6) { \
- *out++ = B64(ch >> (bits-6)); \
- bits -= 6; \
- }
-
-#define DECODE(out, ch, bits, surrogate) \
- while (bits >= 16) { \
- Py_UNICODE outCh = (Py_UNICODE) ((ch >> (bits-16)) & 0xffff); \
- bits -= 16; \
- if (surrogate) { \
- /* We have already generated an error for the high surrogate \
- so let's not bother seeing if the low surrogate is correct or not */ \
- surrogate = 0; \
- } else if (0xDC00 <= outCh && outCh <= 0xDFFF) { \
- /* This is a surrogate pair. Unfortunately we can't represent \
- it in a 16-bit character */ \
- surrogate = 1; \
- errmsg = "code pairs are not supported"; \
- goto utf7Error; \
- } else { \
- *out++ = outCh; \
- } \
- }
+
+/* DECODE_DIRECT: this byte encountered in a UTF-7 string should be
+ * decoded as itself. We are permissive on decoding; the only ASCII
+ * byte not decoding to itself is the + which begins a base64
+ * string. */
+
+#define DECODE_DIRECT(c) \
+ ((c) <= 127 && (c) != '+')
+
+/* The UTF-7 encoder treats ASCII characters differently according to
+ * whether they are Set D, Set O, Whitespace, or special (i.e. none of
+ * the above). See RFC2152. This array identifies these different
+ * sets:
+ * 0 : "Set D"
+ * alphanumeric and '(),-./:?
+ * 1 : "Set O"
+ * !"#$%&*;<=>@[]^_`{|}
+ * 2 : "whitespace"
+ * ht nl cr sp
+ * 3 : special (must be base64 encoded)
+ * everything else (i.e. +\~ and non-printing codes 0-8 11-12 14-31 127)
+ */
+
+static
+char utf7_category[128] = {
+/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3,
+/* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+/* sp ! " # $ % & ' ( ) * + , - . / */
+ 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 0,
+/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+/* @ A B C D E F G H I J K L M N O */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1,
+/* ` a b c d e f g h i j k l m n o */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* p q r s t u v w x y z { | } ~ del */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3,
+};
+
+/* ENCODE_DIRECT: this character should be encoded as itself. The
+ * answer depends on whether we are encoding set O as itself, and also
+ * on whether we are encoding whitespace as itself. RFC2152 makes it
+ * clear that the answers to these questions vary between
+ * applications, so this code needs to be flexible. */
+
+#define ENCODE_DIRECT(c, directO, directWS) \
+ ((c) < 128 && (c) > 0 && \
+ ((utf7_category[(c)] == 0) || \
+ (directWS && (utf7_category[(c)] == 2)) || \
+ (directO && (utf7_category[(c)] == 1))))
PyObject *PyUnicode_DecodeUTF7(const char *s,
Py_ssize_t size,
@@ -1479,6 +1562,13 @@ PyObject *PyUnicode_DecodeUTF7(const char *s,
return PyUnicode_DecodeUTF7Stateful(s, size, errors, NULL);
}
+/* The decoder. The only state we preserve is our read position,
+ * i.e. how many characters we have consumed. So if we end in the
+ * middle of a shift sequence we have to back off the read position
+ * and the output to the beginning of the sequence, otherwise we lose
+ * all the shift state (seen bits, number of bits seen, high
+ * surrogate). */
+
PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
Py_ssize_t size,
const char *errors,
@@ -1493,9 +1583,10 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
Py_UNICODE *p;
const char *errmsg = "";
int inShift = 0;
- unsigned int bitsleft = 0;
- unsigned long charsleft = 0;
- int surrogate = 0;
+ Py_UNICODE *shiftOutStart;
+ unsigned int base64bits = 0;
+ unsigned long base64buffer = 0;
+ Py_UNICODE surrogate = 0;
PyObject *errorHandler = NULL;
PyObject *exc = NULL;
@@ -1509,79 +1600,107 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
}
p = unicode->str;
+ shiftOutStart = p;
e = s + size;
while (s < e) {
- Py_UNICODE ch;
- restart:
- ch = (unsigned char) *s;
+ Py_UNICODE ch = (unsigned char) *s;
- if (inShift) {
- if ((ch == '-') || !B64CHAR(ch)) {
- inShift = 0;
+ if (inShift) { /* in a base-64 section */
+ if (IS_BASE64(ch)) { /* consume a base-64 character */
+ base64buffer = (base64buffer << 6) | FROM_BASE64(ch);
+ base64bits += 6;
s++;
-
- /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate);
- if (bitsleft >= 6) {
- /* The shift sequence has a partial character in it. If
- bitsleft < 6 then we could just classify it as padding
- but that is not the case here */
-
- errmsg = "partial character in shift sequence";
- goto utf7Error;
+ if (base64bits >= 16) {
+ /* we have enough bits for a UTF-16 value */
+ Py_UNICODE outCh = (Py_UNICODE)
+ (base64buffer >> (base64bits-16));
+ base64bits -= 16;
+ base64buffer &= (1 << base64bits) - 1; /* clear high bits */
+ if (surrogate) {
+ /* expecting a second surrogate */
+ if (outCh >= 0xDC00 && outCh <= 0xDFFF) {
+#ifdef Py_UNICODE_WIDE
+ *p++ = (((surrogate & 0x3FF)<<10)
+ | (outCh & 0x3FF)) + 0x10000;
+#else
+ *p++ = surrogate;
+ *p++ = outCh;
+#endif
+ surrogate = 0;
+ }
+ else {
+ surrogate = 0;
+ errmsg = "second surrogate missing";
+ goto utf7Error;
+ }
+ }
+ else if (outCh >= 0xD800 && outCh <= 0xDBFF) {
+ /* first surrogate */
+ surrogate = outCh;
+ }
+ else if (outCh >= 0xDC00 && outCh <= 0xDFFF) {
+ errmsg = "unexpected second surrogate";
+ goto utf7Error;
+ }
+ else {
+ *p++ = outCh;
+ }
}
- /* According to RFC2152 the remaining bits should be zero. We
- choose to signal an error/insert a replacement character
- here so indicate the potential of a misencoded character. */
-
- /* On x86, a << b == a << (b%32) so make sure that bitsleft != 0 */
- if (bitsleft && charsleft << (sizeof(charsleft) * 8 - bitsleft)) {
- errmsg = "non-zero padding bits in shift sequence";
+ }
+ else { /* now leaving a base-64 section */
+ inShift = 0;
+ s++;
+ if (surrogate) {
+ errmsg = "second surrogate missing at end of shift sequence";
goto utf7Error;
}
-
- if (ch == '-') {
- if ((s < e) && (*(s) == '-')) {
- *p++ = '-';
- inShift = 1;
+ if (base64bits > 0) { /* left-over bits */
+ if (base64bits >= 6) {
+ /* We've seen at least one base-64 character */
+ errmsg = "partial character in shift sequence";
+ goto utf7Error;
}
- } else if (SPECIAL(ch,0,0)) {
- errmsg = "unexpected special character";
- goto utf7Error;
- } else {
+ else {
+ /* Some bits remain; they should be zero */
+ if (base64buffer != 0) {
+ errmsg = "non-zero padding bits in shift sequence";
+ goto utf7Error;
+ }
+ }
+ }
+ if (ch != '-') {
+ /* '-' is absorbed; other terminating
+ characters are preserved */
*p++ = ch;
}
- } else {
- charsleft = (charsleft << 6) | UB64(ch);
- bitsleft += 6;
- s++;
- /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate);
}
}
else if ( ch == '+' ) {
startinpos = s-starts;
- s++;
- if (s < e && *s == '-') {
+ s++; /* consume '+' */
+ if (s < e && *s == '-') { /* '+-' encodes '+' */
s++;
*p++ = '+';
- } else
- {
+ }
+ else { /* begin base64-encoded section */
inShift = 1;
- bitsleft = 0;
+ shiftOutStart = p;
+ base64bits = 0;
}
}
- else if (SPECIAL(ch,0,0)) {
- startinpos = s-starts;
- errmsg = "unexpected special character";
+ else if (DECODE_DIRECT(ch)) { /* character decodes as itself */
+ *p++ = ch;
s++;
- goto utf7Error;
}
else {
- *p++ = ch;
+ startinpos = s-starts;
s++;
+ errmsg = "unexpected special character";
+ goto utf7Error;
}
continue;
- utf7Error:
+utf7Error:
outpos = p-PyUnicode_AS_UNICODE(unicode);
endinpos = s-starts;
if (unicode_decode_call_errorhandler(
@@ -1592,23 +1711,33 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
goto onError;
}
- if (inShift && !consumed) {
- outpos = p-PyUnicode_AS_UNICODE(unicode);
- endinpos = size;
- if (unicode_decode_call_errorhandler(
- errors, &errorHandler,
- "utf7", "unterminated shift sequence",
- starts, size, &startinpos, &endinpos, &exc, &s,
- &unicode, &outpos, &p))
- goto onError;
- if (s < e)
- goto restart;
+ /* end of string */
+
+ if (inShift && !consumed) { /* in shift sequence, no more to follow */
+ /* if we're in an inconsistent state, that's an error */
+ if (surrogate ||
+ (base64bits >= 6) ||
+ (base64bits > 0 && base64buffer != 0)) {
+ outpos = p-PyUnicode_AS_UNICODE(unicode);
+ endinpos = size;
+ if (unicode_decode_call_errorhandler(
+ errors, &errorHandler,
+ "utf7", "unterminated shift sequence",
+ starts, size, &startinpos, &endinpos, &exc, &s,
+ &unicode, &outpos, &p))
+ goto onError;
+ }
}
+
+ /* return state */
if (consumed) {
- if(inShift)
+ if (inShift) {
+ p = shiftOutStart; /* back off output */
*consumed = startinpos;
- else
+ }
+ else {
*consumed = s-starts;
+ }
}
if (_PyUnicode_Resize(&unicode, p - PyUnicode_AS_UNICODE(unicode)) < 0)
@@ -1628,27 +1757,27 @@ PyObject *PyUnicode_DecodeUTF7Stateful(const char *s,
PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
Py_ssize_t size,
- int encodeSetO,
- int encodeWhiteSpace,
+ int base64SetO,
+ int base64WhiteSpace,
const char *errors)
{
PyObject *v;
/* It might be possible to tighten this worst case */
- Py_ssize_t cbAllocated = 5 * size;
+ Py_ssize_t allocated = 8 * size;
int inShift = 0;
Py_ssize_t i = 0;
- unsigned int bitsleft = 0;
- unsigned long charsleft = 0;
+ unsigned int base64bits = 0;
+ unsigned long base64buffer = 0;
char * out;
char * start;
- if (cbAllocated / 5 != size)
+ if (allocated / 8 != size)
return PyErr_NoMemory();
if (size == 0)
return PyString_FromStringAndSize(NULL, 0);
- v = PyString_FromStringAndSize(NULL, cbAllocated);
+ v = PyString_FromStringAndSize(NULL, allocated);
if (v == NULL)
return NULL;
@@ -1656,78 +1785,77 @@ PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s,
for (;i < size; ++i) {
Py_UNICODE ch = s[i];
- if (!inShift) {
- if (ch == '+') {
- *out++ = '+';
- *out++ = '-';
- } else if (SPECIAL(ch, encodeSetO, encodeWhiteSpace)) {
- charsleft = ch;
- bitsleft = 16;
- *out++ = '+';
- /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft);
- inShift = bitsleft > 0;
- } else {
- *out++ = (char) ch;
- }
- } else {
- if (!SPECIAL(ch, encodeSetO, encodeWhiteSpace)) {
- *out++ = B64(charsleft << (6-bitsleft));
- charsleft = 0;
- bitsleft = 0;
+ if (inShift) {
+ if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+ /* shifting out */
+ if (base64bits) { /* output remaining bits */
+ *out++ = TO_BASE64(base64buffer << (6-base64bits));
+ base64buffer = 0;
+ base64bits = 0;
+ }
+ inShift = 0;
/* Characters not in the BASE64 set implicitly unshift the sequence
so no '-' is required, except if the character is itself a '-' */
- if (B64CHAR(ch) || ch == '-') {
+ if (IS_BASE64(ch) || ch == '-') {
*out++ = '-';
}
- inShift = 0;
*out++ = (char) ch;
- } else {
- bitsleft += 16;
- charsleft = (charsleft << 16) | ch;
- /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft);
-
- /* If the next character is special then we don't need to terminate
- the shift sequence. If the next character is not a BASE64 character
- or '-' then the shift sequence will be terminated implicitly and we
- don't have to insert a '-'. */
-
- if (bitsleft == 0) {
- if (i + 1 < size) {
- Py_UNICODE ch2 = s[i+1];
-
- if (SPECIAL(ch2, encodeSetO, encodeWhiteSpace)) {
-
- } else if (B64CHAR(ch2) || ch2 == '-') {
- *out++ = '-';
- inShift = 0;
- } else {
- inShift = 0;
- }
-
- }
- else {
+ }
+ else {
+ goto encode_char;
+ }
+ }
+ else { /* not in a shift sequence */
+ if (ch == '+') {
+ *out++ = '+';
*out++ = '-';
- inShift = 0;
- }
- }
}
+ else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
+ *out++ = (char) ch;
+ }
+ else {
+ *out++ = '+';
+ inShift = 1;
+ goto encode_char;
+ }
+ }
+ continue;
+encode_char:
+#ifdef Py_UNICODE_WIDE
+ if (ch >= 0x10000) {
+ /* code first surrogate */
+ base64bits += 16;
+ base64buffer = (base64buffer << 16) | 0xd800 | ((ch-0x10000) >> 10);
+ while (base64bits >= 6) {
+ *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+ base64bits -= 6;
+ }
+ /* prepare second surrogate */
+ ch = 0xDC00 | ((ch-0x10000) & 0x3FF);
+ }
+#endif
+ base64bits += 16;
+ base64buffer = (base64buffer << 16) | ch;
+ while (base64bits >= 6) {
+ *out++ = TO_BASE64(base64buffer >> (base64bits-6));
+ base64bits -= 6;
}
}
- if (bitsleft) {
- *out++= B64(charsleft << (6-bitsleft) );
+ if (base64bits)
+ *out++= TO_BASE64(base64buffer << (6-base64bits) );
+ if (inShift)
*out++ = '-';
- }
- _PyString_Resize(&v, out - start);
+ if (_PyString_Resize(&v, out - start))
+ return NULL;
return v;
}
-#undef SPECIAL
-#undef B64
-#undef B64CHAR
-#undef UB64
-#undef ENCODE
-#undef DECODE
+#undef IS_BASE64
+#undef FROM_BASE64
+#undef TO_BASE64
+#undef DECODE_DIRECT
+#undef ENCODE_DIRECT
/* --- UTF-8 Codec -------------------------------------------------------- */
@@ -2033,7 +2161,8 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s,
/* Cut back to size actually needed. */
nneeded = p - PyString_AS_STRING(v);
assert(nneeded <= nallocated);
- _PyString_Resize(&v, nneeded);
+ if (_PyString_Resize(&v, nneeded))
+ return NULL;
}
return v;
@@ -2077,10 +2206,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. */
@@ -2757,16 +2887,7 @@ PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
message = "malformed \\N character escape";
if (ucnhash_CAPI == NULL) {
/* load the unicode data module */
- PyObject *m, *api;
- m = PyImport_ImportModuleNoBlock("unicodedata");
- if (m == NULL)
- goto ucnhashError;
- api = PyObject_GetAttrString(m, "ucnhash_CAPI");
- Py_DECREF(m);
- if (api == NULL)
- goto ucnhashError;
- ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCObject_AsVoidPtr(api);
- Py_DECREF(api);
+ ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(PyUnicodeData_CAPSULE_NAME, 1);
if (ucnhash_CAPI == NULL)
goto ucnhashError;
}
@@ -3004,7 +3125,8 @@ PyObject *unicodeescape_string(const Py_UNICODE *s,
*p++ = PyString_AS_STRING(repr)[1];
*p = '\0';
- _PyString_Resize(&repr, p - PyString_AS_STRING(repr));
+ if (_PyString_Resize(&repr, p - PyString_AS_STRING(repr)))
+ return NULL;
return repr;
}
@@ -3225,7 +3347,8 @@ PyObject *PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s,
*p++ = (char) ch;
}
*p = '\0';
- _PyString_Resize(&repr, p - q);
+ if (_PyString_Resize(&repr, p - q))
+ return NULL;
return repr;
}
@@ -3564,9 +3687,9 @@ static PyObject *unicode_encode_ucs1(const Py_UNICODE *p,
collstart-startp, collend-startp, &newpos);
if (repunicode == NULL)
goto onError;
- /* need more space? (at least enough for what we
- have+the replacement+the rest of the string, so
- we won't have to check space for encodable characters) */
+ /* need more space? (at least enough for what we have+the
+ replacement+the rest of the string, so we won't have to
+ check space for encodable characters) */
respos = str-PyString_AS_STRING(res);
repsize = PyUnicode_GET_SIZE(repunicode);
requiredsize = respos+repsize+(endp-collend);
@@ -4217,7 +4340,7 @@ PyUnicode_BuildEncodingMap(PyObject* string)
if (!result)
return NULL;
for (i = 0; i < 256; i++) {
- key = value = NULL;
+ value = NULL;
key = PyInt_FromLong(decode[i]);
value = PyInt_FromLong(i);
if (!key || !value)
@@ -5124,27 +5247,27 @@ int PyUnicode_EncodeDecimal(Py_UNICODE *s,
/* --- Helpers ------------------------------------------------------------ */
#include "stringlib/unicodedefs.h"
-
-#define FROM_UNICODE
-
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/partition.h"
+#include "stringlib/split.h"
/* helper macro to fixup start/end slice values */
-#define 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,
@@ -5164,10 +5287,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);
@@ -5222,8 +5345,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;
@@ -5600,305 +5722,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);
- }
-
- Py_DECREF(string);
- return list;
+ list = stringlib_splitlines(
+ (PyObject*) string, PyUnicode_AS_UNICODE(string),
+ PyUnicode_GET_SIZE(string), keepends);
- 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
@@ -5906,28 +5763,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
@@ -5940,10 +5788,14 @@ 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 */
Py_ssize_t i;
+ /* same length */
+ if (str1->length == 0)
+ goto nothing;
if (str1->length == 1) {
/* replace characters */
Py_UNICODE u1, u2;
@@ -5962,8 +5814,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;
@@ -5971,25 +5823,30 @@ 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 {
- Py_ssize_t n, i, j, e;
+ Py_ssize_t n, i, j;
Py_ssize_t product, new_size, delta;
Py_UNICODE *p;
/* replace strings */
- n = stringlib_count(self->str, self->length, str1->str, str1->length);
- 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)); */
@@ -6015,19 +5872,15 @@ 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 */
- 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;
@@ -6083,7 +5936,7 @@ PyDoc_STRVAR(capitalize__doc__,
"S.capitalize() -> unicode\n\
\n\
Return a capitalized version of S, i.e. make the first character\n\
-have upper case.");
+have upper case and the rest lower case.");
static PyObject*
unicode_capitalize(PyUnicodeObject *self)
@@ -6381,8 +6234,6 @@ int PyUnicode_Contains(PyObject *container,
/* Coerce the two arguments */
sub = PyUnicode_FromObject(element);
if (!sub) {
- PyErr_SetString(PyExc_TypeError,
- "'in <string>' requires string as left operand");
return -1;
}
@@ -6457,20 +6308,15 @@ unicode_count(PyUnicodeObject *self, PyObject *args)
Py_ssize_t end = PY_SSIZE_T_MAX;
PyObject *result;
- if (!PyArg_ParseTuple(args, "O|O&O&:count", &substring,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
- return NULL;
-
- substring = (PyUnicodeObject *)PyUnicode_FromObject(
- (PyObject *)substring);
- if (substring == NULL)
+ if (!stringlib_parse_args_finds_unicode("count", args, &substring,
+ &start, &end))
return NULL;
- FIX_START_END(self);
-
+ ADJUST_INDICES(start, end, self->length);
result = PyInt_FromSsize_t(
stringlib_count(self->str + start, end - start,
- substring->str, substring->length)
+ substring->str, substring->length,
+ PY_SSIZE_T_MAX)
);
Py_DECREF(substring);
@@ -6489,13 +6335,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_AsEncodedObject((PyObject *)self, encoding, errors);
if (v == NULL)
@@ -6525,13 +6373,15 @@ as well as any other name registerd with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");
static PyObject *
-unicode_decode(PyUnicodeObject *self, PyObject *args)
+unicode_decode(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:decode", &encoding, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode",
+ kwlist, &encoding, &errors))
return NULL;
v = PyUnicode_AsDecodedObject((PyObject *)self, encoding, errors);
if (v == NULL)
@@ -6649,12 +6499,13 @@ Return -1 on failure.");
static PyObject *
unicode_find(PyUnicodeObject *self, PyObject *args)
{
- PyObject *substring;
+ PyUnicodeObject *substring;
Py_ssize_t start;
Py_ssize_t end;
Py_ssize_t result;
- if (!_ParseTupleFinds(args, &substring, &start, &end))
+ if (!stringlib_parse_args_finds_unicode("find", args, &substring,
+ &start, &end))
return NULL;
result = stringlib_find_slice(
@@ -6715,11 +6566,12 @@ static PyObject *
unicode_index(PyUnicodeObject *self, PyObject *args)
{
Py_ssize_t result;
- PyObject *substring;
+ PyUnicodeObject *substring;
Py_ssize_t start;
Py_ssize_t end;
- if (!_ParseTupleFinds(args, &substring, &start, &end))
+ if (!stringlib_parse_args_finds_unicode("index", args, &substring,
+ &start, &end))
return NULL;
result = stringlib_find_slice(
@@ -7382,12 +7234,13 @@ Return -1 on failure.");
static PyObject *
unicode_rfind(PyUnicodeObject *self, PyObject *args)
{
- PyObject *substring;
+ PyUnicodeObject *substring;
Py_ssize_t start;
Py_ssize_t end;
Py_ssize_t result;
- if (!_ParseTupleFinds(args, &substring, &start, &end))
+ if (!stringlib_parse_args_finds_unicode("rfind", args, &substring,
+ &start, &end))
return NULL;
result = stringlib_rfind_slice(
@@ -7409,12 +7262,13 @@ Like S.rfind() but raise ValueError when the substring is not found.");
static PyObject *
unicode_rindex(PyUnicodeObject *self, PyObject *args)
{
- PyObject *substring;
+ PyUnicodeObject *substring;
Py_ssize_t start;
Py_ssize_t end;
Py_ssize_t result;
- if (!_ParseTupleFinds(args, &substring, &start, &end))
+ if (!stringlib_parse_args_finds_unicode("rindex", args, &substring,
+ &start, &end))
return NULL;
result = stringlib_rfind_slice(
@@ -7793,8 +7647,7 @@ unicode_startswith(PyUnicodeObject *self,
Py_ssize_t end = PY_SSIZE_T_MAX;
int result;
- if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
@@ -7813,8 +7666,12 @@ unicode_startswith(PyUnicodeObject *self,
Py_RETURN_FALSE;
}
substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
- if (substring == NULL)
+ if (substring == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "startswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
return NULL;
+ }
result = tailmatch(self, substring, start, end, -1);
Py_DECREF(substring);
return PyBool_FromLong(result);
@@ -7839,8 +7696,7 @@ unicode_endswith(PyUnicodeObject *self,
Py_ssize_t end = PY_SSIZE_T_MAX;
int result;
- if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
- _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
+ if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
return NULL;
if (PyTuple_Check(subobj)) {
Py_ssize_t i;
@@ -7858,9 +7714,12 @@ unicode_endswith(PyUnicodeObject *self,
Py_RETURN_FALSE;
}
substring = (PyUnicodeObject *)PyUnicode_FromObject(subobj);
- if (substring == NULL)
+ if (substring == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError))
+ PyErr_Format(PyExc_TypeError, "endswith first arg must be str, "
+ "unicode, or tuple, not %s", Py_TYPE(subobj)->tp_name);
return NULL;
-
+ }
result = tailmatch(self, substring, start, end, +1);
Py_DECREF(substring);
return PyBool_FromLong(result);
@@ -7873,7 +7732,8 @@ unicode_endswith(PyUnicodeObject *self,
PyDoc_STRVAR(format__doc__,
"S.format(*args, **kwargs) -> unicode\n\
\n\
-");
+Return a formatted version of S, using substitutions from args and kwargs.\n\
+The substitutions are identified by braces ('{' and '}').");
static PyObject *
unicode__format__(PyObject *self, PyObject *args)
@@ -7907,7 +7767,7 @@ unicode__format__(PyObject *self, PyObject *args)
PyDoc_STRVAR(p_format__doc__,
"S.__format__(format_spec) -> unicode\n\
\n\
-");
+Return a formatted version of S as described by format_spec.");
static PyObject *
unicode__sizeof__(PyUnicodeObject *v)
@@ -7933,7 +7793,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__},
@@ -7949,7 +7809,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__},
- {"decode", (PyCFunction) unicode_decode, METH_VARARGS, decode__doc__},
+ {"decode", (PyCFunction) unicode_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
/* {"maketrans", (PyCFunction) unicode_maketrans, METH_VARARGS, maketrans__doc__}, */
{"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__},
{"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__},
@@ -8164,16 +8024,6 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
}
static int
-doubletounicode(Py_UNICODE *buffer, size_t len, const char *format, double x)
-{
- Py_ssize_t result;
-
- PyOS_ascii_formatd((char *)buffer, len, format, x);
- result = strtounicode(buffer, (char *)buffer);
- return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
-}
-
-static int
longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
{
Py_ssize_t result;
@@ -8187,64 +8037,29 @@ longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
shared with stringobject.c, converting from 8-bit to Unicode after the
formatting is done. */
-static int
-formatfloat(Py_UNICODE *buf,
- size_t buflen,
- int flags,
- int prec,
- int type,
- PyObject *v)
-{
- /* fmt = '%#.' + `prec` + `type`
- worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/
- char fmt[20];
+/* Returns a new reference to a PyUnicode object, or NULL on failure. */
+
+static PyObject *
+formatfloat(PyObject *v, int flags, int prec, int type)
+{
+ char *p;
+ PyObject *result;
double x;
x = PyFloat_AsDouble(v);
if (x == -1.0 && PyErr_Occurred())
- return -1;
+ return NULL;
+
if (prec < 0)
prec = 6;
-#if SIZEOF_INT > 4
- /* make sure that the decimal representation of precision really does
- need at most 10 digits: platforms with sizeof(int) == 8 exist! */
- if (prec > 0x7fffffff) {
- PyErr_SetString(PyExc_OverflowError,
- "outrageously large precision "
- "for formatted float");
- return -1;
- }
-#endif
- if (type == 'f' && fabs(x) >= 1e50)
- type = 'g';
- /* Worst case length calc to ensure no buffer overrun:
-
- 'g' formats:
- fmt = %#.<prec>g
- buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp
- for any double rep.)
- len = 1 + prec + 1 + 2 + 5 = 9 + prec
-
- 'f' formats:
- buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50)
- len = 1 + 50 + 1 + prec = 52 + prec
-
- If prec=0 the effective precision is 1 (the leading digit is
- always given), therefore increase the length by one.
-
- */
- if (((type == 'g' || type == 'G') &&
- buflen <= (size_t)10 + (size_t)prec) ||
- (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) {
- PyErr_SetString(PyExc_OverflowError,
- "formatted float is too long (precision too large?)");
- return -1;
- }
- PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c",
- (flags&F_ALT) ? "#" : "",
- prec, type);
- return doubletounicode(buf, buflen, fmt, x);
+ p = PyOS_double_to_string(x, type, prec,
+ (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL);
+ if (p == NULL)
+ return NULL;
+ result = PyUnicode_FromStringAndSize(p, strlen(p));
+ PyMem_Free(p);
+ return result;
}
static PyObject*
@@ -8414,7 +8229,7 @@ formatchar(Py_UNICODE *buf,
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...)
- FORMATBUFLEN is the length of the buffer in which the floats, ints, &
+ FORMATBUFLEN is the length of the buffer in which the ints &
chars are formatted. XXX This is a magic number. Each formatting
routine does bounds checking to ensure no overflow, but a better
solution may be to malloc a buffer of appropriate size for each
@@ -8485,7 +8300,7 @@ PyObject *PyUnicode_Format(PyObject *format,
Py_UNICODE *pbuf;
Py_UNICODE sign;
Py_ssize_t len;
- Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */
+ Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{int,char}() */
fmt++;
if (*fmt == '(') {
@@ -8746,13 +8561,11 @@ PyObject *PyUnicode_Format(PyObject *format,
case 'F':
case 'g':
case 'G':
- if (c == 'F')
- c = 'f';
- pbuf = formatbuf;
- len = formatfloat(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
- flags, prec, c, v);
- if (len < 0)
+ temp = formatfloat(v, flags, prec, c);
+ if (temp == NULL)
goto onError;
+ pbuf = PyUnicode_AS_UNICODE(temp);
+ len = PyUnicode_GET_SIZE(temp);
sign = 1;
if (flags & F_ZERO)
fill = '0';
@@ -9073,11 +8886,3 @@ _PyUnicode_Fini(void)
#ifdef __cplusplus
}
#endif
-
-
-/*
- Local variables:
- c-basic-offset: 4
- indent-tabs-mode: nil
- End:
-*/
diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h
index 2e9c01b87a..d2ec46b0f8 100644
--- a/Objects/unicodetype_db.h
+++ b/Objects/unicodetype_db.h
@@ -6,23 +6,24 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 32},
{0, 0, 0, 0, 0, 48},
- {0, 0, 0, 0, 0, 6},
- {0, 0, 0, 1, 1, 6},
- {0, 0, 0, 2, 2, 6},
- {0, 0, 0, 3, 3, 6},
- {0, 0, 0, 4, 4, 6},
- {0, 0, 0, 5, 5, 6},
- {0, 0, 0, 6, 6, 6},
- {0, 0, 0, 7, 7, 6},
- {0, 0, 0, 8, 8, 6},
- {0, 0, 0, 9, 9, 6},
+ {0, 0, 0, 0, 0, 518},
+ {0, 0, 0, 1, 1, 518},
+ {0, 0, 0, 2, 2, 518},
+ {0, 0, 0, 3, 3, 518},
+ {0, 0, 0, 4, 4, 518},
+ {0, 0, 0, 5, 5, 518},
+ {0, 0, 0, 6, 6, 518},
+ {0, 0, 0, 7, 7, 518},
+ {0, 0, 0, 8, 8, 518},
+ {0, 0, 0, 9, 9, 518},
{0, 32, 0, 0, 0, 129},
{65504, 0, 65504, 0, 0, 9},
{0, 0, 0, 0, 0, 9},
- {0, 0, 0, 0, 2, 4},
- {0, 0, 0, 0, 3, 4},
+ {0, 0, 0, 0, 2, 516},
+ {0, 0, 0, 0, 3, 516},
{743, 0, 743, 0, 0, 9},
- {0, 0, 0, 0, 1, 4},
+ {0, 0, 0, 0, 1, 516},
+ {0, 0, 0, 0, 0, 512},
{121, 0, 121, 0, 0, 9},
{0, 1, 0, 0, 0, 129},
{65535, 0, 65535, 0, 0, 9},
@@ -60,11 +61,13 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 10795, 0, 0, 0, 129},
{0, 65373, 0, 0, 0, 129},
{0, 10792, 0, 0, 0, 129},
+ {10815, 0, 10815, 0, 0, 9},
{0, 65341, 0, 0, 0, 129},
{0, 69, 0, 0, 0, 129},
{0, 71, 0, 0, 0, 129},
{10783, 0, 10783, 0, 0, 9},
{10780, 0, 10780, 0, 0, 9},
+ {10782, 0, 10782, 0, 0, 9},
{65326, 0, 65326, 0, 0, 9},
{65330, 0, 65330, 0, 0, 9},
{65331, 0, 65331, 0, 0, 9},
@@ -112,12 +115,12 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 48, 0, 0, 0, 129},
{65488, 0, 65488, 0, 0, 9},
{0, 7264, 0, 0, 0, 129},
- {0, 0, 0, 0, 4, 4},
- {0, 0, 0, 0, 5, 4},
- {0, 0, 0, 0, 6, 4},
- {0, 0, 0, 0, 7, 4},
- {0, 0, 0, 0, 8, 4},
- {0, 0, 0, 0, 9, 4},
+ {0, 0, 0, 0, 4, 516},
+ {0, 0, 0, 0, 5, 516},
+ {0, 0, 0, 0, 6, 516},
+ {0, 0, 0, 0, 7, 516},
+ {0, 0, 0, 0, 8, 516},
+ {0, 0, 0, 0, 9, 516},
{42877, 7545, 42877, 0, 0, 265},
{3814, 0, 3814, 0, 0, 9},
{65477, 0, 65477, 0, 0, 9},
@@ -140,14 +143,14 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 65424, 0, 0, 0, 129},
{0, 65408, 0, 0, 0, 129},
{0, 65410, 0, 0, 0, 129},
- {0, 0, 0, 0, 0, 4},
+ {0, 0, 0, 0, 0, 516},
{0, 58019, 0, 0, 0, 129},
{0, 57153, 0, 0, 0, 129},
{0, 57274, 0, 0, 0, 129},
{0, 28, 0, 0, 0, 129},
{65508, 0, 65508, 0, 0, 9},
- {0, 16, 0, 0, 0, 0},
- {65520, 0, 65520, 0, 0, 0},
+ {0, 16, 0, 0, 0, 512},
+ {65520, 0, 65520, 0, 0, 512},
{0, 26, 0, 0, 0, 0},
{65510, 0, 65510, 0, 0, 0},
{0, 54793, 0, 0, 0, 129},
@@ -158,214 +161,507 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 54756, 0, 0, 0, 129},
{0, 54787, 0, 0, 0, 129},
{0, 54753, 0, 0, 0, 129},
+ {0, 54754, 0, 0, 0, 129},
+ {0, 54721, 0, 0, 0, 129},
{58272, 0, 58272, 0, 0, 9},
+ {0, 0, 0, 0, 0, 513},
{42877, 7545, 42877, 0, 0, 385},
{0, 40, 0, 0, 0, 129},
{65496, 0, 65496, 0, 0, 9},
};
/* type indexes */
-#define SHIFT 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, 34, 34, 34,
+ 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, 34, 34, 34, 34, 21, 56, 57, 21, 58, 59,
- 60, 61, 62, 63, 64, 65, 8, 8, 8, 66, 67, 68, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 69, 70, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 71, 72,
- 73, 74, 75, 76, 77, 78, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 79, 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, 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, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 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, 81, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 82, 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,
+ 34, 34, 34, 34, 34, 34, 34, 34, 89, 90, 91, 92, 34, 34, 34, 93, 34, 34,
+ 34, 94, 95, 34, 34, 34, 34, 34, 96, 34, 34, 34, 97, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 98, 99, 100, 34, 34, 34, 34, 34, 34, 101, 102, 34,
+ 34, 34, 34, 34, 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34,
+ 101, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 104, 34, 34, 34, 34, 34, 34, 106, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 107, 108, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 109, 110, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 111, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 112, 34, 34, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 17, 123, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 124, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 125, 126, 127, 128,
+ 129, 130, 34, 34, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 17,
+ 141, 142, 143, 144, 145, 17, 17, 17, 17, 17, 17, 146, 17, 147, 17, 148,
+ 17, 149, 17, 150, 17, 17, 17, 151, 17, 17, 17, 17, 152, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 153, 17, 154, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 155, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 64, 156, 157, 158, 159, 17, 160, 17, 161, 162, 163, 164, 165, 166, 167,
+ 168, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 169, 170, 171, 172,
+ 173, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 174, 175, 176, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 177, 34, 178, 179, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 180, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 181, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 182, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 183, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 84, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 84,
+ 185, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 34, 180, 34, 34, 186, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 187, 17, 64, 188, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 189, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 189,
};
static unsigned char index2[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 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, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
@@ -373,488 +669,448 @@ static unsigned char index2[] = {
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1,
- 1, 1, 1, 1, 17, 18, 1, 19, 1, 1, 1, 20, 16, 1, 1, 1, 1, 1, 14, 14, 14,
+ 1, 1, 1, 1, 17, 18, 1, 19, 1, 1, 1, 20, 16, 1, 21, 21, 21, 1, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 16, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15,
- 15, 15, 15, 15, 15, 15, 21, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 24, 25, 22, 23, 22, 23, 22, 23, 16, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 26, 22, 23, 22, 23, 22, 23, 27, 28, 29, 22, 23, 22, 23, 30, 22, 23,
- 31, 31, 22, 23, 16, 32, 33, 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39,
- 16, 37, 40, 41, 42, 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 16, 16, 22,
- 23, 43, 22, 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 16, 46, 22, 23, 16,
- 47, 46, 46, 46, 46, 48, 49, 50, 48, 49, 50, 48, 49, 50, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 51, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 48, 49, 50, 22,
- 23, 52, 53, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 54, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 16, 16, 16, 16, 16, 55, 22, 23,
- 56, 57, 16, 16, 22, 23, 58, 59, 60, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 61, 62, 16, 63, 64, 16, 65, 65, 16, 66, 16, 67, 16, 16, 16, 16, 65,
- 16, 16, 68, 16, 16, 16, 16, 69, 70, 16, 71, 16, 16, 16, 70, 16, 72, 73,
- 16, 16, 74, 16, 16, 16, 16, 16, 16, 16, 75, 16, 16, 76, 16, 16, 76, 16,
- 16, 16, 16, 76, 77, 78, 78, 79, 16, 16, 16, 16, 16, 80, 16, 46, 16, 16,
+ 15, 15, 15, 15, 15, 15, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 25, 26, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 27, 23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24,
+ 32, 32, 23, 24, 16, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40,
+ 16, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 16, 16, 23,
+ 24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 16, 47, 23, 24, 16,
+ 48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 52, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 49, 50, 51, 23,
+ 24, 53, 54, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 55, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 16, 16, 16, 16, 16, 56, 23, 24,
+ 57, 58, 59, 59, 23, 24, 60, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 63, 64, 65, 66, 67, 16, 68, 68, 16, 69, 16, 70, 16, 16, 16, 16, 68,
+ 16, 16, 71, 16, 16, 16, 16, 72, 73, 16, 74, 16, 16, 16, 73, 16, 75, 76,
+ 16, 16, 77, 16, 16, 16, 16, 16, 16, 16, 78, 16, 16, 79, 16, 16, 79, 16,
+ 16, 16, 16, 79, 80, 81, 81, 82, 16, 16, 16, 16, 16, 83, 16, 47, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46,
- 46, 1, 1, 1, 1, 1, 1, 1, 46, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 47, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22, 23,
- 22, 23, 46, 1, 22, 23, 0, 0, 46, 41, 41, 41, 1, 0, 0, 0, 0, 0, 1, 1, 82,
- 1, 83, 83, 83, 0, 84, 0, 85, 85, 16, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24,
+ 23, 24, 47, 1, 23, 24, 0, 0, 47, 42, 42, 42, 1, 0, 0, 0, 0, 0, 1, 1, 85,
+ 1, 86, 86, 86, 0, 87, 0, 88, 88, 16, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 86, 87, 87, 87, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 88, 15, 15, 15, 15, 15, 15, 15, 15, 15, 89, 90, 90, 91,
- 92, 93, 94, 94, 94, 95, 96, 97, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 98, 99, 100, 16,
- 101, 102, 1, 22, 23, 103, 22, 23, 16, 54, 54, 54, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 14, 14, 14,
+ 89, 90, 90, 90, 16, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 93, 93, 94,
+ 95, 96, 97, 97, 97, 98, 99, 100, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 101, 102, 103,
+ 16, 104, 105, 1, 23, 24, 106, 23, 24, 16, 55, 55, 55, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 1, 1, 1, 1, 1, 1, 1, 1, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 105, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 106, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 0, 0, 46, 1, 1, 1, 1, 1, 1, 0, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 16, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1,
- 1, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 1, 1, 1, 1, 1, 1, 1, 46, 46, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 1, 46, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 1, 1, 1, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46,
- 46, 1, 1, 1, 1, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 0, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 46, 1, 1, 1, 1, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 46, 46, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 0, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 0, 0, 0, 46, 46, 46, 46, 0, 0, 1, 46, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 1, 1, 0, 0, 1, 1, 1, 46, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 46,
- 46, 0, 46, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 46, 46, 46, 46,
- 46, 46, 0, 0, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46,
- 46, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46,
- 46, 0, 46, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1,
- 46, 46, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46,
- 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 1, 46, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 1, 46, 1,
- 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 0, 0, 0, 0, 46, 46, 0, 46, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 1, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 46,
- 0, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0,
- 0, 46, 46, 0, 46, 0, 46, 46, 0, 0, 0, 46, 46, 0, 0, 0, 46, 46, 46, 0, 0,
- 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 1, 1, 1,
- 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 46, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 0, 46, 1, 1,
- 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
- 46, 46, 0, 0, 0, 0, 0, 0, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 1,
- 46, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 46, 0, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0,
- 0, 0, 46, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 1, 1, 0, 0, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46,
- 0, 0, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46,
- 46, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46, 46, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 0, 46, 0, 0, 46, 46, 0, 46, 0, 0, 46,
- 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46,
- 46, 46, 0, 46, 0, 46, 0, 0, 46, 46, 0, 46, 46, 46, 46, 1, 46, 46, 1, 1,
- 1, 1, 1, 1, 0, 1, 1, 46, 0, 0, 46, 46, 46, 46, 46, 0, 46, 0, 1, 1, 1, 1,
- 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 46, 46, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 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, 46, 46, 46, 46, 0, 0, 0, 0, 1, 1,
+ 15, 15, 15, 15, 15, 15, 15, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 108, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 109, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 0, 0, 47, 1, 1, 1, 1, 1, 1, 0,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 16, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 1, 1, 1, 1, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 1, 1, 47,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 47, 47, 1, 1, 1, 1, 47, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 1, 1, 47, 1, 1, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 47, 1,
+ 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47,
+ 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0,
+ 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47, 47, 1,
+ 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47, 47, 1, 1, 21, 21, 21, 21,
+ 21, 21, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47,
+ 0, 47, 47, 0, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0,
+ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 0, 47, 0, 0, 0,
+ 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 47, 47, 47, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 0, 1, 1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,
+ 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0,
+ 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47,
+ 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 47, 47, 0, 47, 47,
+ 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 47, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 0, 47, 47, 47, 47, 47, 47, 0, 0,
+ 0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 0,
+ 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1,
+ 1, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 0, 0, 0, 0, 0, 0,
+ 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 21, 21, 21, 21, 21, 21, 21, 1, 0, 0, 1, 1, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 1, 47, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 47, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 0, 0, 1, 1,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 0,
+ 0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0,
+ 47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 1, 47, 47, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 1, 1, 1, 1, 1, 1, 0, 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1,
- 46, 46, 46, 46, 1, 1, 1, 46, 1, 1, 1, 46, 46, 1, 1, 1, 1, 1, 1, 1, 46,
- 46, 46, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 0, 0, 0, 0, 1, 1, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
- 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
- 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46,
- 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46,
- 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 110, 111, 112, 113, 114,
- 115, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 46, 46,
- 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 1, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 46, 46, 46, 46, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46,
- 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46,
- 1, 1, 1, 1, 46, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0,
- 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46,
- 46, 1, 1, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 0, 0, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46,
- 46, 46, 46, 46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 46, 46, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0,
- 46, 46, 46, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 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,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 47, 47, 47, 47, 1, 1, 1, 47, 1, 1, 1, 47, 47, 1, 1, 1, 1, 1, 1, 1, 47,
+ 47, 47, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 1, 1, 1, 1, 1, 1, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47,
+ 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115,
+ 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 21, 21, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 47, 47, 47, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 47, 1, 1, 1, 1, 47, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1,
+ 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 5, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 1, 1, 1, 0, 0, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 47, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 0, 0, 0, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 46, 116, 16, 16, 16, 117,
+ 16, 47, 119, 16, 16, 16, 120, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 16, 16, 16, 16, 118,
- 16, 16, 119, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 120, 120, 120, 120, 120, 120,
- 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120, 120, 120,
- 120, 120, 0, 0, 121, 121, 121, 121, 121, 121, 0, 0, 120, 120, 120, 120,
- 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 120, 120,
- 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121,
- 120, 120, 120, 120, 120, 120, 0, 0, 121, 121, 121, 121, 121, 121, 0, 0,
- 16, 120, 16, 120, 16, 120, 16, 120, 0, 121, 0, 121, 0, 121, 0, 121, 120,
- 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121,
- 121, 122, 122, 123, 123, 123, 123, 124, 124, 125, 125, 126, 126, 127,
- 127, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 128, 128, 128, 128,
- 128, 128, 128, 128, 120, 120, 120, 120, 120, 120, 120, 120, 128, 128,
- 128, 128, 128, 128, 128, 128, 120, 120, 120, 120, 120, 120, 120, 120,
- 128, 128, 128, 128, 128, 128, 128, 128, 120, 120, 16, 129, 16, 0, 16, 16,
- 121, 121, 130, 130, 131, 1, 132, 1, 1, 1, 16, 129, 16, 0, 16, 16, 133,
- 133, 133, 133, 131, 1, 1, 1, 120, 120, 16, 16, 0, 0, 16, 16, 121, 121,
- 134, 134, 0, 1, 1, 1, 120, 120, 16, 16, 16, 100, 16, 16, 121, 121, 135,
- 135, 103, 1, 1, 1, 0, 0, 16, 129, 16, 0, 16, 16, 136, 136, 137, 137, 131,
- 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 138, 16, 0, 0,
- 110, 111, 112, 113, 114, 115, 1, 1, 1, 1, 1, 16, 138, 20, 17, 18, 110,
- 111, 112, 113, 114, 115, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 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, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 94, 1, 1, 1, 1, 94, 1, 1, 16, 94, 94, 94,
- 16, 16, 94, 94, 94, 16, 1, 94, 1, 1, 1, 94, 94, 94, 94, 94, 1, 1, 1, 1,
- 1, 1, 94, 1, 139, 1, 94, 1, 140, 141, 94, 94, 1, 16, 94, 94, 142, 94, 16,
- 46, 46, 46, 46, 16, 1, 1, 16, 16, 94, 94, 1, 1, 1, 1, 1, 94, 16, 16, 16,
- 16, 1, 1, 1, 1, 143, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
- 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
- 145, 145, 145, 145, 1, 1, 1, 22, 23, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 16, 16, 16, 16, 16, 121, 16, 16, 122, 16, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 123,
+ 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 124,
+ 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124, 124, 124, 124, 0,
+ 0, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124,
+ 124, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124,
+ 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, 124,
+ 124, 124, 124, 0, 0, 16, 123, 16, 123, 16, 123, 16, 123, 0, 124, 0, 124,
+ 0, 124, 0, 124, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124,
+ 124, 124, 124, 124, 124, 125, 125, 126, 126, 126, 126, 127, 127, 128,
+ 128, 129, 129, 130, 130, 0, 0, 123, 123, 123, 123, 123, 123, 123, 123,
+ 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123, 123, 123,
+ 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 123, 123,
+ 123, 123, 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, 123, 123, 16,
+ 132, 16, 0, 16, 16, 124, 124, 133, 133, 134, 1, 135, 1, 1, 1, 16, 132,
+ 16, 0, 16, 16, 136, 136, 136, 136, 134, 1, 1, 1, 123, 123, 16, 16, 0, 0,
+ 16, 16, 124, 124, 137, 137, 0, 1, 1, 1, 123, 123, 16, 16, 16, 103, 16,
+ 16, 124, 124, 138, 138, 106, 1, 1, 1, 0, 0, 16, 132, 16, 0, 16, 16, 139,
+ 139, 140, 140, 134, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 141, 47, 0, 0, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 47, 141,
+ 20, 17, 18, 113, 114, 115, 116, 117, 118, 1, 1, 1, 1, 1, 0, 47, 47, 47,
+ 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 97, 1, 1, 1, 1, 97, 1, 1,
+ 16, 97, 97, 97, 16, 16, 97, 97, 97, 16, 1, 97, 1, 1, 1, 97, 97, 97, 97,
+ 97, 1, 1, 1, 1, 1, 1, 97, 1, 142, 1, 97, 1, 143, 144, 97, 97, 1, 16, 97,
+ 97, 145, 97, 16, 47, 47, 47, 47, 16, 1, 1, 16, 16, 97, 97, 1, 1, 1, 1, 1,
+ 97, 16, 16, 16, 16, 1, 1, 1, 1, 146, 1, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 147, 147, 147, 147, 147, 147, 147, 147,
+ 147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148,
+ 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 21, 21, 21, 23, 24, 21,
+ 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20,
- 17, 18, 110, 111, 112, 113, 114, 115, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 20, 17, 18, 110, 111, 112, 113, 114, 115, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 20, 17, 18, 110, 111, 112, 113, 114, 115, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
- 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 138, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 110, 111, 112, 113, 114, 115, 1, 138, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 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, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1,
- 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 110, 111, 112, 113,
- 114, 115, 1, 20, 17, 18, 110, 111, 112, 113, 114, 115, 1, 20, 17, 18,
- 110, 111, 112, 113, 114, 115, 1, 1, 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, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113,
+ 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,
+ 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
+ 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
+ 141, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 17, 18, 113, 114, 115,
+ 116, 117, 118, 21, 141, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
+ 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 17, 18, 113, 114, 115, 116,
+ 117, 118, 21, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 20, 17, 18,
+ 113, 114, 115, 116, 117, 118, 21, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -862,563 +1118,2220 @@ static unsigned char index2[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
- 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 0, 22, 23, 148, 149, 150, 151, 152, 22, 23, 22,
- 23, 22, 23, 153, 154, 155, 0, 16, 22, 23, 16, 22, 23, 16, 16, 16, 16, 16,
- 16, 46, 0, 0, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 16, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46,
- 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46,
- 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46,
- 0, 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, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 0, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 0,
+ 23, 24, 151, 152, 153, 154, 155, 23, 24, 23, 24, 23, 24, 156, 157, 158,
+ 159, 16, 23, 24, 16, 23, 24, 16, 16, 16, 16, 16, 16, 47, 160, 160, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 16, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 21, 1, 1, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0,
+ 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47,
+ 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 46, 46,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46,
- 1, 1, 1, 1, 1, 46, 46, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 0, 1, 1, 1, 1, 46, 46, 46, 1, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 46, 46, 46, 0,
- 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 47, 47, 21, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 1, 1, 21, 21,
+ 21, 47, 47, 1, 1, 1, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 0, 1, 1, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 1, 21, 21, 21, 21, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 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, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46,
- 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 46, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 46, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
- 22, 23, 22, 23, 22, 23, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 1, 1, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 16, 16, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22,
- 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 46, 16, 16, 16, 16, 16, 16,
- 16, 16, 22, 23, 22, 23, 157, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 46,
- 1, 1, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46,
- 46, 46, 1, 46, 46, 46, 1, 46, 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16,
- 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0,
- 0, 0, 0, 46, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 46, 0,
- 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0,
- 0, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 1, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1,
- 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0,
- 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46,
- 46, 46, 46, 0, 0, 46, 46, 46, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 162, 47, 47, 162,
+ 47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47,
+ 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 162,
+ 162, 162, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 162, 162, 162, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 162, 162, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 47,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 47, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 47, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+ 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 16, 16, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 47, 16, 16, 16, 16,
+ 16, 16, 16, 16, 23, 24, 23, 24, 163, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+ 24, 47, 1, 1, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 1, 47, 47, 47, 1, 47, 47, 47, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 0, 0, 0, 0, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 47, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 1, 1, 1,
+ 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 1, 1, 47, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 1, 47, 1, 1, 1, 47, 47, 1, 1, 47, 47, 47, 47,
+ 47, 1, 1, 47, 1, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 162, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 47, 1, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 47, 47, 47, 47, 47, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1,
+ 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47,
+ 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47,
+ 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 21, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 46, 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, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46,
- 46, 46, 46, 46, 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, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
- 158, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 0, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 0, 46, 46, 0, 0, 0, 46, 0, 0, 46, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1,
- 1, 1, 0, 0, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 46, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 46, 46, 46, 46, 0, 46,
- 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 1, 1, 1, 0,
- 0, 0, 0, 1, 20, 17, 18, 110, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21,
+ 47, 47, 47, 47, 47, 47, 47, 47, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 1, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 1, 21,
+ 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 21,
+ 21, 21, 21, 21, 21, 0, 0, 0, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 1, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 20,
+ 17, 18, 113, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 21, 21, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 21, 21, 21,
+ 21, 21, 21, 21, 21, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 20, 17, 18, 113, 114, 115, 116, 117, 118, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 0, 1, 1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 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, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 94, 0, 94, 94, 0, 0, 94, 0, 0, 94, 94, 0, 0,
- 94, 94, 94, 94, 0, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16, 16, 0, 16,
- 0, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94,
- 94, 0, 94, 94, 94, 94, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 0, 94, 94,
- 94, 94, 94, 94, 94, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 94, 0, 94,
- 94, 94, 94, 0, 94, 94, 94, 94, 94, 0, 94, 0, 0, 0, 94, 94, 94, 94, 94,
- 94, 94, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 16,
+ 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16,
+ 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16,
+ 16, 16, 97, 0, 97, 97, 0, 0, 97, 0, 0, 97, 97, 0, 0, 97, 97, 97, 97, 0,
+ 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 0, 16, 0, 16, 16, 16, 16,
+ 16, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97,
+ 97, 97, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 0, 97, 97, 97, 97, 97, 97,
+ 97, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 0, 97, 97, 97, 97, 0, 97,
+ 97, 97, 97, 97, 0, 97, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 0, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 1, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1,
- 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 1, 16, 16, 16, 16,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16,
+ 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16,
+ 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 1,
+ 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 1, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 94, 94, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16,
- 16, 16, 16, 16, 94, 16, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 16, 16, 16, 16, 16, 97,
+ 16, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
- 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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,
+ 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, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 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, 141, 141, 20, 17, 18, 113, 114, 115, 116, 117, 118, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47,
+ 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 162, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
};
+/* Returns the numeric value as double for Unicode characters
+ * having this property, -1.0 otherwise.
+ */
+double _PyUnicode_ToNumeric(Py_UNICODE ch)
+{
+ switch (ch) {
+ case 0x0F33:
+ return (double) -1.0/2.0;
+ case 0x0030:
+ case 0x0660:
+ case 0x06F0:
+ case 0x07C0:
+ case 0x0966:
+ case 0x09E6:
+ case 0x0A66:
+ case 0x0AE6:
+ case 0x0B66:
+ case 0x0BE6:
+ case 0x0C66:
+ case 0x0C78:
+ case 0x0CE6:
+ case 0x0D66:
+ case 0x0E50:
+ case 0x0ED0:
+ case 0x0F20:
+ case 0x1040:
+ case 0x1090:
+ case 0x17E0:
+ case 0x17F0:
+ case 0x1810:
+ case 0x1946:
+ case 0x19D0:
+ case 0x1A80:
+ case 0x1A90:
+ case 0x1B50:
+ case 0x1BB0:
+ case 0x1C40:
+ case 0x1C50:
+ case 0x2070:
+ case 0x2080:
+ case 0x2189:
+ case 0x24EA:
+ case 0x24FF:
+ case 0x3007:
+ case 0x96F6:
+ case 0xA620:
+ case 0xA6EF:
+ case 0xA8D0:
+ case 0xA900:
+ case 0xA9D0:
+ case 0xAA50:
+ case 0xABF0:
+ case 0xF9B2:
+ case 0xFF10:
+#ifdef Py_UNICODE_WIDE
+ case 0x1018A:
+ case 0x104A0:
+ case 0x1D7CE:
+ case 0x1D7D8:
+ case 0x1D7E2:
+ case 0x1D7EC:
+ case 0x1D7F6:
+ case 0x1F100:
+ case 0x1F101:
+#endif
+ return (double) 0.0;
+ case 0x0031:
+ case 0x00B9:
+ case 0x0661:
+ case 0x06F1:
+ case 0x07C1:
+ case 0x0967:
+ case 0x09E7:
+ case 0x0A67:
+ case 0x0AE7:
+ case 0x0B67:
+ case 0x0BE7:
+ case 0x0C67:
+ case 0x0C79:
+ case 0x0C7C:
+ case 0x0CE7:
+ case 0x0D67:
+ case 0x0E51:
+ case 0x0ED1:
+ case 0x0F21:
+ case 0x1041:
+ case 0x1091:
+ case 0x1369:
+ case 0x17E1:
+ case 0x17F1:
+ case 0x1811:
+ case 0x1947:
+ case 0x19D1:
+ case 0x19DA:
+ case 0x1A81:
+ case 0x1A91:
+ case 0x1B51:
+ case 0x1BB1:
+ case 0x1C41:
+ case 0x1C51:
+ case 0x2081:
+ case 0x215F:
+ case 0x2160:
+ case 0x2170:
+ case 0x2460:
+ case 0x2474:
+ case 0x2488:
+ case 0x24F5:
+ case 0x2776:
+ case 0x2780:
+ case 0x278A:
+ case 0x3021:
+ case 0x3192:
+ case 0x3220:
+ case 0x3280:
+ case 0x4E00:
+ case 0x58F1:
+ case 0x58F9:
+ case 0x5E7A:
+ case 0x5F0C:
+ case 0xA621:
+ case 0xA6E6:
+ case 0xA8D1:
+ case 0xA901:
+ case 0xA9D1:
+ case 0xAA51:
+ case 0xABF1:
+ case 0xFF11:
+#ifdef Py_UNICODE_WIDE
+ case 0x10107:
+ case 0x10142:
+ case 0x10158:
+ case 0x10159:
+ case 0x1015A:
+ case 0x10320:
+ case 0x103D1:
+ case 0x104A1:
+ case 0x10858:
+ case 0x10916:
+ case 0x10A40:
+ case 0x10A7D:
+ case 0x10B58:
+ case 0x10B78:
+ case 0x10E60:
+ case 0x12415:
+ case 0x1241E:
+ case 0x1242C:
+ case 0x12434:
+ case 0x1244F:
+ case 0x12458:
+ case 0x1D360:
+ case 0x1D7CF:
+ case 0x1D7D9:
+ case 0x1D7E3:
+ case 0x1D7ED:
+ case 0x1D7F7:
+ case 0x1F102:
+ case 0x2092A:
+#endif
+ return (double) 1.0;
+ case 0x2152:
+ return (double) 1.0/10.0;
+ case 0x09F4:
+ case 0xA833:
+ return (double) 1.0/16.0;
+ case 0x00BD:
+ case 0x0D74:
+ case 0x0F2A:
+ case 0x2CFD:
+ case 0xA831:
+#ifdef Py_UNICODE_WIDE
+ case 0x10141:
+ case 0x10175:
+ case 0x10176:
+ case 0x10E7B:
+#endif
+ return (double) 1.0/2.0;
+ case 0x2153:
+#ifdef Py_UNICODE_WIDE
+ case 0x10E7D:
+ case 0x1245A:
+ case 0x1245D:
+#endif
+ return (double) 1.0/3.0;
+ case 0x00BC:
+ case 0x09F7:
+ case 0x0D73:
+ case 0xA830:
+#ifdef Py_UNICODE_WIDE
+ case 0x10140:
+ case 0x10E7C:
+ case 0x12460:
+ case 0x12462:
+#endif
+ return (double) 1.0/4.0;
+ case 0x2155:
+ return (double) 1.0/5.0;
+ case 0x2159:
+#ifdef Py_UNICODE_WIDE
+ case 0x12461:
+#endif
+ return (double) 1.0/6.0;
+ case 0x2150:
+ return (double) 1.0/7.0;
+ case 0x09F5:
+ case 0x215B:
+ case 0xA834:
+#ifdef Py_UNICODE_WIDE
+ case 0x1245F:
+#endif
+ return (double) 1.0/8.0;
+ case 0x2151:
+ return (double) 1.0/9.0;
+ case 0x0BF0:
+ case 0x0D70:
+ case 0x1372:
+ case 0x2169:
+ case 0x2179:
+ case 0x2469:
+ case 0x247D:
+ case 0x2491:
+ case 0x24FE:
+ case 0x277F:
+ case 0x2789:
+ case 0x2793:
+ case 0x3038:
+ case 0x3229:
+ case 0x3289:
+ case 0x4EC0:
+ case 0x5341:
+ case 0x62FE:
+ case 0xF973:
+ case 0xF9FD:
+#ifdef Py_UNICODE_WIDE
+ case 0x10110:
+ case 0x10149:
+ case 0x10150:
+ case 0x10157:
+ case 0x10160:
+ case 0x10161:
+ case 0x10162:
+ case 0x10163:
+ case 0x10164:
+ case 0x10322:
+ case 0x103D3:
+ case 0x1085B:
+ case 0x10917:
+ case 0x10A44:
+ case 0x10B5C:
+ case 0x10B7C:
+ case 0x10E69:
+ case 0x1D369:
+#endif
+ return (double) 10.0;
+ case 0x0BF1:
+ case 0x0D71:
+ case 0x137B:
+ case 0x216D:
+ case 0x217D:
+ case 0x4F70:
+ case 0x767E:
+ case 0x964C:
+#ifdef Py_UNICODE_WIDE
+ case 0x10119:
+ case 0x1014B:
+ case 0x10152:
+ case 0x1016A:
+ case 0x103D5:
+ case 0x1085D:
+ case 0x10919:
+ case 0x10A46:
+ case 0x10B5E:
+ case 0x10B7E:
+ case 0x10E72:
+#endif
+ return (double) 100.0;
+ case 0x0BF2:
+ case 0x0D72:
+ case 0x216F:
+ case 0x217F:
+ case 0x2180:
+ case 0x4EDF:
+ case 0x5343:
+ case 0x9621:
+#ifdef Py_UNICODE_WIDE
+ case 0x10122:
+ case 0x1014D:
+ case 0x10154:
+ case 0x10171:
+ case 0x1085E:
+ case 0x10A47:
+ case 0x10B5F:
+ case 0x10B7F:
+#endif
+ return (double) 1000.0;
+ case 0x137C:
+ case 0x2182:
+ case 0x4E07:
+ case 0x842C:
+#ifdef Py_UNICODE_WIDE
+ case 0x1012B:
+ case 0x10155:
+ case 0x1085F:
+#endif
+ return (double) 10000.0;
+ case 0x2188:
+ return (double) 100000.0;
+ case 0x4EBF:
+ case 0x5104:
+ return (double) 100000000.0;
+ case 0x5146:
+ return (double) 1000000000000.0;
+ case 0x216A:
+ case 0x217A:
+ case 0x246A:
+ case 0x247E:
+ case 0x2492:
+ case 0x24EB:
+ return (double) 11.0;
+ case 0x0F2F:
+ return (double) 11.0/2.0;
+ case 0x216B:
+ case 0x217B:
+ case 0x246B:
+ case 0x247F:
+ case 0x2493:
+ case 0x24EC:
+ return (double) 12.0;
+ case 0x246C:
+ case 0x2480:
+ case 0x2494:
+ case 0x24ED:
+ return (double) 13.0;
+ case 0x0F30:
+ return (double) 13.0/2.0;
+ case 0x246D:
+ case 0x2481:
+ case 0x2495:
+ case 0x24EE:
+ return (double) 14.0;
+ case 0x246E:
+ case 0x2482:
+ case 0x2496:
+ case 0x24EF:
+ return (double) 15.0;
+ case 0x0F31:
+ return (double) 15.0/2.0;
+ case 0x09F9:
+ case 0x246F:
+ case 0x2483:
+ case 0x2497:
+ case 0x24F0:
+ return (double) 16.0;
+ case 0x16EE:
+ case 0x2470:
+ case 0x2484:
+ case 0x2498:
+ case 0x24F1:
+ return (double) 17.0;
+ case 0x0F32:
+ return (double) 17.0/2.0;
+ case 0x16EF:
+ case 0x2471:
+ case 0x2485:
+ case 0x2499:
+ case 0x24F2:
+ return (double) 18.0;
+ case 0x16F0:
+ case 0x2472:
+ case 0x2486:
+ case 0x249A:
+ case 0x24F3:
+ return (double) 19.0;
+ case 0x0032:
+ case 0x00B2:
+ case 0x0662:
+ case 0x06F2:
+ case 0x07C2:
+ case 0x0968:
+ case 0x09E8:
+ case 0x0A68:
+ case 0x0AE8:
+ case 0x0B68:
+ case 0x0BE8:
+ case 0x0C68:
+ case 0x0C7A:
+ case 0x0C7D:
+ case 0x0CE8:
+ case 0x0D68:
+ case 0x0E52:
+ case 0x0ED2:
+ case 0x0F22:
+ case 0x1042:
+ case 0x1092:
+ case 0x136A:
+ case 0x17E2:
+ case 0x17F2:
+ case 0x1812:
+ case 0x1948:
+ case 0x19D2:
+ case 0x1A82:
+ case 0x1A92:
+ case 0x1B52:
+ case 0x1BB2:
+ case 0x1C42:
+ case 0x1C52:
+ case 0x2082:
+ case 0x2161:
+ case 0x2171:
+ case 0x2461:
+ case 0x2475:
+ case 0x2489:
+ case 0x24F6:
+ case 0x2777:
+ case 0x2781:
+ case 0x278B:
+ case 0x3022:
+ case 0x3193:
+ case 0x3221:
+ case 0x3281:
+ case 0x3483:
+ case 0x4E8C:
+ case 0x5169:
+ case 0x5F0D:
+ case 0x5F10:
+ case 0x8CAE:
+ case 0x8CB3:
+ case 0x8D30:
+ case 0xA622:
+ case 0xA6E7:
+ case 0xA8D2:
+ case 0xA902:
+ case 0xA9D2:
+ case 0xAA52:
+ case 0xABF2:
+ case 0xF978:
+ case 0xFF12:
+#ifdef Py_UNICODE_WIDE
+ case 0x10108:
+ case 0x1015B:
+ case 0x1015C:
+ case 0x1015D:
+ case 0x1015E:
+ case 0x103D2:
+ case 0x104A2:
+ case 0x10859:
+ case 0x1091A:
+ case 0x10A41:
+ case 0x10B59:
+ case 0x10B79:
+ case 0x10E61:
+ case 0x12400:
+ case 0x12416:
+ case 0x1241F:
+ case 0x12423:
+ case 0x1242D:
+ case 0x12435:
+ case 0x1244A:
+ case 0x12450:
+ case 0x12459:
+ case 0x1D361:
+ case 0x1D7D0:
+ case 0x1D7DA:
+ case 0x1D7E4:
+ case 0x1D7EE:
+ case 0x1D7F8:
+ case 0x1F103:
+ case 0x22390:
+#endif
+ return (double) 2.0;
+ case 0x2154:
+#ifdef Py_UNICODE_WIDE
+ case 0x10177:
+ case 0x10E7E:
+ case 0x1245B:
+ case 0x1245E:
+#endif
+ return (double) 2.0/3.0;
+ case 0x2156:
+ return (double) 2.0/5.0;
+ case 0x1373:
+ case 0x2473:
+ case 0x2487:
+ case 0x249B:
+ case 0x24F4:
+ case 0x3039:
+ case 0x5344:
+ case 0x5EFF:
+#ifdef Py_UNICODE_WIDE
+ case 0x10111:
+ case 0x103D4:
+ case 0x1085C:
+ case 0x10918:
+ case 0x10A45:
+ case 0x10B5D:
+ case 0x10B7D:
+ case 0x10E6A:
+ case 0x1D36A:
+#endif
+ return (double) 20.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011A:
+ case 0x10E73:
+ return (double) 200.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10123:
+ return (double) 2000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012C:
+ return (double) 20000.0;
+#endif
+ case 0x3251:
+ return (double) 21.0;
+ case 0x3252:
+ return (double) 22.0;
+ case 0x3253:
+ return (double) 23.0;
+ case 0x3254:
+ return (double) 24.0;
+ case 0x3255:
+ return (double) 25.0;
+ case 0x3256:
+ return (double) 26.0;
+ case 0x3257:
+ return (double) 27.0;
+ case 0x3258:
+ return (double) 28.0;
+ case 0x3259:
+ return (double) 29.0;
+ case 0x0033:
+ case 0x00B3:
+ case 0x0663:
+ case 0x06F3:
+ case 0x07C3:
+ case 0x0969:
+ case 0x09E9:
+ case 0x0A69:
+ case 0x0AE9:
+ case 0x0B69:
+ case 0x0BE9:
+ case 0x0C69:
+ case 0x0C7B:
+ case 0x0C7E:
+ case 0x0CE9:
+ case 0x0D69:
+ case 0x0E53:
+ case 0x0ED3:
+ case 0x0F23:
+ case 0x1043:
+ case 0x1093:
+ case 0x136B:
+ case 0x17E3:
+ case 0x17F3:
+ case 0x1813:
+ case 0x1949:
+ case 0x19D3:
+ case 0x1A83:
+ case 0x1A93:
+ case 0x1B53:
+ case 0x1BB3:
+ case 0x1C43:
+ case 0x1C53:
+ case 0x2083:
+ case 0x2162:
+ case 0x2172:
+ case 0x2462:
+ case 0x2476:
+ case 0x248A:
+ case 0x24F7:
+ case 0x2778:
+ case 0x2782:
+ case 0x278C:
+ case 0x3023:
+ case 0x3194:
+ case 0x3222:
+ case 0x3282:
+ case 0x4E09:
+ case 0x4EE8:
+ case 0x53C1:
+ case 0x53C2:
+ case 0x53C3:
+ case 0x53C4:
+ case 0x5F0E:
+ case 0xA623:
+ case 0xA6E8:
+ case 0xA8D3:
+ case 0xA903:
+ case 0xA9D3:
+ case 0xAA53:
+ case 0xABF3:
+ case 0xF96B:
+ case 0xFF13:
+#ifdef Py_UNICODE_WIDE
+ case 0x10109:
+ case 0x104A3:
+ case 0x1085A:
+ case 0x1091B:
+ case 0x10A42:
+ case 0x10B5A:
+ case 0x10B7A:
+ case 0x10E62:
+ case 0x12401:
+ case 0x12408:
+ case 0x12417:
+ case 0x12420:
+ case 0x12424:
+ case 0x12425:
+ case 0x1242E:
+ case 0x1242F:
+ case 0x12436:
+ case 0x12437:
+ case 0x1243A:
+ case 0x1243B:
+ case 0x1244B:
+ case 0x12451:
+ case 0x1D362:
+ case 0x1D7D1:
+ case 0x1D7DB:
+ case 0x1D7E5:
+ case 0x1D7EF:
+ case 0x1D7F9:
+ case 0x1F104:
+ case 0x20AFD:
+ case 0x20B19:
+ case 0x22998:
+ case 0x23B1B:
+#endif
+ return (double) 3.0;
+ case 0x09F6:
+ case 0xA835:
+ return (double) 3.0/16.0;
+ case 0x0F2B:
+ return (double) 3.0/2.0;
+ case 0x00BE:
+ case 0x09F8:
+ case 0x0D75:
+ case 0xA832:
+#ifdef Py_UNICODE_WIDE
+ case 0x10178:
+#endif
+ return (double) 3.0/4.0;
+ case 0x2157:
+ return (double) 3.0/5.0;
+ case 0x215C:
+ return (double) 3.0/8.0;
+ case 0x1374:
+ case 0x303A:
+ case 0x325A:
+ case 0x5345:
+#ifdef Py_UNICODE_WIDE
+ case 0x10112:
+ case 0x10165:
+ case 0x10E6B:
+ case 0x1D36B:
+ case 0x20983:
+#endif
+ return (double) 30.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011B:
+ case 0x1016B:
+ case 0x10E74:
+ return (double) 300.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10124:
+ return (double) 3000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012D:
+ return (double) 30000.0;
+#endif
+ case 0x325B:
+ return (double) 31.0;
+ case 0x325C:
+ return (double) 32.0;
+ case 0x325D:
+ return (double) 33.0;
+ case 0x325E:
+ return (double) 34.0;
+ case 0x325F:
+ return (double) 35.0;
+ case 0x32B1:
+ return (double) 36.0;
+ case 0x32B2:
+ return (double) 37.0;
+ case 0x32B3:
+ return (double) 38.0;
+ case 0x32B4:
+ return (double) 39.0;
+ case 0x0034:
+ case 0x0664:
+ case 0x06F4:
+ case 0x07C4:
+ case 0x096A:
+ case 0x09EA:
+ case 0x0A6A:
+ case 0x0AEA:
+ case 0x0B6A:
+ case 0x0BEA:
+ case 0x0C6A:
+ case 0x0CEA:
+ case 0x0D6A:
+ case 0x0E54:
+ case 0x0ED4:
+ case 0x0F24:
+ case 0x1044:
+ case 0x1094:
+ case 0x136C:
+ case 0x17E4:
+ case 0x17F4:
+ case 0x1814:
+ case 0x194A:
+ case 0x19D4:
+ case 0x1A84:
+ case 0x1A94:
+ case 0x1B54:
+ case 0x1BB4:
+ case 0x1C44:
+ case 0x1C54:
+ case 0x2074:
+ case 0x2084:
+ case 0x2163:
+ case 0x2173:
+ case 0x2463:
+ case 0x2477:
+ case 0x248B:
+ case 0x24F8:
+ case 0x2779:
+ case 0x2783:
+ case 0x278D:
+ case 0x3024:
+ case 0x3195:
+ case 0x3223:
+ case 0x3283:
+ case 0x4E96:
+ case 0x56DB:
+ case 0x8086:
+ case 0xA624:
+ case 0xA6E9:
+ case 0xA8D4:
+ case 0xA904:
+ case 0xA9D4:
+ case 0xAA54:
+ case 0xABF4:
+ case 0xFF14:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010A:
+ case 0x104A4:
+ case 0x10A43:
+ case 0x10B5B:
+ case 0x10B7B:
+ case 0x10E63:
+ case 0x12402:
+ case 0x12409:
+ case 0x1240F:
+ case 0x12418:
+ case 0x12421:
+ case 0x12426:
+ case 0x12430:
+ case 0x12438:
+ case 0x1243C:
+ case 0x1243D:
+ case 0x1243E:
+ case 0x1243F:
+ case 0x1244C:
+ case 0x12452:
+ case 0x12453:
+ case 0x1D363:
+ case 0x1D7D2:
+ case 0x1D7DC:
+ case 0x1D7E6:
+ case 0x1D7F0:
+ case 0x1D7FA:
+ case 0x1F105:
+ case 0x20064:
+ case 0x200E2:
+ case 0x2626D:
+#endif
+ return (double) 4.0;
+ case 0x2158:
+ return (double) 4.0/5.0;
+ case 0x1375:
+ case 0x32B5:
+ case 0x534C:
+#ifdef Py_UNICODE_WIDE
+ case 0x10113:
+ case 0x10E6C:
+ case 0x1D36C:
+ case 0x2098C:
+ case 0x2099C:
+#endif
+ return (double) 40.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011C:
+ case 0x10E75:
+ return (double) 400.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10125:
+ return (double) 4000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012E:
+ return (double) 40000.0;
+#endif
+ case 0x32B6:
+ return (double) 41.0;
+ case 0x32B7:
+ return (double) 42.0;
+ case 0x32B8:
+ return (double) 43.0;
+ case 0x32B9:
+ return (double) 44.0;
+ case 0x32BA:
+ return (double) 45.0;
+ case 0x32BB:
+ return (double) 46.0;
+ case 0x32BC:
+ return (double) 47.0;
+ case 0x32BD:
+ return (double) 48.0;
+ case 0x32BE:
+ return (double) 49.0;
+ case 0x0035:
+ case 0x0665:
+ case 0x06F5:
+ case 0x07C5:
+ case 0x096B:
+ case 0x09EB:
+ case 0x0A6B:
+ case 0x0AEB:
+ case 0x0B6B:
+ case 0x0BEB:
+ case 0x0C6B:
+ case 0x0CEB:
+ case 0x0D6B:
+ case 0x0E55:
+ case 0x0ED5:
+ case 0x0F25:
+ case 0x1045:
+ case 0x1095:
+ case 0x136D:
+ case 0x17E5:
+ case 0x17F5:
+ case 0x1815:
+ case 0x194B:
+ case 0x19D5:
+ case 0x1A85:
+ case 0x1A95:
+ case 0x1B55:
+ case 0x1BB5:
+ case 0x1C45:
+ case 0x1C55:
+ case 0x2075:
+ case 0x2085:
+ case 0x2164:
+ case 0x2174:
+ case 0x2464:
+ case 0x2478:
+ case 0x248C:
+ case 0x24F9:
+ case 0x277A:
+ case 0x2784:
+ case 0x278E:
+ case 0x3025:
+ case 0x3224:
+ case 0x3284:
+ case 0x3405:
+ case 0x382A:
+ case 0x4E94:
+ case 0x4F0D:
+ case 0xA625:
+ case 0xA6EA:
+ case 0xA8D5:
+ case 0xA905:
+ case 0xA9D5:
+ case 0xAA55:
+ case 0xABF5:
+ case 0xFF15:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010B:
+ case 0x10143:
+ case 0x10148:
+ case 0x1014F:
+ case 0x1015F:
+ case 0x10173:
+ case 0x10321:
+ case 0x104A5:
+ case 0x10E64:
+ case 0x12403:
+ case 0x1240A:
+ case 0x12410:
+ case 0x12419:
+ case 0x12422:
+ case 0x12427:
+ case 0x12431:
+ case 0x12439:
+ case 0x1244D:
+ case 0x12454:
+ case 0x12455:
+ case 0x1D364:
+ case 0x1D7D3:
+ case 0x1D7DD:
+ case 0x1D7E7:
+ case 0x1D7F1:
+ case 0x1D7FB:
+ case 0x1F106:
+ case 0x20121:
+#endif
+ return (double) 5.0;
+ case 0x0F2C:
+ return (double) 5.0/2.0;
+ case 0x215A:
+#ifdef Py_UNICODE_WIDE
+ case 0x1245C:
+#endif
+ return (double) 5.0/6.0;
+ case 0x215D:
+ return (double) 5.0/8.0;
+ case 0x1376:
+ case 0x216C:
+ case 0x217C:
+ case 0x2186:
+ case 0x32BF:
+#ifdef Py_UNICODE_WIDE
+ case 0x10114:
+ case 0x10144:
+ case 0x1014A:
+ case 0x10151:
+ case 0x10166:
+ case 0x10167:
+ case 0x10168:
+ case 0x10169:
+ case 0x10174:
+ case 0x10323:
+ case 0x10A7E:
+ case 0x10E6D:
+ case 0x1D36D:
+#endif
+ return (double) 50.0;
+ case 0x216E:
+ case 0x217E:
+#ifdef Py_UNICODE_WIDE
+ case 0x1011D:
+ case 0x10145:
+ case 0x1014C:
+ case 0x10153:
+ case 0x1016C:
+ case 0x1016D:
+ case 0x1016E:
+ case 0x1016F:
+ case 0x10170:
+ case 0x10E76:
+#endif
+ return (double) 500.0;
+ case 0x2181:
+#ifdef Py_UNICODE_WIDE
+ case 0x10126:
+ case 0x10146:
+ case 0x1014E:
+ case 0x10172:
+#endif
+ return (double) 5000.0;
+ case 0x2187:
+#ifdef Py_UNICODE_WIDE
+ case 0x1012F:
+ case 0x10147:
+ case 0x10156:
+#endif
+ return (double) 50000.0;
+ case 0x0036:
+ case 0x0666:
+ case 0x06F6:
+ case 0x07C6:
+ case 0x096C:
+ case 0x09EC:
+ case 0x0A6C:
+ case 0x0AEC:
+ case 0x0B6C:
+ case 0x0BEC:
+ case 0x0C6C:
+ case 0x0CEC:
+ case 0x0D6C:
+ case 0x0E56:
+ case 0x0ED6:
+ case 0x0F26:
+ case 0x1046:
+ case 0x1096:
+ case 0x136E:
+ case 0x17E6:
+ case 0x17F6:
+ case 0x1816:
+ case 0x194C:
+ case 0x19D6:
+ case 0x1A86:
+ case 0x1A96:
+ case 0x1B56:
+ case 0x1BB6:
+ case 0x1C46:
+ case 0x1C56:
+ case 0x2076:
+ case 0x2086:
+ case 0x2165:
+ case 0x2175:
+ case 0x2185:
+ case 0x2465:
+ case 0x2479:
+ case 0x248D:
+ case 0x24FA:
+ case 0x277B:
+ case 0x2785:
+ case 0x278F:
+ case 0x3026:
+ case 0x3225:
+ case 0x3285:
+ case 0x516D:
+ case 0x9646:
+ case 0x9678:
+ case 0xA626:
+ case 0xA6EB:
+ case 0xA8D6:
+ case 0xA906:
+ case 0xA9D6:
+ case 0xAA56:
+ case 0xABF6:
+ case 0xF9D1:
+ case 0xF9D3:
+ case 0xFF16:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010C:
+ case 0x104A6:
+ case 0x10E65:
+ case 0x12404:
+ case 0x1240B:
+ case 0x12411:
+ case 0x1241A:
+ case 0x12428:
+ case 0x12440:
+ case 0x1244E:
+ case 0x1D365:
+ case 0x1D7D4:
+ case 0x1D7DE:
+ case 0x1D7E8:
+ case 0x1D7F2:
+ case 0x1D7FC:
+ case 0x1F107:
+ case 0x20AEA:
+#endif
+ return (double) 6.0;
+ case 0x1377:
+#ifdef Py_UNICODE_WIDE
+ case 0x10115:
+ case 0x10E6E:
+ case 0x1D36E:
+#endif
+ return (double) 60.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011E:
+ case 0x10E77:
+ return (double) 600.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10127:
+ return (double) 6000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10130:
+ return (double) 60000.0;
+#endif
+ case 0x0037:
+ case 0x0667:
+ case 0x06F7:
+ case 0x07C7:
+ case 0x096D:
+ case 0x09ED:
+ case 0x0A6D:
+ case 0x0AED:
+ case 0x0B6D:
+ case 0x0BED:
+ case 0x0C6D:
+ case 0x0CED:
+ case 0x0D6D:
+ case 0x0E57:
+ case 0x0ED7:
+ case 0x0F27:
+ case 0x1047:
+ case 0x1097:
+ case 0x136F:
+ case 0x17E7:
+ case 0x17F7:
+ case 0x1817:
+ case 0x194D:
+ case 0x19D7:
+ case 0x1A87:
+ case 0x1A97:
+ case 0x1B57:
+ case 0x1BB7:
+ case 0x1C47:
+ case 0x1C57:
+ case 0x2077:
+ case 0x2087:
+ case 0x2166:
+ case 0x2176:
+ case 0x2466:
+ case 0x247A:
+ case 0x248E:
+ case 0x24FB:
+ case 0x277C:
+ case 0x2786:
+ case 0x2790:
+ case 0x3027:
+ case 0x3226:
+ case 0x3286:
+ case 0x3B4D:
+ case 0x4E03:
+ case 0x67D2:
+ case 0x6F06:
+ case 0xA627:
+ case 0xA6EC:
+ case 0xA8D7:
+ case 0xA907:
+ case 0xA9D7:
+ case 0xAA57:
+ case 0xABF7:
+ case 0xFF17:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010D:
+ case 0x104A7:
+ case 0x10E66:
+ case 0x12405:
+ case 0x1240C:
+ case 0x12412:
+ case 0x1241B:
+ case 0x12429:
+ case 0x12441:
+ case 0x12442:
+ case 0x12443:
+ case 0x1D366:
+ case 0x1D7D5:
+ case 0x1D7DF:
+ case 0x1D7E9:
+ case 0x1D7F3:
+ case 0x1D7FD:
+ case 0x1F108:
+ case 0x20001:
+#endif
+ return (double) 7.0;
+ case 0x0F2D:
+ return (double) 7.0/2.0;
+ case 0x215E:
+ return (double) 7.0/8.0;
+ case 0x1378:
+#ifdef Py_UNICODE_WIDE
+ case 0x10116:
+ case 0x10E6F:
+ case 0x1D36F:
+#endif
+ return (double) 70.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x1011F:
+ case 0x10E78:
+ return (double) 700.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10128:
+ return (double) 7000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10131:
+ return (double) 70000.0;
+#endif
+ case 0x0038:
+ case 0x0668:
+ case 0x06F8:
+ case 0x07C8:
+ case 0x096E:
+ case 0x09EE:
+ case 0x0A6E:
+ case 0x0AEE:
+ case 0x0B6E:
+ case 0x0BEE:
+ case 0x0C6E:
+ case 0x0CEE:
+ case 0x0D6E:
+ case 0x0E58:
+ case 0x0ED8:
+ case 0x0F28:
+ case 0x1048:
+ case 0x1098:
+ case 0x1370:
+ case 0x17E8:
+ case 0x17F8:
+ case 0x1818:
+ case 0x194E:
+ case 0x19D8:
+ case 0x1A88:
+ case 0x1A98:
+ case 0x1B58:
+ case 0x1BB8:
+ case 0x1C48:
+ case 0x1C58:
+ case 0x2078:
+ case 0x2088:
+ case 0x2167:
+ case 0x2177:
+ case 0x2467:
+ case 0x247B:
+ case 0x248F:
+ case 0x24FC:
+ case 0x277D:
+ case 0x2787:
+ case 0x2791:
+ case 0x3028:
+ case 0x3227:
+ case 0x3287:
+ case 0x516B:
+ case 0x634C:
+ case 0xA628:
+ case 0xA6ED:
+ case 0xA8D8:
+ case 0xA908:
+ case 0xA9D8:
+ case 0xAA58:
+ case 0xABF8:
+ case 0xFF18:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010E:
+ case 0x104A8:
+ case 0x10E67:
+ case 0x12406:
+ case 0x1240D:
+ case 0x12413:
+ case 0x1241C:
+ case 0x1242A:
+ case 0x12444:
+ case 0x12445:
+ case 0x1D367:
+ case 0x1D7D6:
+ case 0x1D7E0:
+ case 0x1D7EA:
+ case 0x1D7F4:
+ case 0x1D7FE:
+ case 0x1F109:
+#endif
+ return (double) 8.0;
+ case 0x1379:
+#ifdef Py_UNICODE_WIDE
+ case 0x10117:
+ case 0x10E70:
+ case 0x1D370:
+#endif
+ return (double) 80.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x10120:
+ case 0x10E79:
+ return (double) 800.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10129:
+ return (double) 8000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10132:
+ return (double) 80000.0;
+#endif
+ case 0x0039:
+ case 0x0669:
+ case 0x06F9:
+ case 0x07C9:
+ case 0x096F:
+ case 0x09EF:
+ case 0x0A6F:
+ case 0x0AEF:
+ case 0x0B6F:
+ case 0x0BEF:
+ case 0x0C6F:
+ case 0x0CEF:
+ case 0x0D6F:
+ case 0x0E59:
+ case 0x0ED9:
+ case 0x0F29:
+ case 0x1049:
+ case 0x1099:
+ case 0x1371:
+ case 0x17E9:
+ case 0x17F9:
+ case 0x1819:
+ case 0x194F:
+ case 0x19D9:
+ case 0x1A89:
+ case 0x1A99:
+ case 0x1B59:
+ case 0x1BB9:
+ case 0x1C49:
+ case 0x1C59:
+ case 0x2079:
+ case 0x2089:
+ case 0x2168:
+ case 0x2178:
+ case 0x2468:
+ case 0x247C:
+ case 0x2490:
+ case 0x24FD:
+ case 0x277E:
+ case 0x2788:
+ case 0x2792:
+ case 0x3029:
+ case 0x3228:
+ case 0x3288:
+ case 0x4E5D:
+ case 0x5EFE:
+ case 0x7396:
+ case 0xA629:
+ case 0xA6EE:
+ case 0xA8D9:
+ case 0xA909:
+ case 0xA9D9:
+ case 0xAA59:
+ case 0xABF9:
+ case 0xFF19:
+#ifdef Py_UNICODE_WIDE
+ case 0x1010F:
+ case 0x104A9:
+ case 0x10E68:
+ case 0x12407:
+ case 0x1240E:
+ case 0x12414:
+ case 0x1241D:
+ case 0x1242B:
+ case 0x12446:
+ case 0x12447:
+ case 0x12448:
+ case 0x12449:
+ case 0x1D368:
+ case 0x1D7D7:
+ case 0x1D7E1:
+ case 0x1D7EB:
+ case 0x1D7F5:
+ case 0x1D7FF:
+ case 0x1F10A:
+ case 0x2F890:
+#endif
+ return (double) 9.0;
+ case 0x0F2E:
+ return (double) 9.0/2.0;
+ case 0x137A:
+#ifdef Py_UNICODE_WIDE
+ case 0x10118:
+ case 0x10341:
+ case 0x10E71:
+ case 0x1D371:
+#endif
+ return (double) 90.0;
+#ifdef Py_UNICODE_WIDE
+ case 0x10121:
+ case 0x1034A:
+ case 0x10E7A:
+ return (double) 900.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x1012A:
+ return (double) 9000.0;
+#endif
+#ifdef Py_UNICODE_WIDE
+ case 0x10133:
+ return (double) 90000.0;
+#endif
+ }
+ return -1.0;
+}
+
+/* Returns 1 for Unicode characters having the bidirectional
+ * type 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise.
+ */
+int _PyUnicode_IsWhitespace(register const Py_UNICODE ch)
+{
+#ifdef WANT_WCTYPE_FUNCTIONS
+ return iswspace(ch);
+#else
+ switch (ch) {
+ case 0x0009:
+ case 0x000A:
+ case 0x000B:
+ case 0x000C:
+ case 0x000D:
+ case 0x001C:
+ case 0x001D:
+ case 0x001E:
+ case 0x001F:
+ case 0x0020:
+ case 0x0085:
+ case 0x00A0:
+ case 0x1680:
+ case 0x180E:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x2028:
+ case 0x2029:
+ case 0x202F:
+ case 0x205F:
+ case 0x3000:
+ return 1;
+ }
+ return 0;
+#endif
+}
+
+/* Returns 1 for Unicode characters having the line break
+ * property 'BK', 'CR', 'LF' or 'NL' or having bidirectional
+ * type 'B', 0 otherwise.
+ */
+int _PyUnicode_IsLinebreak(register const Py_UNICODE ch)
+{
+ switch (ch) {
+ case 0x000A:
+ case 0x000B:
+ case 0x000C:
+ case 0x000D:
+ case 0x001C:
+ case 0x001D:
+ case 0x001E:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ return 1;
+ }
+ return 0;
+}
+