summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c129
-rw-r--r--Objects/bytearrayobject.c623
-rw-r--r--Objects/bytesobject.c760
-rw-r--r--Objects/capsule.c36
-rw-r--r--Objects/classobject.c4
-rw-r--r--Objects/cobject.c169
-rw-r--r--Objects/codeobject.c221
-rw-r--r--Objects/complexobject.c203
-rw-r--r--Objects/descrobject.c74
-rw-r--r--Objects/dictobject.c148
-rw-r--r--Objects/enumobject.c7
-rw-r--r--Objects/exceptions.c68
-rw-r--r--Objects/fileobject.c24
-rw-r--r--Objects/floatobject.c228
-rw-r--r--Objects/frameobject.c28
-rw-r--r--Objects/funcobject.c3
-rw-r--r--Objects/genobject.c2
-rw-r--r--Objects/iterobject.c4
-rw-r--r--Objects/listobject.c500
-rw-r--r--Objects/lnotab_notes.txt124
-rw-r--r--Objects/longobject.c2027
-rw-r--r--Objects/memoryobject.c138
-rw-r--r--Objects/methodobject.c4
-rw-r--r--Objects/moduleobject.c75
-rw-r--r--Objects/object.c202
-rw-r--r--Objects/obmalloc.c143
-rw-r--r--Objects/rangeobject.c626
-rw-r--r--Objects/setobject.c109
-rw-r--r--Objects/sliceobject.c27
-rw-r--r--Objects/stringlib/README.txt4
-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.h86
-rw-r--r--Objects/stringlib/formatter.h92
-rw-r--r--Objects/stringlib/partition.h47
-rw-r--r--Objects/stringlib/split.h394
-rw-r--r--Objects/stringlib/string_format.h26
-rw-r--r--Objects/stringlib/stringdefs.h4
-rw-r--r--Objects/stringlib/transmogrify.h113
-rw-r--r--Objects/stringlib/unicodedefs.h22
-rw-r--r--Objects/structseq.c238
-rw-r--r--Objects/tupleobject.c10
-rw-r--r--Objects/typeobject.c181
-rw-r--r--Objects/typeslots.inc75
-rw-r--r--Objects/typeslots.py30
-rw-r--r--Objects/unicodectype.c657
-rw-r--r--Objects/unicodeobject.c1585
-rw-r--r--Objects/unicodetype_db.h4305
-rw-r--r--Objects/weakrefobject.c4
50 files changed, 8698 insertions, 6046 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 2d4f2e1..2f887aa 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -693,48 +693,37 @@ PyBuffer_Release(Py_buffer *view)
PyObject *
PyObject_Format(PyObject *obj, PyObject *format_spec)
{
- static PyObject * str__format__ = NULL;
PyObject *meth;
PyObject *empty = NULL;
PyObject *result = NULL;
-
- /* Initialize cached value */
- if (str__format__ == NULL) {
- /* Initialize static variable needed by _PyType_Lookup */
- str__format__ = PyUnicode_FromString("__format__");
- if (str__format__ == NULL)
- goto done;
- }
+ static PyObject *format_cache = NULL;
/* If no format_spec is provided, use an empty string */
if (format_spec == NULL) {
- empty = PyUnicode_FromUnicode(NULL, 0);
- format_spec = empty;
+ empty = PyUnicode_FromUnicode(NULL, 0);
+ format_spec = empty;
}
- /* Make sure the type is initialized. float gets initialized late */
- if (Py_TYPE(obj)->tp_dict == NULL)
- if (PyType_Ready(Py_TYPE(obj)) < 0)
- goto done;
-
/* Find the (unbound!) __format__ method (a borrowed reference) */
- meth = _PyType_Lookup(Py_TYPE(obj), str__format__);
+ meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache);
if (meth == NULL) {
- PyErr_Format(PyExc_TypeError,
- "Type %.100s doesn't define __format__",
- Py_TYPE(obj)->tp_name);
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_TypeError,
+ "Type %.100s doesn't define __format__",
+ Py_TYPE(obj)->tp_name);
goto done;
}
- /* And call it, binding it to the value */
- result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL);
+ /* And call it. */
+ result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL);
+ Py_DECREF(meth);
if (result && !PyUnicode_Check(result)) {
- PyErr_SetString(PyExc_TypeError,
- "__format__ method did not return string");
- Py_DECREF(result);
- result = NULL;
- goto done;
+ PyErr_SetString(PyExc_TypeError,
+ "__format__ method did not return string");
+ Py_DECREF(result);
+ result = NULL;
+ goto done;
}
done:
@@ -1453,7 +1442,7 @@ PyNumber_ToBase(PyObject *n, int base)
int
PySequence_Check(PyObject *s)
{
- if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type))
+ if (PyDict_Check(s))
return 0;
return s != NULL && s->ob_type->tp_as_sequence &&
s->ob_type->tp_as_sequence->sq_item != NULL;
@@ -2322,15 +2311,7 @@ objargs_mktuple(va_list va)
va_list countva;
PyObject *result, *tmp;
-#ifdef VA_LIST_IS_ARRAY
- memcpy(countva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(countva, va);
-#else
- countva = va;
-#endif
-#endif
+ Py_VA_COPY(countva, va);
while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
++n;
@@ -2519,7 +2500,10 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
if (retval == 0) {
PyObject *c = PyObject_GetAttr(inst, __class__);
if (c == NULL) {
- PyErr_Clear();
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ retval = -1;
}
else {
if (c != (PyObject *)(inst->ob_type) &&
@@ -2537,8 +2521,10 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
return -1;
icls = PyObject_GetAttr(inst, __class__);
if (icls == NULL) {
- PyErr_Clear();
- retval = 0;
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_Clear();
+ else
+ retval = -1;
}
else {
retval = abstract_issubclass(icls, cls);
@@ -2721,3 +2707,66 @@ PyIter_Next(PyObject *iter)
PyErr_Clear();
return result;
}
+
+
+/*
+ * Flatten a sequence of bytes() objects into a C array of
+ * NULL terminated string pointers with a NULL char* terminating the array.
+ * (ie: an argv or env list)
+ *
+ * Memory allocated for the returned list is allocated using malloc() and MUST
+ * be freed by the caller using a free() loop or _Py_FreeCharPArray().
+ */
+char *const *
+_PySequence_BytesToCharpArray(PyObject* self)
+{
+ char **array;
+ Py_ssize_t i, argc;
+ PyObject *item = NULL;
+
+ argc = PySequence_Size(self);
+ if (argc == -1)
+ return NULL;
+
+ array = malloc((argc + 1) * sizeof(char *));
+ if (array == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ for (i = 0; i < argc; ++i) {
+ char *data;
+ item = PySequence_GetItem(self, i);
+ data = PyBytes_AsString(item);
+ if (data == NULL) {
+ /* NULL terminate before freeing. */
+ array[i] = NULL;
+ goto fail;
+ }
+ array[i] = strdup(data);
+ if (!array[i]) {
+ PyErr_NoMemory();
+ goto fail;
+ }
+ Py_DECREF(item);
+ }
+ array[argc] = NULL;
+
+ return array;
+
+fail:
+ Py_XDECREF(item);
+ _Py_FreeCharPArray(array);
+ return NULL;
+}
+
+
+/* Free's a NULL terminated char** array of C strings. */
+void
+_Py_FreeCharPArray(char *const array[])
+{
+ Py_ssize_t i;
+ for (i = 0; array[i] != NULL; ++i) {
+ free(array[i]);
+ }
+ free((void*)array);
+}
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 27affb5..7a74104 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;
}
@@ -41,6 +33,7 @@ _getbytevalue(PyObject* arg, int *value)
PyObject *index = PyNumber_Index(arg);
if (index == NULL) {
PyErr_Format(PyExc_TypeError, "an integer is required");
+ *value = -1;
return 0;
}
face_value = PyLong_AsLong(index);
@@ -50,6 +43,7 @@ _getbytevalue(PyObject* arg, int *value)
if (face_value < 0 || face_value >= 256) {
/* this includes the OverflowError in case the long is too large */
PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
+ *value = -1;
return 0;
}
@@ -316,9 +310,9 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
if (count < 0)
count = 0;
mysize = Py_SIZE(self);
- size = mysize * count;
- if (count != 0 && size / count != mysize)
+ if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
return PyErr_NoMemory();
+ size = mysize * count;
result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
if (result != NULL && size != 0) {
if (mysize == 1)
@@ -341,9 +335,9 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
if (count < 0)
count = 0;
mysize = Py_SIZE(self);
- size = mysize * count;
- if (count != 0 && size / count != mysize)
+ if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
return PyErr_NoMemory();
+ size = mysize * count;
if (size < self->ob_alloc) {
Py_SIZE(self) = size;
self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
@@ -395,7 +389,7 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index)
}
else if (PySlice_Check(index)) {
Py_ssize_t start, stop, step, slicelength, cur, i;
- if (PySlice_GetIndicesEx((PySliceObject *)index,
+ if (PySlice_GetIndicesEx(index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
@@ -579,7 +573,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
}
}
else if (PySlice_Check(index)) {
- if (PySlice_GetIndicesEx((PySliceObject *)index,
+ if (PySlice_GetIndicesEx(index,
PyByteArray_GET_SIZE(self),
&start, &stop, &step, &slicelen) < 0) {
return -1;
@@ -655,6 +649,11 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
if (!_canresize(self))
return -1;
+
+ if (slicelen == 0)
+ /* Nothing to do here. */
+ return 0;
+
if (step < 0) {
stop = start + 1;
start = stop + step * (slicelen - 1) - 1;
@@ -671,7 +670,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
self->ob_bytes + cur + 1, lim);
}
/* Move the tail of the bytes, in one chunk */
- cur = start + slicelen*step;
+ cur = start + (size_t)slicelen*step;
if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
memmove(self->ob_bytes + cur - slicelen,
self->ob_bytes + cur,
@@ -685,7 +684,8 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
}
else {
/* Assign slice */
- Py_ssize_t cur, i;
+ Py_ssize_t i;
+ size_t cur;
if (needed != slicelen) {
PyErr_Format(PyExc_ValueError,
@@ -1038,19 +1038,19 @@ bytearray_dealloc(PyByteArrayObject *self)
/* Methods */
#define STRINGLIB_CHAR char
-#define STRINGLIB_CMP memcmp
#define STRINGLIB_LEN PyByteArray_GET_SIZE
#define STRINGLIB_STR PyByteArray_AS_STRING
#define STRINGLIB_NEW PyByteArray_FromStringAndSize
-#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"
@@ -1058,21 +1058,20 @@ bytearray_dealloc(PyByteArrayObject *self)
/* The following Py_LOCAL_INLINE and Py_LOCAL functions
were copied from the old char* style string object. */
-Py_LOCAL_INLINE(void)
-_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
-{
- if (*end > len)
- *end = len;
- else if (*end < 0)
- *end += len;
- if (*end < 0)
- *end = 0;
- if (*start < 0)
- *start += len;
- if (*start < 0)
- *start = 0;
-}
-
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
Py_LOCAL_INLINE(Py_ssize_t)
bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
@@ -1139,10 +1138,10 @@ bytearray_count(PyByteArrayObject *self, PyObject *args)
if (_getbuffer(sub_obj, &vsub) < 0)
return NULL;
- _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
+ ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
count_obj = PyLong_FromSsize_t(
- stringlib_count(str + start, end - start, vsub.buf, vsub.len)
+ stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
);
PyBuffer_Release(&vsub);
return count_obj;
@@ -1250,7 +1249,7 @@ _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start
if (_getbuffer(substr, &vsubstr) < 0)
return -1;
- _adjust_indices(&start, &end, len);
+ ADJUST_INDICES(start, end, len);
if (direction < 0) {
/* startswith */
@@ -1468,20 +1467,11 @@ bytearray_maketrans(PyObject *null, PyObject *args)
}
-#define FORWARD 1
-#define REVERSE -1
-
/* find and count characters and substrings */
#define findchar(target, target_len, c) \
((char *)memchr((const void *)(target), c, target_len))
-/* Don't call if length < 2 */
-#define Py_STRING_MATCH(target, offset, pattern, length) \
- (target[offset] == pattern[0] && \
- target[offset+length-1] == pattern[length-1] && \
- !memcmp(target+offset+1, pattern+1, length-2) )
-
/* Bytes ops must return a string, create a copy */
Py_LOCAL(PyByteArrayObject *)
@@ -1509,93 +1499,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 */
@@ -1607,30 +1510,28 @@ replace_interleave(PyByteArrayObject *self,
{
char *self_s, *result_s;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, i, product;
+ Py_ssize_t count, i;
PyByteArrayObject *result;
self_len = PyByteArray_GET_SIZE(self);
- /* 1 at the end plus 1 after every character */
- count = self_len+1;
- if (maxcount < count)
+ /* 1 at the end plus 1 after every character;
+ count = min(maxcount, self_len + 1) */
+ if (maxcount <= self_len)
count = maxcount;
+ else
+ /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
+ count = self_len + 1;
/* Check for overflow */
/* result_len = count * to_len + self_len; */
- product = count * to_len;
- if (product / to_len != count) {
- PyErr_SetString(PyExc_OverflowError,
- "replace string is too long");
- return NULL;
- }
- result_len = product + self_len;
- if (result_len < 0) {
+ assert(count > 0);
+ if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError,
"replace string is too long");
return NULL;
}
+ result_len = count * to_len + self_len;
if (! (result = (PyByteArrayObject *)
PyByteArray_FromStringAndSize(NULL, result_len)) )
@@ -1717,10 +1618,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 */
@@ -1739,9 +1639,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;
@@ -1817,9 +1717,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);
@@ -1839,9 +1739,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);
@@ -1861,7 +1761,7 @@ replace_single_character(PyByteArrayObject *self,
char *self_s, *result_s;
char *start, *next, *end;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, product;
+ Py_ssize_t count;
PyByteArrayObject *result;
self_s = PyByteArray_AS_STRING(self);
@@ -1875,16 +1775,12 @@ replace_single_character(PyByteArrayObject *self,
/* use the difference between current and new, hence the "-1" */
/* result_len = self_len + count * (to_len-1) */
- product = count * (to_len-1);
- if (product / (to_len-1) != count) {
+ assert(count > 0);
+ if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
return NULL;
}
- result_len = self_len + product;
- if (result_len < 0) {
- PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
- return NULL;
- }
+ result_len = self_len + count * (to_len - 1);
if ( (result = (PyByteArrayObject *)
PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
@@ -1928,15 +1824,16 @@ replace_substring(PyByteArrayObject *self,
char *self_s, *result_s;
char *start, *next, *end;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, offset, product;
+ Py_ssize_t count, offset;
PyByteArrayObject *result;
self_s = PyByteArray_AS_STRING(self);
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);
@@ -1944,16 +1841,12 @@ replace_substring(PyByteArrayObject *self,
/* Check for overflow */
/* result_len = self_len + count * (to_len-from_len) */
- product = count * (to_len-from_len);
- if (product / (to_len-from_len) != count) {
- PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
- return NULL;
- }
- result_len = self_len + product;
- if (result_len < 0) {
+ assert(count > 0);
+ if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
return NULL;
}
+ result_len = self_len + count * (to_len - from_len);
if ( (result = (PyByteArrayObject *)
PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
@@ -1963,9 +1856,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;
@@ -2094,123 +1987,6 @@ bytearray_replace(PyByteArrayObject *self, PyObject *args)
return res;
}
-
-/* Overallocate the initial list to reduce the number of reallocs for small
- split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
- resizes, to sizes 4, 8, then 16. Most observed string splits are for human
- text (roughly 11 words per line) and field delimited data (usually 1-10
- fields). For large strings the split algorithms are bandwidth limited
- so increasing the preallocation likely will not improve things.*/
-
-#define MAX_PREALLOC 12
-
-/* 5 splits gives 6 elements */
-#define PREALLOC_SIZE(maxsplit) \
- (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
-
-#define SPLIT_APPEND(data, left, right) \
- str = PyByteArray_FromStringAndSize((data) + (left), \
- (right) - (left)); \
- if (str == NULL) \
- goto onError; \
- if (PyList_Append(list, str)) { \
- Py_DECREF(str); \
- goto onError; \
- } \
- else \
- Py_DECREF(str);
-
-#define SPLIT_ADD(data, left, right) { \
- str = PyByteArray_FromStringAndSize((data) + (left), \
- (right) - (left)); \
- if (str == NULL) \
- goto onError; \
- if (count < MAX_PREALLOC) { \
- PyList_SET_ITEM(list, count, str); \
- } else { \
- if (PyList_Append(list, str)) { \
- Py_DECREF(str); \
- goto onError; \
- } \
- else \
- Py_DECREF(str); \
- } \
- count++; }
-
-/* Always force the list to the expected size. */
-#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
-
-
-Py_LOCAL_INLINE(PyObject *)
-split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- register Py_ssize_t i, j, count = 0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- i = j = 0;
- while ((j < len) && (maxcount-- > 0)) {
- for(; j < len; j++) {
- /* I found that using memchr makes no difference */
- if (s[j] == ch) {
- SPLIT_ADD(s, i, j);
- i = j = j + 1;
- break;
- }
- }
- }
- if (i <= len) {
- SPLIT_ADD(s, i, len);
- }
- FIX_PREALLOC_SIZE(list);
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
-
-Py_LOCAL_INLINE(PyObject *)
-split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
-{
- register Py_ssize_t i, j, count = 0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- for (i = j = 0; i < len; ) {
- /* find a token */
- while (i < len && Py_ISSPACE(s[i]))
- i++;
- j = i;
- while (i < len && !Py_ISSPACE(s[i]))
- i++;
- if (j < i) {
- if (maxcount-- <= 0)
- break;
- SPLIT_ADD(s, j, i);
- while (i < len && Py_ISSPACE(s[i]))
- i++;
- j = i;
- }
- }
- if (j < len) {
- SPLIT_ADD(s, j, len);
- }
- FIX_PREALLOC_SIZE(list);
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
PyDoc_STRVAR(split__doc__,
"B.split([sep[, maxsplit]]) -> list of bytearrays\n\
\n\
@@ -2222,14 +1998,11 @@ If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
bytearray_split(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
- Py_ssize_t 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;
@@ -2237,86 +2010,18 @@ bytearray_split(PyByteArrayObject *self, PyObject *args)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return split_whitespace(s, len, maxsplit);
+ return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
if (_getbuffer(subobj, &vsub) < 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- PyBuffer_Release(&vsub);
- return NULL;
- }
- if (n == 1) {
- list = split_char(s, len, sub[0], maxsplit);
- PyBuffer_Release(&vsub);
- return list;
- }
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL) {
- PyBuffer_Release(&vsub);
- return NULL;
- }
-
-#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__,
@@ -2343,7 +2048,7 @@ bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
);
Py_DECREF(bytesep);
- return make_nullbytes_unique(result);
+ return result;
}
PyDoc_STRVAR(rpartition__doc__,
@@ -2371,81 +2076,7 @@ bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
);
Py_DECREF(bytesep);
- return make_nullbytes_unique(result);
-}
-
-Py_LOCAL_INLINE(PyObject *)
-rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- register Py_ssize_t i, j, count=0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- i = j = len - 1;
- while ((i >= 0) && (maxcount-- > 0)) {
- for (; i >= 0; i--) {
- if (s[i] == ch) {
- SPLIT_ADD(s, i + 1, j + 1);
- j = i = i - 1;
- break;
- }
- }
- }
- if (j >= -1) {
- SPLIT_ADD(s, 0, j + 1);
- }
- FIX_PREALLOC_SIZE(list);
- if (PyList_Reverse(list) < 0)
- goto onError;
-
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
-Py_LOCAL_INLINE(PyObject *)
-rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
-{
- register Py_ssize_t i, j, count = 0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- for (i = j = len - 1; i >= 0; ) {
- /* find a token */
- while (i >= 0 && Py_ISSPACE(s[i]))
- i--;
- j = i;
- while (i >= 0 && !Py_ISSPACE(s[i]))
- i--;
- if (j > i) {
- if (maxcount-- <= 0)
- break;
- SPLIT_ADD(s, i + 1, j + 1);
- while (i >= 0 && Py_ISSPACE(s[i]))
- i--;
- j = i;
- }
- }
- if (j >= 0) {
- SPLIT_ADD(s, 0, j + 1);
- }
- FIX_PREALLOC_SIZE(list);
- if (PyList_Reverse(list) < 0)
- goto onError;
-
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
+ return result;
}
PyDoc_STRVAR(rsplit__doc__,
@@ -2460,10 +2091,10 @@ If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
{
- Py_ssize_t len = PyByteArray_GET_SIZE(self), n, 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))
@@ -2472,54 +2103,18 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return rsplit_whitespace(s, len, maxsplit);
+ return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
if (_getbuffer(subobj, &vsub) < 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- PyBuffer_Release(&vsub);
- return NULL;
- }
- else if (n == 1) {
- list = rsplit_char(s, len, sub[0], maxsplit);
- PyBuffer_Release(&vsub);
- return list;
- }
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL) {
- PyBuffer_Release(&vsub);
- return NULL;
- }
-
- j = len;
- 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__,
@@ -2695,8 +2290,8 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args)
return NULL;
if (n == 0) {
- PyErr_SetString(PyExc_OverflowError,
- "cannot pop an empty bytearray");
+ PyErr_SetString(PyExc_IndexError,
+ "pop from empty bytearray");
return NULL;
}
if (where < 0)
@@ -2875,22 +2470,23 @@ bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
}
PyDoc_STRVAR(decode_doc,
-"B.decode([encoding[, errors]]) -> str\n\
+"B.decode(encoding='utf-8', errors='strict') -> str\n\
\n\
-Decode B using the codec registered for encoding. encoding defaults\n\
-to the default encoding. errors may be given to set a different error\n\
+Decode B using the codec registered for encoding. Default encoding\n\
+is 'utf-8'. errors may be given to set a different error\n\
handling scheme. Default is 'strict' meaning that encoding errors raise\n\
a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
as well as any other name registered with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");
static PyObject *
-bytearray_decode(PyObject *self, PyObject *args)
+bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char *encoding = NULL;
const char *errors = NULL;
+ static char *kwlist[] = {"encoding", "errors", 0};
- if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
return NULL;
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
@@ -2984,6 +2580,27 @@ bytearray_join(PyByteArrayObject *self, PyObject *it)
return NULL;
}
+PyDoc_STRVAR(splitlines__doc__,
+"B.splitlines([keepends]) -> list of lines\n\
+\n\
+Return a list of the lines in B, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+bytearray_splitlines(PyObject *self, PyObject *args)
+{
+ int keepends = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+ return NULL;
+
+ return stringlib_splitlines(
+ (PyObject*) self, PyByteArray_AS_STRING(self),
+ PyByteArray_GET_SIZE(self), keepends
+ );
+}
+
PyDoc_STRVAR(fromhex_doc,
"bytearray.fromhex(string) -> bytearray (static method)\n\
\n\
@@ -3120,7 +2737,7 @@ bytearray_methods[] = {
_Py_capitalize__doc__},
{"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
{"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
- {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc},
+ {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
{"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
expandtabs__doc__},
@@ -3162,7 +2779,7 @@ bytearray_methods[] = {
{"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
{"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
{"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
- {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
+ {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
splitlines__doc__},
{"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
startswith__doc__},
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index f2ee131..38458ef 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -56,7 +56,7 @@ static PyBytesObject *nullstring;
If `str' is NULL then PyBytes_FromStringAndSize() will allocate `size+1'
bytes (setting the last byte to the null terminating character) and you can
fill in the data yourself. If `str' is non-NULL then the resulting
- PyString object must be treated as immutable and you must not fill in nor
+ PyBytes object must be treated as immutable and you must not fill in nor
alter the data yourself, since the strings may be shared.
The PyObject member `op->ob_size', which denotes the number of "extra
@@ -173,20 +173,12 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
char *s;
PyObject* string;
-#ifdef VA_LIST_IS_ARRAY
- Py_MEMCPY(count, vargs, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(count, vargs);
-#else
- count = vargs;
-#endif
-#endif
+ Py_VA_COPY(count, vargs);
/* step 1: figure out how large a buffer we need */
for (f = format; *f; f++) {
if (*f == '%') {
const char* p = f;
- while (*++f && *f != '%' && !ISALPHA(*f))
+ while (*++f && *f != '%' && !Py_ISALPHA(*f))
;
/* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
@@ -255,15 +247,15 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
/* parse the width.precision part (we're only
interested in the precision value, if any) */
n = 0;
- while (ISDIGIT(*f))
+ while (Py_ISDIGIT(*f))
n = (n*10) + *f++ - '0';
if (*f == '.') {
f++;
n = 0;
- while (ISDIGIT(*f))
+ while (Py_ISDIGIT(*f))
n = (n*10) + *f++ - '0';
}
- while (*f && *f != '%' && !ISALPHA(*f))
+ while (*f && *f != '%' && !Py_ISALPHA(*f))
f++;
/* handle the long flag, but only for %ld and %lu.
others can be added when necessary. */
@@ -454,22 +446,22 @@ PyObject *PyBytes_DecodeEscape(const char *s,
*p++ = c;
break;
case 'x':
- if (s+1 < end && ISXDIGIT(s[0]) && ISXDIGIT(s[1])) {
+ if (s+1 < end && Py_ISXDIGIT(s[0]) && Py_ISXDIGIT(s[1])) {
unsigned int x = 0;
c = Py_CHARMASK(*s);
s++;
- if (ISDIGIT(c))
+ if (Py_ISDIGIT(c))
x = c - '0';
- else if (ISLOWER(c))
+ else if (Py_ISLOWER(c))
x = 10 + c - 'a';
else
x = 10 + c - 'A';
x = x << 4;
c = Py_CHARMASK(*s);
s++;
- if (ISDIGIT(c))
+ if (Py_ISDIGIT(c))
x += c - '0';
- else if (ISLOWER(c))
+ else if (Py_ISLOWER(c))
x += 10 + c - 'a';
else
x += 10 + c - 'A';
@@ -563,29 +555,15 @@ PyBytes_AsStringAndSize(register PyObject *obj,
/* Methods */
#include "stringlib/stringdefs.h"
-#define STRINGLIB_CHAR char
-
-#define STRINGLIB_CMP memcmp
-#define STRINGLIB_LEN PyBytes_GET_SIZE
-#define STRINGLIB_NEW PyBytes_FromStringAndSize
-#define STRINGLIB_STR PyBytes_AS_STRING
-/* #define STRINGLIB_WANT_CONTAINS_OBJ 1 */
-
-#define STRINGLIB_EMPTY nullstring
-#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact
-#define STRINGLIB_MUTABLE 0
#include "stringlib/fastsearch.h"
-
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/partition.h"
+#include "stringlib/split.h"
#include "stringlib/ctype.h"
-#include "stringlib/transmogrify.h"
-#define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping
-#define _Py_InsertThousandsGroupingLocale _PyBytes_InsertThousandsGroupingLocale
-#include "stringlib/localeutil.h"
+#include "stringlib/transmogrify.h"
PyObject *
PyBytes_Repr(PyObject *obj, int smartquotes)
@@ -593,13 +571,14 @@ PyBytes_Repr(PyObject *obj, int smartquotes)
static const char *hexdigits = "0123456789abcdef";
register PyBytesObject* op = (PyBytesObject*) obj;
Py_ssize_t length = Py_SIZE(op);
- size_t newsize = 3 + 4 * length;
+ size_t newsize;
PyObject *v;
- if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) {
+ if (length > (PY_SSIZE_T_MAX - 3) / 4) {
PyErr_SetString(PyExc_OverflowError,
"bytes object is too large to make repr");
return NULL;
}
+ newsize = 3 + 4 * length;
v = PyUnicode_FromUnicode(NULL, newsize);
if (v == NULL) {
return NULL;
@@ -746,12 +725,12 @@ bytes_repeat(register PyBytesObject *a, register Py_ssize_t n)
/* watch out for overflows: the size can overflow int,
* and the # of bytes needed can overflow size_t
*/
- size = Py_SIZE(a) * n;
- if (n && size / n != Py_SIZE(a)) {
+ if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) {
PyErr_SetString(PyExc_OverflowError,
"repeated bytes are too long");
return NULL;
}
+ size = Py_SIZE(a) * n;
if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) {
Py_INCREF(a);
return (PyObject *)a;
@@ -889,12 +868,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
return result;
}
-static long
+static Py_hash_t
bytes_hash(PyBytesObject *a)
{
register Py_ssize_t len;
register unsigned char *p;
- register long x;
+ register Py_hash_t x;
if (a->ob_shash != -1)
return a->ob_shash;
@@ -932,7 +911,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item)
char* result_buf;
PyObject* result;
- if (PySlice_GetIndicesEx((PySliceObject*)item,
+ if (PySlice_GetIndicesEx(item,
PyBytes_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
@@ -1014,133 +993,6 @@ static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};
#define STRIPNAME(i) (stripformat[i]+3)
-
-/* Don't call if length < 2 */
-#define Py_STRING_MATCH(target, offset, pattern, length) \
- (target[offset] == pattern[0] && \
- target[offset+length-1] == pattern[length-1] && \
- !memcmp(target+offset+1, pattern+1, length-2) )
-
-
-/* Overallocate the initial list to reduce the number of reallocs for small
- split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
- resizes, to sizes 4, 8, then 16. Most observed string splits are for human
- text (roughly 11 words per line) and field delimited data (usually 1-10
- fields). For large strings the split algorithms are bandwidth limited
- so increasing the preallocation likely will not improve things.*/
-
-#define MAX_PREALLOC 12
-
-/* 5 splits gives 6 elements */
-#define PREALLOC_SIZE(maxsplit) \
- (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
-
-#define SPLIT_ADD(data, left, right) { \
- str = PyBytes_FromStringAndSize((data) + (left), \
- (right) - (left)); \
- if (str == NULL) \
- goto onError; \
- if (count < MAX_PREALLOC) { \
- PyList_SET_ITEM(list, count, str); \
- } else { \
- if (PyList_Append(list, str)) { \
- Py_DECREF(str); \
- goto onError; \
- } \
- else \
- Py_DECREF(str); \
- } \
- count++; }
-
-/* Always force the list to the expected size. */
-#define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
-
-#define SKIP_SPACE(s, i, len) { while (i<len && ISSPACE(s[i])) i++; }
-#define SKIP_NONSPACE(s, i, len) { while (i<len && !ISSPACE(s[i])) i++; }
-#define RSKIP_SPACE(s, i) { while (i>=0 && ISSPACE(s[i])) i--; }
-#define RSKIP_NONSPACE(s, i) { while (i>=0 && !ISSPACE(s[i])) i--; }
-
-Py_LOCAL_INLINE(PyObject *)
-split_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
-{
- const char *s = PyBytes_AS_STRING(self);
- Py_ssize_t i, j, count=0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
-
- if (list == NULL)
- return NULL;
-
- i = j = 0;
-
- while (maxsplit-- > 0) {
- SKIP_SPACE(s, i, len);
- if (i==len) break;
- j = i; i++;
- SKIP_NONSPACE(s, i, len);
- if (j == 0 && i == len && PyBytes_CheckExact(self)) {
- /* No whitespace in self, so just use it as list[0] */
- Py_INCREF(self);
- PyList_SET_ITEM(list, 0, (PyObject *)self);
- count++;
- break;
- }
- SPLIT_ADD(s, j, i);
- }
-
- if (i < len) {
- /* Only occurs when maxsplit was reached */
- /* Skip any remaining whitespace and copy to end of string */
- SKIP_SPACE(s, i, len);
- if (i != len)
- SPLIT_ADD(s, i, len);
- }
- FIX_PREALLOC_SIZE(list);
- return list;
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
-Py_LOCAL_INLINE(PyObject *)
-split_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- const char *s = PyBytes_AS_STRING(self);
- register Py_ssize_t i, j, count=0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- i = j = 0;
- while ((j < len) && (maxcount-- > 0)) {
- for(; j<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 && PyBytes_CheckExact(self)) {
- /* ch not in self, so just use self as list[0] */
- Py_INCREF(self);
- PyList_SET_ITEM(list, 0, (PyObject *)self);
- count++;
- }
- else if (i <= len) {
- SPLIT_ADD(s, i, len);
- }
- FIX_PREALLOC_SIZE(list);
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
PyDoc_STRVAR(split__doc__,
"B.split([sep[, maxsplit]]) -> list of bytes\n\
\n\
@@ -1152,74 +1004,26 @@ If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
bytes_split(PyBytesObject *self, PyObject *args)
{
- Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j;
- Py_ssize_t maxsplit = -1, count=0;
+ Py_ssize_t len = PyBytes_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
const char *s = PyBytes_AS_STRING(self), *sub;
Py_buffer vsub;
- PyObject *list, *str, *subobj = Py_None;
-#ifdef USE_FAST
- Py_ssize_t pos;
-#endif
+ PyObject *list, *subobj = Py_None;
if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return split_whitespace(self, len, maxsplit);
+ return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
if (_getbuffer(subobj, &vsub) < 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- PyBuffer_Release(&vsub);
- return NULL;
- }
- else if (n == 1) {
- list = split_char(self, len, sub[0], maxsplit);
- PyBuffer_Release(&vsub);
- return list;
- }
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL) {
- PyBuffer_Release(&vsub);
- return NULL;
- }
-
-#ifdef USE_FAST
- i = j = 0;
- while (maxsplit-- > 0) {
- pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
- if (pos < 0)
- break;
- j = i+pos;
- SPLIT_ADD(s, i, j);
- i = j + n;
- }
-#else
- i = j = 0;
- while ((j+n <= len) && (maxsplit-- > 0)) {
- for (; j+n <= len; j++) {
- if (Py_STRING_MATCH(s, j, sub, n)) {
- SPLIT_ADD(s, i, j);
- i = j = j + n;
- break;
- }
- }
- }
-#endif
- SPLIT_ADD(s, i, len);
- FIX_PREALLOC_SIZE(list);
+ list = stringlib_split((PyObject*) self, s, len, sub, n, maxsplit);
PyBuffer_Release(&vsub);
return list;
-
- onError:
- Py_DECREF(list);
- PyBuffer_Release(&vsub);
- return NULL;
}
PyDoc_STRVAR(partition__doc__,
@@ -1277,90 +1081,6 @@ bytes_rpartition(PyBytesObject *self, PyObject *sep_obj)
);
}
-Py_LOCAL_INLINE(PyObject *)
-rsplit_whitespace(PyBytesObject *self, Py_ssize_t len, Py_ssize_t maxsplit)
-{
- const char *s = PyBytes_AS_STRING(self);
- Py_ssize_t i, j, count=0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));
-
- if (list == NULL)
- return NULL;
-
- i = j = len-1;
-
- while (maxsplit-- > 0) {
- RSKIP_SPACE(s, i);
- if (i<0) break;
- j = i; i--;
- RSKIP_NONSPACE(s, i);
- if (j == len-1 && i < 0 && PyBytes_CheckExact(self)) {
- /* No whitespace in self, so just use it as list[0] */
- Py_INCREF(self);
- PyList_SET_ITEM(list, 0, (PyObject *)self);
- count++;
- break;
- }
- SPLIT_ADD(s, i + 1, j + 1);
- }
- if (i >= 0) {
- /* Only occurs when maxsplit was reached. Skip any remaining
- whitespace and copy to beginning of string. */
- RSKIP_SPACE(s, i);
- if (i >= 0)
- SPLIT_ADD(s, 0, i + 1);
-
- }
- FIX_PREALLOC_SIZE(list);
- if (PyList_Reverse(list) < 0)
- goto onError;
- return list;
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
-Py_LOCAL_INLINE(PyObject *)
-rsplit_char(PyBytesObject *self, Py_ssize_t len, char ch, Py_ssize_t maxcount)
-{
- const char *s = PyBytes_AS_STRING(self);
- register Py_ssize_t i, j, count=0;
- PyObject *str;
- PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
-
- if (list == NULL)
- return NULL;
-
- i = j = len - 1;
- while ((i >= 0) && (maxcount-- > 0)) {
- for (; i >= 0; i--) {
- if (s[i] == ch) {
- SPLIT_ADD(s, i + 1, j + 1);
- j = i = i - 1;
- break;
- }
- }
- }
- if (i < 0 && count == 0 && PyBytes_CheckExact(self)) {
- /* ch not in self, so just use self as list[0] */
- Py_INCREF(self);
- PyList_SET_ITEM(list, 0, (PyObject *)self);
- count++;
- }
- else if (j >= -1) {
- SPLIT_ADD(s, 0, j + 1);
- }
- FIX_PREALLOC_SIZE(list);
- if (PyList_Reverse(list) < 0)
- goto onError;
- return list;
-
- onError:
- Py_DECREF(list);
- return NULL;
-}
-
PyDoc_STRVAR(rsplit__doc__,
"B.rsplit([sep[, maxsplit]]) -> list of bytes\n\
\n\
@@ -1374,71 +1094,28 @@ If maxsplit is given, at most maxsplit splits are done.");
static PyObject *
bytes_rsplit(PyBytesObject *self, PyObject *args)
{
- Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j;
- Py_ssize_t maxsplit = -1, count=0;
- const char *s, *sub;
+ Py_ssize_t len = PyBytes_GET_SIZE(self), n;
+ Py_ssize_t maxsplit = -1;
+ const char *s = PyBytes_AS_STRING(self), *sub;
Py_buffer vsub;
- PyObject *list, *str, *subobj = Py_None;
+ PyObject *list, *subobj = Py_None;
if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
- return rsplit_whitespace(self, len, maxsplit);
+ return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
if (_getbuffer(subobj, &vsub) < 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
- if (n == 0) {
- PyErr_SetString(PyExc_ValueError, "empty separator");
- PyBuffer_Release(&vsub);
- return NULL;
- }
- else if (n == 1) {
- list = rsplit_char(self, len, sub[0], maxsplit);
- PyBuffer_Release(&vsub);
- return list;
- }
-
- list = PyList_New(PREALLOC_SIZE(maxsplit));
- if (list == NULL) {
- PyBuffer_Release(&vsub);
- return NULL;
- }
-
- j = len;
- i = j - n;
-
- s = PyBytes_AS_STRING(self);
- while ( (i >= 0) && (maxsplit-- > 0) ) {
- for (; i>=0; i--) {
- if (Py_STRING_MATCH(s, i, sub, n)) {
- SPLIT_ADD(s, i + n, j);
- j = i;
- i -= n;
- break;
- }
- }
- }
- SPLIT_ADD(s, 0, j);
- FIX_PREALLOC_SIZE(list);
- if (PyList_Reverse(list) < 0)
- goto onError;
+ list = stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit);
PyBuffer_Release(&vsub);
return list;
-
-onError:
- Py_DECREF(list);
- PyBuffer_Release(&vsub);
- return NULL;
}
-#undef SPLIT_ADD
-#undef MAX_PREALLOC
-#undef PREALLOC_SIZE
-
PyDoc_STRVAR(join__doc__,
"B.join(iterable_of_bytes) -> bytes\n\
@@ -1545,20 +1222,20 @@ _PyBytes_Join(PyObject *sep, PyObject *x)
return bytes_join(sep, x);
}
-Py_LOCAL_INLINE(void)
-bytes_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
-{
- if (*end > len)
- *end = len;
- else if (*end < 0)
- *end += len;
- if (*end < 0)
- *end = 0;
- if (*start < 0)
- *start += len;
- if (*start < 0)
- *start = 0;
-}
+/* helper macro to fixup start/end slice values */
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
Py_LOCAL_INLINE(Py_ssize_t)
bytes_find_internal(PyBytesObject *self, PyObject *args, int dir)
@@ -1595,7 +1272,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir)
PyDoc_STRVAR(find__doc__,
"B.find(sub[, start[, end]]) -> int\n\
\n\
-Return the lowest index in S where substring sub is found,\n\
+Return the lowest index in B where substring sub is found,\n\
such that sub is contained within s[start:end]. Optional\n\
arguments start and end are interpreted as in slice notation.\n\
\n\
@@ -1719,7 +1396,7 @@ do_strip(PyBytesObject *self, int striptype)
i = 0;
if (striptype != RIGHTSTRIP) {
- while (i < len && ISSPACE(s[i])) {
+ while (i < len && Py_ISSPACE(s[i])) {
i++;
}
}
@@ -1728,7 +1405,7 @@ do_strip(PyBytesObject *self, int striptype)
if (striptype != LEFTSTRIP) {
do {
j--;
- } while (j >= i && ISSPACE(s[j]));
+ } while (j >= i && Py_ISSPACE(s[j]));
j++;
}
@@ -1805,7 +1482,7 @@ PyDoc_STRVAR(count__doc__,
"B.count(sub[, start[, end]]) -> int\n\
\n\
Return the number of non-overlapping occurrences of substring sub in\n\
-string S[start:end]. Optional arguments start and end are interpreted\n\
+string B[start:end]. Optional arguments start and end are interpreted\n\
as in slice notation.");
static PyObject *
@@ -1826,10 +1503,10 @@ bytes_count(PyBytesObject *self, PyObject *args)
else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
return NULL;
- bytes_adjust_indices(&start, &end, PyBytes_GET_SIZE(self));
+ ADJUST_INDICES(start, end, PyBytes_GET_SIZE(self));
return PyLong_FromSsize_t(
- stringlib_count(str + start, end - start, sub, sub_len)
+ stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
);
}
@@ -1946,9 +1623,6 @@ bytes_maketrans(PyObject *null, PyObject *args)
return _Py_bytes_maketrans(args);
}
-#define FORWARD 1
-#define REVERSE -1
-
/* find and count characters and substrings */
#define findchar(target, target_len, c) \
@@ -1984,94 +1658,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 */
@@ -2083,30 +1669,28 @@ replace_interleave(PyBytesObject *self,
{
char *self_s, *result_s;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, i, product;
+ Py_ssize_t count, i;
PyBytesObject *result;
self_len = PyBytes_GET_SIZE(self);
- /* 1 at the end plus 1 after every character */
- count = self_len+1;
- if (maxcount < count)
+ /* 1 at the end plus 1 after every character;
+ count = min(maxcount, self_len + 1) */
+ if (maxcount <= self_len)
count = maxcount;
+ else
+ /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
+ count = self_len + 1;
/* Check for overflow */
/* result_len = count * to_len + self_len; */
- product = count * to_len;
- if (product / to_len != count) {
- PyErr_SetString(PyExc_OverflowError,
- "replacement bytes are too long");
- return NULL;
- }
- result_len = product + self_len;
- if (result_len < 0) {
+ assert(count > 0);
+ if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError,
"replacement bytes are too long");
return NULL;
}
+ result_len = count * to_len + self_len;
if (! (result = (PyBytesObject *)
PyBytes_FromStringAndSize(NULL, result_len)) )
@@ -2192,10 +1776,9 @@ replace_delete_substring(PyBytesObject *self,
self_len = PyBytes_GET_SIZE(self);
self_s = PyBytes_AS_STRING(self);
- count = countstring(self_s, self_len,
- from_s, from_len,
- 0, self_len, 1,
- maxcount);
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
if (count == 0) {
/* no matches */
@@ -2214,9 +1797,9 @@ replace_delete_substring(PyBytesObject *self,
start = self_s;
end = self_s + self_len;
while (count-- > 0) {
- offset = findstring(start, end-start,
- from_s, from_len,
- 0, end-start, FORWARD);
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
if (offset == -1)
break;
next = start + offset;
@@ -2292,9 +1875,9 @@ replace_substring_in_place(PyBytesObject *self,
self_s = PyBytes_AS_STRING(self);
self_len = PyBytes_GET_SIZE(self);
- offset = findstring(self_s, self_len,
- from_s, from_len,
- 0, self_len, FORWARD);
+ offset = stringlib_find(self_s, self_len,
+ from_s, from_len,
+ 0);
if (offset == -1) {
/* No matches; return the original string */
return return_self(self);
@@ -2314,9 +1897,9 @@ replace_substring_in_place(PyBytesObject *self,
end = result_s + self_len;
while ( --maxcount > 0) {
- offset = findstring(start, end-start,
- from_s, from_len,
- 0, end-start, FORWARD);
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
if (offset==-1)
break;
Py_MEMCPY(start+offset, to_s, from_len);
@@ -2336,7 +1919,7 @@ replace_single_character(PyBytesObject *self,
char *self_s, *result_s;
char *start, *next, *end;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, product;
+ Py_ssize_t count;
PyBytesObject *result;
self_s = PyBytes_AS_STRING(self);
@@ -2350,18 +1933,13 @@ replace_single_character(PyBytesObject *self,
/* use the difference between current and new, hence the "-1" */
/* result_len = self_len + count * (to_len-1) */
- product = count * (to_len-1);
- if (product / (to_len-1) != count) {
+ assert(count > 0);
+ if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError,
"replacement bytes are too long");
return NULL;
}
- result_len = self_len + product;
- if (result_len < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "replacment bytes are too long");
- return NULL;
- }
+ result_len = self_len + count * (to_len - 1);
if ( (result = (PyBytesObject *)
PyBytes_FromStringAndSize(NULL, result_len)) == NULL)
@@ -2404,15 +1982,16 @@ replace_substring(PyBytesObject *self,
char *self_s, *result_s;
char *start, *next, *end;
Py_ssize_t self_len, result_len;
- Py_ssize_t count, offset, product;
+ Py_ssize_t count, offset;
PyBytesObject *result;
self_s = PyBytes_AS_STRING(self);
self_len = PyBytes_GET_SIZE(self);
- count = countstring(self_s, self_len,
- from_s, from_len,
- 0, self_len, FORWARD, maxcount);
+ count = stringlib_count(self_s, self_len,
+ from_s, from_len,
+ maxcount);
+
if (count == 0) {
/* no matches, return unchanged */
return return_self(self);
@@ -2420,18 +1999,13 @@ replace_substring(PyBytesObject *self,
/* Check for overflow */
/* result_len = self_len + count * (to_len-from_len) */
- product = count * (to_len-from_len);
- if (product / (to_len-from_len) != count) {
- PyErr_SetString(PyExc_OverflowError,
- "replacement bytes are too long");
- return NULL;
- }
- result_len = self_len + product;
- if (result_len < 0) {
+ assert(count > 0);
+ if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
PyErr_SetString(PyExc_OverflowError,
"replacement bytes are too long");
return NULL;
}
+ result_len = self_len + count * (to_len-from_len);
if ( (result = (PyBytesObject *)
PyBytes_FromStringAndSize(NULL, result_len)) == NULL)
@@ -2441,9 +2015,9 @@ replace_substring(PyBytesObject *self,
start = self_s;
end = self_s + self_len;
while (count-- > 0) {
- offset = findstring(start, end-start,
- from_s, from_len,
- 0, end-start, FORWARD);
+ offset = stringlib_find(start, end-start,
+ from_s, from_len,
+ 0);
if (offset == -1)
break;
next = start+offset;
@@ -2601,7 +2175,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
return -1;
str = PyBytes_AS_STRING(self);
- bytes_adjust_indices(&start, &end, len);
+ ADJUST_INDICES(start, end, len);
if (direction < 0) {
/* startswith */
@@ -2710,22 +2284,23 @@ bytes_endswith(PyBytesObject *self, PyObject *args)
PyDoc_STRVAR(decode__doc__,
-"B.decode([encoding[, errors]]) -> str\n\
+"B.decode(encoding='utf-8', errors='strict') -> str\n\
\n\
-Decode S using the codec registered for encoding. encoding defaults\n\
-to the default encoding. errors may be given to set a different error\n\
+Decode B using the codec registered for encoding. Default encoding\n\
+is 'utf-8'. errors may be given to set a different error\n\
handling scheme. Default is 'strict' meaning that encoding errors raise\n\
a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
as well as any other name registerd with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");
static PyObject *
-bytes_decode(PyObject *self, PyObject *args)
+bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char *encoding = NULL;
const char *errors = NULL;
+ static char *kwlist[] = {"encoding", "errors", 0};
- if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
return NULL;
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
@@ -2733,6 +2308,28 @@ bytes_decode(PyObject *self, PyObject *args)
}
+PyDoc_STRVAR(splitlines__doc__,
+"B.splitlines([keepends]) -> list of lines\n\
+\n\
+Return a list of the lines in B, breaking at line boundaries.\n\
+Line breaks are not included in the resulting list unless keepends\n\
+is given and true.");
+
+static PyObject*
+bytes_splitlines(PyObject *self, PyObject *args)
+{
+ int keepends = 0;
+
+ if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
+ return NULL;
+
+ return stringlib_splitlines(
+ (PyObject*) self, PyBytes_AS_STRING(self),
+ PyBytes_GET_SIZE(self), keepends
+ );
+}
+
+
PyDoc_STRVAR(fromhex_doc,
"bytes.fromhex(string) -> bytes\n\
\n\
@@ -2745,11 +2342,11 @@ hex_digit_to_int(Py_UNICODE c)
{
if (c >= 128)
return -1;
- if (ISDIGIT(c))
+ if (Py_ISDIGIT(c))
return c - '0';
else {
- if (ISUPPER(c))
- c = TOLOWER(c);
+ if (Py_ISUPPER(c))
+ c = Py_TOLOWER(c);
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
}
@@ -2815,7 +2412,7 @@ bytes_sizeof(PyBytesObject *v)
static PyObject *
bytes_getnewargs(PyBytesObject *v)
{
- return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v));
+ return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v));
}
@@ -2826,7 +2423,7 @@ bytes_methods[] = {
_Py_capitalize__doc__},
{"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
{"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__},
- {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode__doc__},
+ {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
{"endswith", (PyCFunction)bytes_endswith, METH_VARARGS,
endswith__doc__},
{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
@@ -2865,7 +2462,7 @@ bytes_methods[] = {
{"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__},
{"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__},
{"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__},
- {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
+ {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS,
splitlines__doc__},
{"startswith", (PyCFunction)bytes_startswith, METH_VARARGS,
startswith__doc__},
@@ -2892,6 +2489,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
const char *encoding = NULL;
const char *errors = NULL;
PyObject *new = NULL;
+ Py_ssize_t size;
static char *kwlist[] = {"source", "encoding", "errors", 0};
if (type != &PyBytes_Type)
@@ -2922,28 +2520,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
assert(PyBytes_Check(new));
return new;
}
-
- /* If it's not unicode, there can't be encoding or errors */
- if (encoding != NULL || errors != NULL) {
- PyErr_SetString(PyExc_TypeError,
- "encoding or errors without a string argument");
- return NULL;
- }
- return PyObject_Bytes(x);
-}
-
-PyObject *
-PyBytes_FromObject(PyObject *x)
-{
- PyObject *new, *it;
- Py_ssize_t i, size;
-
- if (x == NULL) {
- PyErr_BadInternalCall();
- return NULL;
- }
-
- /* Is it an int? */
+ /* Is it an integer? */
size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_OverflowError))
@@ -2965,6 +2542,25 @@ PyBytes_FromObject(PyObject *x)
return new;
}
+ /* If it's not unicode, there can't be encoding or errors */
+ if (encoding != NULL || errors != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding or errors without a string argument");
+ return NULL;
+ }
+ return PyObject_Bytes(x);
+}
+
+PyObject *
+PyBytes_FromObject(PyObject *x)
+{
+ PyObject *new, *it;
+ Py_ssize_t i, size;
+
+ if (x == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
/* Use the modern buffer interface */
if (PyObject_CheckBuffer(x)) {
Py_buffer view;
@@ -2984,18 +2580,68 @@ PyBytes_FromObject(PyObject *x)
PyBuffer_Release(&view);
return NULL;
}
+ if (PyUnicode_Check(x)) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot convert unicode object to bytes");
+ return NULL;
+ }
+
+ if (PyList_CheckExact(x)) {
+ new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x));
+ if (new == NULL)
+ return NULL;
+ for (i = 0; i < Py_SIZE(x); i++) {
+ Py_ssize_t value = PyNumber_AsSsize_t(
+ PyList_GET_ITEM(x, i), PyExc_ValueError);
+ if (value == -1 && PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (value < 0 || value >= 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "bytes must be in range(0, 256)");
+ Py_DECREF(new);
+ return NULL;
+ }
+ ((PyBytesObject *)new)->ob_sval[i] = (char) value;
+ }
+ return new;
+ }
+ if (PyTuple_CheckExact(x)) {
+ new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x));
+ if (new == NULL)
+ return NULL;
+ for (i = 0; i < Py_SIZE(x); i++) {
+ Py_ssize_t value = PyNumber_AsSsize_t(
+ PyTuple_GET_ITEM(x, i), PyExc_ValueError);
+ if (value == -1 && PyErr_Occurred()) {
+ Py_DECREF(new);
+ return NULL;
+ }
+ if (value < 0 || value >= 256) {
+ PyErr_SetString(PyExc_ValueError,
+ "bytes must be in range(0, 256)");
+ Py_DECREF(new);
+ return NULL;
+ }
+ ((PyBytesObject *)new)->ob_sval[i] = (char) value;
+ }
+ return new;
+ }
/* For iterator version, create a string object and resize as needed */
- /* XXX(gb): is 64 a good value? also, optimize if length is known */
- /* XXX(guido): perhaps use Pysequence_Fast() -- I can't imagine the
- input being a truly long iterator. */
- size = 64;
+ size = _PyObject_LengthHint(x, 64);
+ if (size == -1 && PyErr_Occurred())
+ return NULL;
+ /* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from
+ returning a shared empty bytes string. This required because we
+ want to call _PyBytes_Resize() the returned object, which we can
+ only do on bytes objects with refcount == 1. */
+ size += 1;
new = PyBytes_FromStringAndSize(NULL, size);
if (new == NULL)
return NULL;
- /* XXX Optimize this if the arguments is a list, tuple */
-
/* Get the iterator */
it = PyObject_GetIter(x);
if (it == NULL)
@@ -3029,7 +2675,7 @@ PyBytes_FromObject(PyObject *x)
/* Append the byte */
if (i >= size) {
- size *= 2;
+ size = 2 * size + 1;
if (_PyBytes_Resize(&new, size) < 0)
goto error;
}
@@ -3200,7 +2846,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
/* _PyBytes_FormatLong emulates the format codes d, u, o, x and X, and
* the F_ALT flag, for Python's long (unbounded) ints. It's not used for
* Python's regular ints.
- * Return value: a new PyString*, or NULL if error.
+ * Return value: a new PyBytes*, or NULL if error.
* . *pbuf is set to point into it,
* *plen set to the # of chars following that.
* Caller must decref it when done using pbuf.
diff --git a/Objects/capsule.c b/Objects/capsule.c
index e25af6c..acd3de6 100644
--- a/Objects/capsule.c
+++ b/Objects/capsule.c
@@ -298,27 +298,27 @@ Python import mechanism to link to one another.\n\
PyTypeObject PyCapsule_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "PyCapsule", /*tp_name*/
- sizeof(PyCapsule), /*tp_basicsize*/
- 0, /*tp_itemsize*/
+ "PyCapsule", /*tp_name*/
+ sizeof(PyCapsule), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
/* methods */
capsule_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_reserved*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
capsule_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- 0, /*tp_flags*/
- PyCapsule_Type__doc__ /*tp_doc*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ 0, /*tp_flags*/
+ PyCapsule_Type__doc__ /*tp_doc*/
};
diff --git a/Objects/classobject.c b/Objects/classobject.c
index afd4ec3..6df930f 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -263,10 +263,10 @@ method_repr(PyMethodObject *a)
return result;
}
-static long
+static Py_hash_t
method_hash(PyMethodObject *a)
{
- long x, y;
+ Py_hash_t x, y;
if (a->im_self == NULL)
x = PyObject_Hash(Py_None);
else
diff --git a/Objects/cobject.c b/Objects/cobject.c
deleted file mode 100644
index a692150..0000000
--- a/Objects/cobject.c
+++ /dev/null
@@ -1,169 +0,0 @@
-
-/* Wrap void* pointers to be passed between C modules */
-
-#include "Python.h"
-
-
-/* Declarations for objects of type PyCObject */
-
-typedef void (*destructor1)(void *);
-typedef void (*destructor2)(void *, void*);
-
-
-static int deprecation_exception(void)
-{
- return PyErr_WarnEx(PyExc_PendingDeprecationWarning,
- "The CObject API is deprecated as of Python 3.1. "
- "Please convert to using the Capsule API.", 1);
-}
-
-PyObject *
-PyCObject_FromVoidPtr(void *cobj, void (*destr)(void *))
-{
- PyCObject *self;
-
- if (deprecation_exception()) {
- return NULL;
- }
-
- self = PyObject_NEW(PyCObject, &PyCObject_Type);
- if (self == NULL)
- return NULL;
- self->cobject=cobj;
- self->destructor=destr;
- self->desc=NULL;
-
- return (PyObject *)self;
-}
-
-PyObject *
-PyCObject_FromVoidPtrAndDesc(void *cobj, void *desc,
- void (*destr)(void *, void *))
-{
- PyCObject *self;
-
- if (deprecation_exception()) {
- return NULL;
- }
-
- if (!desc) {
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_FromVoidPtrAndDesc called with null"
- " description");
- return NULL;
- }
- self = PyObject_NEW(PyCObject, &PyCObject_Type);
- if (self == NULL)
- return NULL;
- self->cobject = cobj;
- self->destructor = (destructor1)destr;
- self->desc = desc;
-
- return (PyObject *)self;
-}
-
-void *
-PyCObject_AsVoidPtr(PyObject *self)
-{
- if (self) {
- if (self->ob_type == &PyCObject_Type)
- return ((PyCObject *)self)->cobject;
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_AsVoidPtr with non-C-object");
- }
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_AsVoidPtr called with null pointer");
- return NULL;
-}
-
-void *
-PyCObject_GetDesc(PyObject *self)
-{
- if (self) {
- if (self->ob_type == &PyCObject_Type)
- return ((PyCObject *)self)->desc;
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_GetDesc with non-C-object");
- }
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyCObject_GetDesc called with null pointer");
- return NULL;
-}
-
-void *
-PyCObject_Import(char *module_name, char *name)
-{
- PyObject *m, *c;
- void *r = NULL;
-
- if ((m = PyImport_ImportModule(module_name))) {
- if ((c = PyObject_GetAttrString(m,name))) {
- r = PyCObject_AsVoidPtr(c);
- Py_DECREF(c);
- }
- Py_DECREF(m);
- }
- return r;
-}
-
-int
-PyCObject_SetVoidPtr(PyObject *self, void *cobj)
-{
- PyCObject* cself = (PyCObject*)self;
- if (cself == NULL || !PyCObject_Check(cself) ||
- cself->destructor != NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Invalid call to PyCObject_SetVoidPtr");
- return 0;
- }
- cself->cobject = cobj;
- return 1;
-}
-
-static void
-PyCObject_dealloc(PyCObject *self)
-{
- if (self->destructor) {
- if(self->desc)
- ((destructor2)(self->destructor))(self->cobject, self->desc);
- else
- (self->destructor)(self->cobject);
- }
- PyObject_DEL(self);
-}
-
-
-PyDoc_STRVAR(PyCObject_Type__doc__,
-"C objects to be exported from one extension module to another\n\
-\n\
-C objects are used for communication between extension modules. They\n\
-provide a way for an extension module to export a C interface to other\n\
-extension modules, so that extension modules can use the Python import\n\
-mechanism to link to one another.");
-
-PyTypeObject PyCObject_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "PyCObject", /*tp_name*/
- sizeof(PyCObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)PyCObject_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_reserved*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- 0, /*tp_flags*/
- PyCObject_Type__doc__ /*tp_doc*/
-};
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index e3eccf7..bb938ea 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -54,7 +54,7 @@ PyCode_New(int argcount, int kwonlyargcount,
Py_ssize_t i;
/* Check argument types */
- if (argcount < 0 || nlocals < 0 ||
+ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
code == NULL ||
consts == NULL || !PyTuple_Check(consts) ||
names == NULL || !PyTuple_Check(names) ||
@@ -108,10 +108,58 @@ PyCode_New(int argcount, int kwonlyargcount,
Py_INCREF(lnotab);
co->co_lnotab = lnotab;
co->co_zombieframe = NULL;
+ co->co_weakreflist = NULL;
}
return co;
}
+PyCodeObject *
+PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
+{
+ static PyObject *emptystring = NULL;
+ static PyObject *nulltuple = NULL;
+ PyObject *filename_ob = NULL;
+ PyObject *funcname_ob = NULL;
+ PyCodeObject *result = NULL;
+ if (emptystring == NULL) {
+ emptystring = PyBytes_FromString("");
+ if (emptystring == NULL)
+ goto failed;
+ }
+ if (nulltuple == NULL) {
+ nulltuple = PyTuple_New(0);
+ if (nulltuple == NULL)
+ goto failed;
+ }
+ funcname_ob = PyUnicode_FromString(funcname);
+ if (funcname_ob == NULL)
+ goto failed;
+ filename_ob = PyUnicode_DecodeFSDefault(filename);
+ if (filename_ob == NULL)
+ goto failed;
+
+ result = PyCode_New(0, /* argcount */
+ 0, /* kwonlyargcount */
+ 0, /* nlocals */
+ 0, /* stacksize */
+ 0, /* flags */
+ emptystring, /* code */
+ nulltuple, /* consts */
+ nulltuple, /* names */
+ nulltuple, /* varnames */
+ nulltuple, /* freevars */
+ nulltuple, /* cellvars */
+ filename_ob, /* filename */
+ funcname_ob, /* name */
+ firstlineno, /* firstlineno */
+ emptystring /* lnotab */
+ );
+
+failed:
+ Py_XDECREF(funcname_ob);
+ Py_XDECREF(filename_ob);
+ return result;
+}
#define OFF(x) offsetof(PyCodeObject, x)
@@ -284,22 +332,28 @@ 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);
}
static PyObject *
code_repr(PyCodeObject *co)
{
- int lineno = -1;
- char *filename = "???";
-
+ int lineno;
if (co->co_firstlineno != 0)
lineno = co->co_firstlineno;
- if (co->co_filename && PyUnicode_Check(co->co_filename))
- filename = _PyUnicode_AsString(co->co_filename);
- return PyUnicode_FromFormat(
- "<code object %.100U at %p, file \"%.300s\", line %d>",
- co->co_name, co, filename, lineno);
+ else
+ lineno = -1;
+ if (co->co_filename && PyUnicode_Check(co->co_filename)) {
+ return PyUnicode_FromFormat(
+ "<code object %U at %p, file \"%U\", line %d>",
+ co->co_name, co, co->co_filename, lineno);
+ } else {
+ return PyUnicode_FromFormat(
+ "<code object %U at %p, file ???, line %d>",
+ co->co_name, co, lineno);
+ }
}
static PyObject *
@@ -363,10 +417,10 @@ code_richcompare(PyObject *self, PyObject *other, int op)
return res;
}
-static long
+static Py_hash_t
code_hash(PyCodeObject *co)
{
- long h, h0, h1, h2, h3, h4, h5, h6;
+ Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
h0 = PyObject_Hash(co->co_name);
if (h0 == -1) return -1;
h1 = PyObject_Hash(co->co_code);
@@ -415,7 +469,7 @@ PyTypeObject PyCode_Type = {
0, /* tp_traverse */
0, /* tp_clear */
code_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
+ offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
@@ -431,54 +485,14 @@ 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
PyCode_Addr2Line(PyCodeObject *co, int addrq)
{
- int size = PyBytes_Size(co->co_lnotab) / 2;
+ Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
int line = co->co_firstlineno;
int addr = 0;
@@ -491,87 +505,13 @@ 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;
+ Py_ssize_t size;
+ int addr, line;
unsigned char* p;
p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
@@ -586,11 +526,9 @@ PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
instr_lb -- if we stored the matching value of p
somwhere we could skip the first while loop. */
- /* see comments in compile.c for the description of
+ /* See lnotab_notes.txt for the description of
co_lnotab. A point to remember: increments to p
- should come in pairs -- although we don't care about
- the line increments here, treating them as byte
- increments gets confusing, to say the least. */
+ come in (addr, line) pairs. */
bounds->ap_lower = 0;
while (size > 0) {
@@ -603,13 +541,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 4948a21..e247ba9 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -8,8 +8,6 @@
#include "Python.h"
#include "structmember.h"
-#ifndef WITHOUT_COMPLEX
-
/* elementary operations on complex numbers */
static Py_complex c_1 = {1., 0.};
@@ -264,12 +262,25 @@ PyComplex_ImagAsDouble(PyObject *op)
}
}
+static PyObject *
+try_complex_special_method(PyObject *op) {
+ PyObject *f;
+ static PyObject *complexstr;
+
+ f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
+ if (f) {
+ PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
+ Py_DECREF(f);
+ return res;
+ }
+ return NULL;
+}
+
Py_complex
PyComplex_AsCComplex(PyObject *op)
{
Py_complex cv;
PyObject *newop = NULL;
- static PyObject *complex_str = NULL;
assert(op);
/* If op is already of type PyComplex_Type, return its value */
@@ -282,21 +293,7 @@ PyComplex_AsCComplex(PyObject *op)
cv.real = -1.;
cv.imag = 0.;
- if (complex_str == NULL) {
- if (!(complex_str = PyUnicode_FromString("__complex__")))
- return cv;
- }
-
- {
- PyObject *complexfunc;
- complexfunc = _PyType_Lookup(op->ob_type, complex_str);
- /* complexfunc is a borrowed reference */
- if (complexfunc) {
- newop = PyObject_CallFunctionObjArgs(complexfunc, op, NULL);
- if (!newop)
- return cv;
- }
- }
+ newop = try_complex_special_method(op);
if (newop) {
if (!PyComplex_Check(newop)) {
@@ -309,6 +306,9 @@ PyComplex_AsCComplex(PyObject *op)
Py_DECREF(newop);
return cv;
}
+ else if (PyErr_Occurred()) {
+ return cv;
+ }
/* If neither of the above works, interpret op as a float giving the
real part of the result, and fill in the imaginary part as 0. */
else {
@@ -324,10 +324,11 @@ complex_dealloc(PyObject *op)
op->ob_type->tp_free(op);
}
-
static PyObject *
-complex_format(PyComplexObject *v, int precision, char format_code)
+complex_repr(PyComplexObject *v)
{
+ int precision = 0;
+ char format_code = 'r';
PyObject *result = NULL;
Py_ssize_t len;
@@ -344,6 +345,8 @@ complex_format(PyComplexObject *v, int precision, char format_code)
char *tail = "";
if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
+ /* Real part is +0: just output the imaginary part and do not
+ include parens. */
re = "";
im = PyOS_double_to_string(v->cval.imag, format_code,
precision, 0, NULL);
@@ -352,7 +355,8 @@ complex_format(PyComplexObject *v, int precision, char format_code)
goto done;
}
} else {
- /* Format imaginary part with sign, real part without */
+ /* Format imaginary part with sign, real part without. Include
+ parens in the result. */
pre = PyOS_double_to_string(v->cval.real, format_code,
precision, 0, NULL);
if (!pre) {
@@ -371,7 +375,7 @@ complex_format(PyComplexObject *v, int precision, char format_code)
tail = ")";
}
/* Alloc the final buffer. Add one for the "j" in the format string,
- and one for the trailing zero. */
+ and one for the trailing zero byte. */
len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
buf = PyMem_Malloc(len);
if (!buf) {
@@ -388,27 +392,15 @@ complex_format(PyComplexObject *v, int precision, char format_code)
return result;
}
-static PyObject *
-complex_repr(PyComplexObject *v)
-{
- return complex_format(v, 0, 'r');
-}
-
-static PyObject *
-complex_str(PyComplexObject *v)
-{
- return complex_format(v, PyFloat_STR_PRECISION, 'g');
-}
-
-static long
+static Py_hash_t
complex_hash(PyComplexObject *v)
{
- long hashreal, hashimag, combined;
- hashreal = _Py_HashDouble(v->cval.real);
- if (hashreal == -1)
+ Py_uhash_t hashreal, hashimag, combined;
+ hashreal = (Py_uhash_t)_Py_HashDouble(v->cval.real);
+ if (hashreal == (Py_uhash_t)-1)
return -1;
- hashimag = _Py_HashDouble(v->cval.imag);
- if (hashimag == -1)
+ hashimag = (Py_uhash_t)_Py_HashDouble(v->cval.imag);
+ if (hashimag == (Py_uhash_t)-1)
return -1;
/* Note: if the imaginary part is 0, hashimag is 0 now,
* so the following returns hashreal unchanged. This is
@@ -416,10 +408,10 @@ complex_hash(PyComplexObject *v)
* compare equal must have the same hash value, so that
* hash(x + 0*j) must equal hash(x).
*/
- combined = hashreal + 1000003 * hashimag;
- if (combined == -1)
- combined = -2;
- return combined;
+ combined = hashreal + _PyHASH_IMAG * hashimag;
+ if (combined == (Py_uhash_t)-1)
+ combined = (Py_uhash_t)-2;
+ return (Py_hash_t)combined;
}
/* This macro may return! */
@@ -504,7 +496,7 @@ complex_div(PyObject *v, PyObject *w)
quot = c_quot(a, b);
PyFPE_END_PROTECT(quot)
if (errno == EDOM) {
- PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
+ PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero");
return NULL;
}
return PyComplex_FromCComplex(quot);
@@ -620,24 +612,58 @@ static PyObject *
complex_richcompare(PyObject *v, PyObject *w, int op)
{
PyObject *res;
- Py_complex i, j;
- TO_COMPLEX(v, i);
- TO_COMPLEX(w, j);
+ Py_complex i;
+ int equal;
if (op != Py_EQ && op != Py_NE) {
- /* XXX Should eventually return NotImplemented */
- PyErr_SetString(PyExc_TypeError,
- "no ordering relation is defined for complex numbers");
- return NULL;
+ goto Unimplemented;
}
- if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ))
- res = Py_True;
+ assert(PyComplex_Check(v));
+ TO_COMPLEX(v, i);
+
+ if (PyLong_Check(w)) {
+ /* Check for 0.0 imaginary part first to avoid the rich
+ * comparison when possible.
+ */
+ if (i.imag == 0.0) {
+ PyObject *j, *sub_res;
+ j = PyFloat_FromDouble(i.real);
+ if (j == NULL)
+ return NULL;
+
+ sub_res = PyObject_RichCompare(j, w, op);
+ Py_DECREF(j);
+ return sub_res;
+ }
+ else {
+ equal = 0;
+ }
+ }
+ else if (PyFloat_Check(w)) {
+ equal = (i.real == PyFloat_AsDouble(w) && i.imag == 0.0);
+ }
+ else if (PyComplex_Check(w)) {
+ Py_complex j;
+
+ TO_COMPLEX(w, j);
+ equal = (i.real == j.real && i.imag == j.imag);
+ }
+ else {
+ goto Unimplemented;
+ }
+
+ if (equal == (op == Py_EQ))
+ res = Py_True;
else
- res = Py_False;
+ res = Py_False;
Py_INCREF(res);
return res;
+
+Unimplemented:
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
static PyObject *
@@ -738,26 +764,30 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
char *end;
double x=0.0, y=0.0, z;
int got_bracket=0;
- char s_buffer[256];
+ PyObject *s_buffer = NULL;
Py_ssize_t len;
if (PyUnicode_Check(v)) {
- if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) {
- PyErr_SetString(PyExc_ValueError,
- "complex() literal too large to convert");
+ Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v);
+ Py_UNICODE *bufptr;
+ s_buffer = PyUnicode_TransformDecimalToASCII(
+ PyUnicode_AS_UNICODE(v), buflen);
+ if (s_buffer == NULL)
return NULL;
+ /* Replace non-ASCII whitespace with ' ' */
+ bufptr = PyUnicode_AS_UNICODE(s_buffer);
+ for (i = 0; i < buflen; i++) {
+ Py_UNICODE ch = bufptr[i];
+ if (ch > 127 && Py_UNICODE_ISSPACE(ch))
+ bufptr[i] = ' ';
}
- if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
- PyUnicode_GET_SIZE(v),
- s_buffer,
- NULL))
- return NULL;
- s = s_buffer;
- len = strlen(s);
+ s = _PyUnicode_AsStringAndSize(s_buffer, &len);
+ if (s == NULL)
+ goto error;
}
else if (PyObject_AsCharBuffer(v, &s, &len)) {
PyErr_SetString(PyExc_TypeError,
- "complex() arg is not a string");
+ "complex() argument must be a string or a number");
return NULL;
}
@@ -800,7 +830,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
if (PyErr_ExceptionMatches(PyExc_ValueError))
PyErr_Clear();
else
- return NULL;
+ goto error;
}
if (end != s) {
/* all 4 forms starting with <float> land here */
@@ -813,7 +843,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
if (PyErr_ExceptionMatches(PyExc_ValueError))
PyErr_Clear();
else
- return NULL;
+ goto error;
}
if (end != s)
/* <float><signed-float>j */
@@ -868,24 +898,26 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v)
if (s-start != len)
goto parse_error;
+ Py_XDECREF(s_buffer);
return complex_subtype_from_doubles(type, x, y);
parse_error:
PyErr_SetString(PyExc_ValueError,
"complex() arg is a malformed string");
+ error:
+ Py_XDECREF(s_buffer);
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;
@@ -920,26 +952,15 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
- /* XXX Hack to support classes with __complex__ method */
- if (complexstr == NULL) {
- complexstr = PyUnicode_InternFromString("__complex__");
- if (complexstr == NULL)
- return NULL;
- }
- f = PyObject_GetAttr(r, complexstr);
- if (f == NULL)
- PyErr_Clear();
- else {
- PyObject *args = PyTuple_New(0);
- if (args == NULL)
- return NULL;
- r = PyEval_CallObject(f, args);
- Py_DECREF(args);
- Py_DECREF(f);
- if (r == NULL)
- return NULL;
+ tmp = try_complex_special_method(r);
+ if (tmp) {
+ r = tmp;
own_r = 1;
}
+ else if (PyErr_Occurred()) {
+ return NULL;
+ }
+
nbr = r->ob_type->tp_as_number;
if (i != NULL)
nbi = i->ob_type->tp_as_number;
@@ -1079,7 +1100,7 @@ PyTypeObject PyComplex_Type = {
0, /* tp_as_mapping */
(hashfunc)complex_hash, /* tp_hash */
0, /* tp_call */
- (reprfunc)complex_str, /* tp_str */
+ (reprfunc)complex_repr, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
@@ -1104,5 +1125,3 @@ PyTypeObject PyComplex_Type = {
complex_new, /* tp_new */
PyObject_Del, /* tp_free */
};
-
-#endif
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 9eda4bd..93daefd 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -92,7 +92,7 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
"descriptor '%V' for type '%s' "
"needs either an object or a type",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name);
+ PyDescr_TYPE(descr)->tp_name);
return NULL;
}
}
@@ -101,16 +101,16 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
"descriptor '%V' for type '%s' "
"needs a type, not a '%s' as arg 2",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name,
+ PyDescr_TYPE(descr)->tp_name,
type->ob_type->tp_name);
return NULL;
}
- if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) {
+ if (!PyType_IsSubtype((PyTypeObject *)type, PyDescr_TYPE(descr))) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' for type '%s' "
"doesn't apply to type '%s'",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name,
+ PyDescr_TYPE(descr)->tp_name,
((PyTypeObject *)type)->tp_name);
return NULL;
}
@@ -149,7 +149,7 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
PyErr_Format(PyExc_AttributeError,
"attribute '%V' of '%.100s' objects is not readable",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name);
+ PyDescr_TYPE(descr)->tp_name);
return NULL;
}
@@ -204,7 +204,7 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
PyErr_Format(PyExc_AttributeError,
"attribute '%V' of '%.100s' objects is not writable",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name);
+ PyDescr_TYPE(descr)->tp_name);
return -1;
}
@@ -222,18 +222,18 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
"descriptor '%V' of '%.100s' "
"object needs an argument",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name);
+ PyDescr_TYPE(descr)->tp_name);
return NULL;
}
self = PyTuple_GET_ITEM(args, 0);
if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
- (PyObject *)(descr->d_type))) {
+ (PyObject *)PyDescr_TYPE(descr))) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' "
"requires a '%.100s' object "
"but received a '%.100s'",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name,
+ PyDescr_TYPE(descr)->tp_name,
self->ob_type->tp_name);
return NULL;
}
@@ -258,7 +258,7 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
{
PyObject *func, *result;
- func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type);
+ func = PyCFunction_New(descr->d_method, (PyObject *)PyDescr_TYPE(descr));
if (func == NULL)
return NULL;
@@ -281,18 +281,18 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
"descriptor '%V' of '%.100s' "
"object needs an argument",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name);
+ PyDescr_TYPE(descr)->tp_name);
return NULL;
}
self = PyTuple_GET_ITEM(args, 0);
if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
- (PyObject *)(descr->d_type))) {
+ (PyObject *)PyDescr_TYPE(descr))) {
PyErr_Format(PyExc_TypeError,
"descriptor '%V' "
"requires a '%.100s' object "
"but received a '%.100s'",
descr_name((PyDescrObject *)descr), "?",
- descr->d_type->tp_name,
+ PyDescr_TYPE(descr)->tp_name,
self->ob_type->tp_name);
return NULL;
}
@@ -712,19 +712,19 @@ proxy_get(proxyobject *pp, PyObject *args)
static PyObject *
proxy_keys(proxyobject *pp)
{
- return PyMapping_Keys(pp->dict);
+ return PyObject_CallMethod(pp->dict, "keys", NULL);
}
static PyObject *
proxy_values(proxyobject *pp)
{
- return PyMapping_Values(pp->dict);
+ return PyObject_CallMethod(pp->dict, "values", NULL);
}
static PyObject *
proxy_items(proxyobject *pp)
{
- return PyMapping_Items(pp->dict);
+ return PyObject_CallMethod(pp->dict, "items", NULL);
}
static PyObject *
@@ -924,10 +924,10 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op)
return v;
}
-static long
+static Py_hash_t
wrapper_hash(wrapperobject *wp)
{
- int x, y;
+ Py_hash_t x, y;
x = _Py_HashPointer(wp->descr);
if (x == -1)
return -1;
@@ -957,7 +957,7 @@ static PyMemberDef wrapper_members[] = {
static PyObject *
wrapper_objclass(wrapperobject *wp)
{
- PyObject *c = (PyObject *)wp->descr->d_type;
+ PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr);
Py_INCREF(c);
return c;
@@ -1068,7 +1068,7 @@ PyWrapper_New(PyObject *d, PyObject *self)
assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
descr = (PyWrapperDescrObject *)d;
assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
- (PyObject *)(descr->d_type)));
+ (PyObject *)PyDescr_TYPE(descr)));
wp = PyObject_GC_New(wrapperobject, &wrappertype);
if (wp != NULL) {
@@ -1124,7 +1124,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},
@@ -1141,7 +1141,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);
}
@@ -1151,7 +1151,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);
}
@@ -1161,7 +1161,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);
}
@@ -1199,7 +1199,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
return NULL;
}
- return PyObject_CallFunction(gs->prop_get, "(O)", obj);
+ return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL);
}
static int
@@ -1220,9 +1220,9 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
return -1;
}
if (value == NULL)
- res = PyObject_CallFunction(func, "(O)", obj);
+ res = PyObject_CallFunctionObjArgs(func, obj, NULL);
else
- res = PyObject_CallFunction(func, "(OO)", obj, value);
+ res = PyObject_CallFunctionObjArgs(func, obj, value, NULL);
if (res == NULL)
return -1;
Py_DECREF(res);
@@ -1230,11 +1230,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)
@@ -1252,15 +1251,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);
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 8492c61..3fa5cc4 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -124,15 +124,6 @@ masked); and the PyDictObject struct required a member to hold the table's
polynomial. In Tim's experiments the current scheme ran faster, produced
equally good collision statistics, needed less code & used less memory.
-Theoretical Python 2.5 headache: hash codes are only C "long", but
-sizeof(Py_ssize_t) > sizeof(long) may be possible. In that case, and if a
-dict is genuinely huge, then only the slots directly reachable via indexing
-by a C long can be the first slot in a probe sequence. The probe sequence
-will still eventually reach every slot in the table, but the collision rate
-on initial probes may be much higher than this scheme was designed for.
-Getting a hash code as fat as Py_ssize_t is the only real cure. But in
-practice, this probably won't make a lick of difference for many years (at
-which point everyone will have terabytes of RAM on 64-bit boxes).
*/
/* Object used as dummy key to fill deleted entries */
@@ -148,7 +139,7 @@ _PyDict_Dummy(void)
/* forward declarations */
static PyDictEntry *
-lookdict_unicode(PyDictObject *mp, PyObject *key, long hash);
+lookdict_unicode(PyDictObject *mp, PyObject *key, Py_hash_t hash);
#ifdef SHOW_CONVERSION_COUNTS
static long created = 0L;
@@ -318,7 +309,7 @@ the caller can (if it wishes) add the <key, value> pair to the returned
PyDictEntry*.
*/
static PyDictEntry *
-lookdict(PyDictObject *mp, PyObject *key, register long hash)
+lookdict(PyDictObject *mp, PyObject *key, register Py_hash_t hash)
{
register size_t i;
register size_t perturb;
@@ -407,7 +398,7 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash)
* This is valuable because dicts with only unicode keys are very common.
*/
static PyDictEntry *
-lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash)
+lookdict_unicode(PyDictObject *mp, PyObject *key, register Py_hash_t hash)
{
register size_t i;
register size_t perturb;
@@ -458,6 +449,21 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash)
return 0;
}
+int
+_PyDict_HasOnlyStringKeys(PyObject *dict)
+{
+ Py_ssize_t pos = 0;
+ PyObject *key, *value;
+ assert(PyDict_Check(dict));
+ /* Shortcut */
+ if (((PyDictObject *)dict)->ma_lookup == lookdict_unicode)
+ return 1;
+ while (PyDict_Next(dict, &pos, &key, &value))
+ if (!PyUnicode_Check(key))
+ return 0;
+ return 1;
+}
+
#ifdef SHOW_TRACK_COUNT
#define INCREASE_TRACK_COUNT \
(count_tracked++, count_untracked--);
@@ -512,11 +518,11 @@ Eats a reference to key and one to value.
Returns -1 if an error occurred, or 0 on success.
*/
static int
-insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
+insertdict(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
{
PyObject *old_value;
register PyDictEntry *ep;
- typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, long);
+ typedef PyDictEntry *(*lookupfunc)(PyDictObject *, PyObject *, Py_hash_t);
assert(mp->ma_lookup != NULL);
ep = mp->ma_lookup(mp, key, hash);
@@ -540,7 +546,7 @@ insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
Py_DECREF(dummy);
}
ep->me_key = key;
- ep->me_hash = (Py_ssize_t)hash;
+ ep->me_hash = hash;
ep->me_value = value;
mp->ma_used++;
}
@@ -556,7 +562,7 @@ Note that no refcounts are changed by this routine; if needed, the caller
is responsible for incref'ing `key` and `value`.
*/
static void
-insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
+insertdict_clean(register PyDictObject *mp, PyObject *key, Py_hash_t hash,
PyObject *value)
{
register size_t i;
@@ -575,7 +581,7 @@ insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
assert(ep->me_value == NULL);
mp->ma_fill++;
ep->me_key = key;
- ep->me_hash = (Py_ssize_t)hash;
+ ep->me_hash = hash;
ep->me_value = value;
mp->ma_used++;
}
@@ -652,8 +658,7 @@ dictresize(PyDictObject *mp, Py_ssize_t minused)
for (ep = oldtable; i > 0; ep++) {
if (ep->me_value != NULL) { /* active entry */
--i;
- insertdict_clean(mp, ep->me_key, (long)ep->me_hash,
- ep->me_value);
+ insertdict_clean(mp, ep->me_key, ep->me_hash, ep->me_value);
}
else if (ep->me_key != NULL) { /* dummy entry */
--i;
@@ -698,7 +703,7 @@ _PyDict_NewPresized(Py_ssize_t minused)
PyObject *
PyDict_GetItem(PyObject *op, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
PyDictObject *mp = (PyDictObject *)op;
PyDictEntry *ep;
PyThreadState *tstate;
@@ -719,7 +724,8 @@ PyDict_GetItem(PyObject *op, PyObject *key)
Let's just hope that no exception occurs then... This must be
_PyThreadState_Current and not PyThreadState_GET() because in debug
mode, the latter complains if tstate is NULL. */
- tstate = _PyThreadState_Current;
+ tstate = (PyThreadState*)_Py_atomic_load_relaxed(
+ &_PyThreadState_Current);
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
PyObject *err_type, *err_value, *err_tb;
@@ -747,7 +753,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
PyObject *
PyDict_GetItemWithError(PyObject *op, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
PyDictObject*mp = (PyDictObject *)op;
PyDictEntry *ep;
@@ -780,7 +786,7 @@ int
PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
{
register PyDictObject *mp;
- register long hash;
+ register Py_hash_t hash;
register Py_ssize_t n_used;
if (!PyDict_Check(op)) {
@@ -826,7 +832,7 @@ int
PyDict_DelItem(PyObject *op, PyObject *key)
{
register PyDictObject *mp;
- register long hash;
+ register Py_hash_t hash;
register PyDictEntry *ep;
PyObject *old_value, *old_key;
@@ -972,7 +978,7 @@ PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/
int
-_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash)
+_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, Py_hash_t *phash)
{
register Py_ssize_t i;
register Py_ssize_t mask;
@@ -990,7 +996,7 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue,
*ppos = i+1;
if (i > mask)
return 0;
- *phash = (long)(ep[i].me_hash);
+ *phash = ep[i].me_hash;
if (pkey)
*pkey = ep[i].me_key;
if (pvalue)
@@ -1112,7 +1118,7 @@ static PyObject *
dict_subscript(PyDictObject *mp, register PyObject *key)
{
PyObject *v;
- long hash;
+ Py_hash_t hash;
PyDictEntry *ep;
assert(mp->ma_table != NULL);
if (!PyUnicode_CheckExact(key) ||
@@ -1306,7 +1312,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
PyObject *oldvalue;
Py_ssize_t pos = 0;
PyObject *key;
- long hash;
+ Py_hash_t hash;
if (dictresize(mp, Py_SIZE(seq)))
return NULL;
@@ -1324,7 +1330,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
PyDictObject *mp = (PyDictObject *)d;
Py_ssize_t pos = 0;
PyObject *key;
- long hash;
+ Py_hash_t hash;
if (dictresize(mp, PySet_GET_SIZE(seq)))
return NULL;
@@ -1386,8 +1392,12 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds, char *methnam
else
result = PyDict_MergeFromSeq2(self, arg, 1);
}
- if (result == 0 && kwds != NULL)
- result = PyDict_Merge(self, kwds, 1);
+ if (result == 0 && kwds != NULL) {
+ if (PyArg_ValidateKeywordArguments(kwds))
+ result = PyDict_Merge(self, kwds, 1);
+ else
+ result = -1;
+ }
return result;
}
@@ -1529,7 +1539,7 @@ PyDict_Merge(PyObject *a, PyObject *b, int override)
Py_INCREF(entry->me_key);
Py_INCREF(entry->me_value);
if (insertdict(mp, entry->me_key,
- (long)entry->me_hash,
+ entry->me_hash,
entry->me_value) != 0)
return -1;
}
@@ -1712,7 +1722,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
static PyObject *
dict_contains(register PyDictObject *mp, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
PyDictEntry *ep;
if (!PyUnicode_CheckExact(key) ||
@@ -1733,7 +1743,7 @@ dict_get(register PyDictObject *mp, PyObject *args)
PyObject *key;
PyObject *failobj = Py_None;
PyObject *val = NULL;
- long hash;
+ Py_hash_t hash;
PyDictEntry *ep;
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
@@ -1762,7 +1772,7 @@ dict_setdefault(register PyDictObject *mp, PyObject *args)
PyObject *key;
PyObject *failobj = Py_None;
PyObject *val = NULL;
- long hash;
+ Py_hash_t hash;
PyDictEntry *ep;
if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
@@ -1798,7 +1808,7 @@ dict_clear(register PyDictObject *mp)
static PyObject *
dict_pop(PyDictObject *mp, PyObject *args)
{
- long hash;
+ Py_hash_t hash;
PyDictEntry *ep;
PyObject *old_value, *old_key;
PyObject *key, *deflt = NULL;
@@ -1843,7 +1853,7 @@ dict_pop(PyDictObject *mp, PyObject *args)
static PyObject *
dict_popitem(PyDictObject *mp)
{
- Py_ssize_t i = 0;
+ Py_hash_t i = 0;
PyDictEntry *ep;
PyObject *res;
@@ -2018,7 +2028,7 @@ static PyMethodDef mapp_methods[] = {
int
PyDict_Contains(PyObject *op, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
PyDictObject *mp = (PyDictObject *)op;
PyDictEntry *ep;
@@ -2034,7 +2044,7 @@ PyDict_Contains(PyObject *op, PyObject *key)
/* Internal version of PyDict_Contains used when the hash value is already known */
int
-_PyDict_Contains(PyObject *op, PyObject *key, long hash)
+_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
{
PyDictObject *mp = (PyDictObject *)op;
PyDictEntry *ep;
@@ -2123,7 +2133,7 @@ PyTypeObject PyDict_Type = {
0, /* tp_as_number */
&dict_as_sequence, /* tp_as_sequence */
&dict_as_mapping, /* tp_as_mapping */
- (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
@@ -2786,7 +2796,63 @@ static PyNumberMethods dictviews_as_number = {
(binaryfunc)dictviews_or, /*nb_or*/
};
+static PyObject*
+dictviews_isdisjoint(PyObject *self, PyObject *other)
+{
+ PyObject *it;
+ PyObject *item = NULL;
+
+ if (self == other) {
+ if (dictview_len((dictviewobject *)self) == 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+
+ /* Iterate over the shorter object (only if other is a set,
+ * because PySequence_Contains may be expensive otherwise): */
+ if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
+ Py_ssize_t len_self = dictview_len((dictviewobject *)self);
+ Py_ssize_t len_other = PyObject_Size(other);
+ if (len_other == -1)
+ return NULL;
+
+ if ((len_other > len_self)) {
+ PyObject *tmp = other;
+ other = self;
+ self = tmp;
+ }
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return NULL;
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ int contains = PySequence_Contains(self, item);
+ Py_DECREF(item);
+ if (contains == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+
+ if (contains) {
+ Py_DECREF(it);
+ Py_RETURN_FALSE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL; /* PyIter_Next raised an exception. */
+ Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if the view and the given iterable have a null intersection.");
+
static PyMethodDef dictkeys_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};
@@ -2871,6 +2937,8 @@ static PySequenceMethods dictitems_as_sequence = {
};
static PyMethodDef dictitems_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};
diff --git a/Objects/enumobject.c b/Objects/enumobject.c
index b579f96..00a3346 100644
--- a/Objects/enumobject.c
+++ b/Objects/enumobject.c
@@ -159,12 +159,13 @@ enum_next(enumobject *en)
}
PyDoc_STRVAR(enum_doc,
-"enumerate(iterable) -> iterator for index, value of iterable\n"
+"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
"\n"
"Return an enumerate object. iterable must be another object that supports\n"
"iteration. The enumerate object yields pairs containing a count (from\n"
-"zero) and a value yielded by the iterable argument. enumerate is useful\n"
-"for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
+"start, which defaults to zero) and a value yielded by the iterable argument.\n"
+"enumerate is useful for obtaining an indexed list:\n"
+" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
PyTypeObject PyEnum_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 1531867..0106ba3 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -959,20 +959,27 @@ SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
/* This is called "my_basename" instead of just "basename" to avoid name
conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
defined, and Python does define that. */
-static char *
-my_basename(char *name)
-{
- char *cp = name;
- char *result = name;
-
- if (name == NULL)
- return "???";
- while (*cp != '\0') {
- if (*cp == SEP)
- result = cp + 1;
- ++cp;
+static PyObject*
+my_basename(PyObject *name)
+{
+ Py_UNICODE *unicode;
+ Py_ssize_t i, size, offset;
+
+ unicode = PyUnicode_AS_UNICODE(name);
+ size = PyUnicode_GET_SIZE(name);
+ offset = 0;
+ for(i=0; i < size; i++) {
+ if (unicode[i] == SEP)
+ offset = i + 1;
+ }
+ if (offset != 0) {
+ return PyUnicode_FromUnicode(
+ PyUnicode_AS_UNICODE(name) + offset,
+ size - offset);
+ } else {
+ Py_INCREF(name);
+ return name;
}
- return result;
}
@@ -980,7 +987,8 @@ static PyObject *
SyntaxError_str(PySyntaxErrorObject *self)
{
int have_lineno = 0;
- char *filename = 0;
+ PyObject *filename;
+ PyObject *result;
/* Below, we always ignore overflow errors, just printing -1.
Still, we cannot allow an OverflowError to be raised, so
we need to call PyLong_AsLongAndOverflow. */
@@ -990,7 +998,11 @@ SyntaxError_str(PySyntaxErrorObject *self)
lineno here */
if (self->filename && PyUnicode_Check(self->filename)) {
- filename = _PyUnicode_AsString(self->filename);
+ filename = my_basename(self->filename);
+ if (filename == NULL)
+ return NULL;
+ } else {
+ filename = NULL;
}
have_lineno = (self->lineno != NULL) && PyLong_CheckExact(self->lineno);
@@ -998,18 +1010,20 @@ SyntaxError_str(PySyntaxErrorObject *self)
return PyObject_Str(self->msg ? self->msg : Py_None);
if (filename && have_lineno)
- return PyUnicode_FromFormat("%S (%s, line %ld)",
+ result = PyUnicode_FromFormat("%S (%U, line %ld)",
self->msg ? self->msg : Py_None,
- my_basename(filename),
+ filename,
PyLong_AsLongAndOverflow(self->lineno, &overflow));
else if (filename)
- return PyUnicode_FromFormat("%S (%s)",
+ result = PyUnicode_FromFormat("%S (%U)",
self->msg ? self->msg : Py_None,
- my_basename(filename));
+ filename);
else /* only have_lineno */
- return PyUnicode_FromFormat("%S (line %ld)",
+ result = PyUnicode_FromFormat("%S (line %ld)",
self->msg ? self->msg : Py_None,
PyLong_AsLongAndOverflow(self->lineno, &overflow));
+ Py_XDECREF(filename);
+ return result;
}
static PyMemberDef SyntaxError_members[] = {
@@ -1496,7 +1510,7 @@ PyUnicodeEncodeError_Create(
const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
Py_ssize_t start, Py_ssize_t end, const char *reason)
{
- return PyObject_CallFunction(PyExc_UnicodeEncodeError, "Uu#nnU",
+ return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
encoding, object, length, start, end, reason);
}
@@ -1608,7 +1622,7 @@ PyUnicodeDecodeError_Create(
const char *encoding, const char *object, Py_ssize_t length,
Py_ssize_t start, Py_ssize_t end, const char *reason)
{
- return PyObject_CallFunction(PyExc_UnicodeDecodeError, "Uy#nnU",
+ return PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
encoding, object, length, start, end, reason);
}
@@ -1922,6 +1936,7 @@ SimpleExtendsException(PyExc_Warning, UnicodeWarning,
"Base class for warnings about Unicode related problems, mostly\n"
"related to conversion problems.");
+
/*
* BytesWarning extends Warning
*/
@@ -1930,6 +1945,13 @@ SimpleExtendsException(PyExc_Warning, BytesWarning,
"related to conversion from str or comparing to str.");
+/*
+ * ResourceWarning extends Warning
+ */
+SimpleExtendsException(PyExc_Warning, ResourceWarning,
+ "Base class for warnings about resource usage.");
+
+
/* Pre-computed RuntimeError instance for when recursion depth is reached.
Meant to be used when normalizing the exception for exceeding the recursion
@@ -2004,6 +2026,7 @@ _PyExc_Init(void)
PRE_INIT(ImportWarning)
PRE_INIT(UnicodeWarning)
PRE_INIT(BytesWarning)
+ PRE_INIT(ResourceWarning)
bltinmod = PyImport_ImportModule("builtins");
if (bltinmod == NULL)
@@ -2066,6 +2089,7 @@ _PyExc_Init(void)
POST_INIT(ImportWarning)
POST_INIT(UnicodeWarning)
POST_INIT(BytesWarning)
+ POST_INIT(ResourceWarning)
preallocate_memerrors();
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index b36aa02..d20f196 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -29,7 +29,7 @@ PyObject *
PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding,
char *errors, char *newline, int closefd)
{
- PyObject *io, *stream, *nameobj = NULL;
+ PyObject *io, *stream;
io = PyImport_ImportModule("io");
if (io == NULL)
@@ -40,16 +40,8 @@ PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding,
Py_DECREF(io);
if (stream == NULL)
return NULL;
- if (name != NULL) {
- nameobj = PyUnicode_FromString(name);
- if (nameobj == NULL)
- PyErr_Clear();
- else {
- if (PyObject_SetAttrString(stream, "name", nameobj) < 0)
- PyErr_Clear();
- Py_DECREF(nameobj);
- }
- }
+ /* ignore name attribute because the name attribute of _BufferedIOMixin
+ and TextIOWrapper is read only */
return stream;
}
@@ -352,7 +344,7 @@ stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
}
static int
-fileio_init(PyObject *self, PyObject *args, PyObject *kwds)
+stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyErr_SetString(PyExc_TypeError,
"cannot create 'stderrprinter' instances");
@@ -398,7 +390,13 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS
errno = 0;
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+ if (n > INT_MAX)
+ n = INT_MAX;
+ n = write(self->fd, c, (int)n);
+#else
n = write(self->fd, c, n);
+#endif
Py_END_ALLOW_THREADS
if (n < 0) {
@@ -517,7 +515,7 @@ PyTypeObject PyStdPrinter_Type = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- fileio_init, /* tp_init */
+ stdprinter_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
stdprinter_new, /* tp_new */
PyObject_Del, /* tp_free */
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 8161ed5..09c0e961 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -5,7 +5,6 @@
for any kind of float exception without losing portability. */
#include "Python.h"
-#include "structseq.h"
#include <ctype.h>
#include <float.h>
@@ -21,7 +20,22 @@
extern int finite(double);
#endif
-/* Special free list -- see comments for same code in intobject.c. */
+/* Special free list
+
+ Since some Python programs can spend much of their time allocating
+ and deallocating floats, these operations should be very fast.
+ Therefore we use a dedicated allocation scheme with a much lower
+ overhead (in space and time) than straight malloc(): a simple
+ dedicated free list, filled when necessary with memory from malloc().
+
+ block_list is a singly-linked list of all PyFloatBlocks ever allocated,
+ linked via their next members. PyFloatBlocks are never returned to the
+ system before shutdown (PyFloat_Fini).
+
+ free_list is a singly-linked list of available PyFloatObjects, linked
+ via abuse of their ob_type members.
+*/
+
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
@@ -69,7 +83,7 @@ PyFloat_GetMin(void)
static PyTypeObject FloatInfoType;
PyDoc_STRVAR(floatinfo__doc__,
-"sys.floatinfo\n\
+"sys.float_info\n\
\n\
A structseq holding information about the float type. It contains low level\n\
information about the precision and internal representation. Please study\n\
@@ -96,7 +110,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
@@ -160,52 +174,58 @@ PyFloat_FromString(PyObject *v)
{
const char *s, *last, *end;
double x;
- char buffer[256]; /* for errors */
- char *s_buffer = NULL;
+ PyObject *s_buffer = NULL;
Py_ssize_t len;
PyObject *result = NULL;
if (PyUnicode_Check(v)) {
- s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
+ Py_ssize_t i, buflen = PyUnicode_GET_SIZE(v);
+ Py_UNICODE *bufptr;
+ s_buffer = PyUnicode_TransformDecimalToASCII(
+ PyUnicode_AS_UNICODE(v), buflen);
if (s_buffer == NULL)
- return PyErr_NoMemory();
- if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
- PyUnicode_GET_SIZE(v),
- s_buffer,
- NULL))
- goto error;
- s = s_buffer;
- len = strlen(s);
+ return NULL;
+ /* Replace non-ASCII whitespace with ' ' */
+ bufptr = PyUnicode_AS_UNICODE(s_buffer);
+ for (i = 0; i < buflen; i++) {
+ Py_UNICODE ch = bufptr[i];
+ if (ch > 127 && Py_UNICODE_ISSPACE(ch))
+ bufptr[i] = ' ';
+ }
+ s = _PyUnicode_AsStringAndSize(s_buffer, &len);
+ if (s == NULL) {
+ Py_DECREF(s_buffer);
+ return NULL;
+ }
+ last = s + len;
}
else if (PyObject_AsCharBuffer(v, &s, &len)) {
PyErr_SetString(PyExc_TypeError,
- "float() argument must be a string or a number");
+ "float() argument must be a string or a number");
return NULL;
}
last = s + len;
-
- while (Py_ISSPACE(*s))
+ /* strip space */
+ while (s < last && Py_ISSPACE(*s))
s++;
+ while (s < last - 1 && Py_ISSPACE(last[-1]))
+ last--;
/* We don't care about overflow or underflow. If the platform
* supports them, infinities and signed zeroes (on underflow) are
* fine. */
x = PyOS_string_to_double(s, (char **)&end, NULL);
- if (x == -1.0 && PyErr_Occurred())
- goto error;
- while (Py_ISSPACE(*end))
- end++;
- if (end == last)
- result = PyFloat_FromDouble(x);
- else {
- PyOS_snprintf(buffer, sizeof(buffer),
- "invalid literal for float(): %.200s", s);
- PyErr_SetString(PyExc_ValueError, buffer);
+ if (end != last) {
+ PyErr_Format(PyExc_ValueError,
+ "could not convert string to float: "
+ "%R", v);
result = NULL;
}
+ else if (x == -1.0 && PyErr_Occurred())
+ result = NULL;
+ else
+ result = PyFloat_FromDouble(x);
- error:
- if (s_buffer)
- PyMem_FREE(s_buffer);
+ Py_XDECREF(s_buffer);
return result;
}
@@ -290,32 +310,20 @@ convert_to_double(PyObject **v, double *dbl)
}
static PyObject *
-float_str_or_repr(PyFloatObject *v, int precision, char format_code)
+float_repr(PyFloatObject *v)
{
PyObject *result;
char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
- format_code, precision,
+ 'r', 0,
Py_DTSF_ADD_DOT_0,
NULL);
if (!buf)
- return PyErr_NoMemory();
+ return PyErr_NoMemory();
result = PyUnicode_FromString(buf);
PyMem_Free(buf);
return result;
}
-static PyObject *
-float_repr(PyFloatObject *v)
-{
- return float_str_or_repr(v, 0, 'r');
-}
-
-static PyObject *
-float_str(PyFloatObject *v)
-{
- return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');
-}
-
/* Comparison is pretty much a nightmare. When comparing float to float,
* we do it as straightforwardly (and long-windedly) as conceivable, so
* that, e.g., Python x == y delivers the same result as the platform
@@ -519,7 +527,7 @@ float_richcompare(PyObject *v, PyObject *w, int op)
return Py_NotImplemented;
}
-static long
+static Py_hash_t
float_hash(PyFloatObject *v)
{
return _Py_HashDouble(v->ob_fval);
@@ -567,13 +575,11 @@ float_div(PyObject *v, PyObject *w)
double a,b;
CONVERT_TO_DOUBLE(v, a);
CONVERT_TO_DOUBLE(w, b);
-#ifdef Py_NAN
if (b == 0.0) {
PyErr_SetString(PyExc_ZeroDivisionError,
- "float division");
+ "float division by zero");
return NULL;
}
-#endif
PyFPE_START_PROTECT("divide", return 0)
a = a / b;
PyFPE_END_PROTECT(a)
@@ -587,13 +593,11 @@ float_rem(PyObject *v, PyObject *w)
double mod;
CONVERT_TO_DOUBLE(v, vx);
CONVERT_TO_DOUBLE(w, wx);
-#ifdef Py_NAN
if (wx == 0.0) {
PyErr_SetString(PyExc_ZeroDivisionError,
"float modulo");
return NULL;
}
-#endif
PyFPE_START_PROTECT("modulo", return 0)
mod = fmod(vx, wx);
if (mod) {
@@ -605,11 +609,8 @@ float_rem(PyObject *v, PyObject *w)
else {
/* the remainder is zero, and in the presence of signed zeroes
fmod returns different results across platforms; ensure
- it has the same sign as the denominator; we'd like to do
- "mod = wx * 0.0", but that may get optimized away */
- mod *= mod; /* hide "mod = +0" from optimizer */
- if (wx < 0.0)
- mod = -mod;
+ it has the same sign as the denominator. */
+ mod = copysign(0.0, wx);
}
PyFPE_END_PROTECT(mod)
return PyFloat_FromDouble(mod);
@@ -645,11 +646,8 @@ float_divmod(PyObject *v, PyObject *w)
else {
/* the remainder is zero, and in the presence of signed zeroes
fmod returns different results across platforms; ensure
- it has the same sign as the denominator; we'd like to do
- "mod = wx * 0.0", but that may get optimized away */
- mod *= mod; /* hide "mod = +0" from optimizer */
- if (wx < 0.0)
- mod = -mod;
+ it has the same sign as the denominator. */
+ mod = copysign(0.0, wx);
}
/* snap quotient to nearest integral value */
if (div) {
@@ -659,8 +657,7 @@ float_divmod(PyObject *v, PyObject *w)
}
else {
/* div is zero - get the same sign as the true quotient */
- div *= div; /* hide "div = +0" from optimizers */
- floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
+ floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
}
PyFPE_END_PROTECT(floordiv)
return Py_BuildValue("(dd)", floordiv, mod);
@@ -681,10 +678,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 "
@@ -699,17 +701,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.
@@ -720,33 +758,41 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
*/
return PyComplex_Type.tp_as_number->nb_power(v, w, z);
}
- /* iw is an exact integer, albeit perhaps a very large one.
+ /* iw is an exact integer, albeit perhaps a very large
+ * one. Replace iv by its absolute value and remember
+ * to negate the pow result if iw is odd.
+ */
+ iv = -iv;
+ negate_result = DOUBLE_IS_ODD_INTEGER(iw);
+ }
+
+ if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
+ /* (-1) ** large_integer also ends up here. Here's an
+ * extract from the comments for the previous
+ * implementation explaining why this special case is
+ * necessary:
+ *
* -1 raised to an exact integer should never be exceptional.
* Alas, some libms (chiefly glibc as of early 2003) return
* NaN and set EDOM on pow(-1, large_int) if the int doesn't
* happen to be representable in a *C* integer. That's a
- * bug; we let that slide in math.pow() (which currently
- * reflects all platform accidents), but not for Python's **.
- */
- if (iv == -1.0 && Py_IS_FINITE(iw)) {
- /* Return 1 if iw is even, -1 if iw is odd; there's
- * no guarantee that any C integral type is big
- * enough to hold iw, so we have to check this
- * indirectly.
- */
- ix = floor(iw * 0.5) * 2.0;
- return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0);
- }
- /* Else iv != -1.0, and overflow or underflow are possible.
- * Unless we're to write pow() ourselves, we have to trust
- * the platform to do this correctly.
+ * bug.
*/
+ return PyFloat_FromDouble(negate_result ? -1.0 : 1.0);
}
+
+ /* Now iv and iw are finite, iw is nonzero, and iv is
+ * positive and not equal to 1.0. We finally allow
+ * the platform pow to step in and do the rest.
+ */
errno = 0;
PyFPE_START_PROTECT("pow", return NULL)
ix = pow(iv, iw);
PyFPE_END_PROTECT(ix)
Py_ADJUST_ERANGE1(ix);
+ if (negate_result)
+ ix = -ix;
+
if (errno != 0) {
/* We don't expect any errno value other than ERANGE, but
* the range of libm bugs appears unbounded.
@@ -758,6 +804,8 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
return PyFloat_FromDouble(ix);
}
+#undef DOUBLE_IS_ODD_INTEGER
+
static PyObject *
float_neg(PyFloatObject *v)
{
@@ -1113,7 +1161,7 @@ float_hex(PyObject *v)
CONVERT_TO_DOUBLE(v, x);
if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
- return float_str((PyFloatObject *)v);
+ return float_repr((PyFloatObject *)v);
if (x == 0.0) {
if (copysign(1.0, x) == -1.0)
@@ -1366,7 +1414,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
round_up = 1;
break;
}
- if (round_up == 1) {
+ if (round_up) {
x += 2*half_eps;
if (top_exp == DBL_MAX_EXP &&
x == ldexp((double)(2*half_eps), DBL_MANT_DIG))
@@ -1443,13 +1491,11 @@ float_as_integer_ratio(PyObject *v, PyObject *unused)
"Cannot pass infinity to float.as_integer_ratio.");
return NULL;
}
-#ifdef Py_NAN
if (Py_IS_NAN(self)) {
PyErr_SetString(PyExc_ValueError,
"Cannot pass NaN to float.as_integer_ratio.");
return NULL;
}
-#endif
PyFPE_START_PROTECT("as_integer_ratio", goto error);
float_part = frexp(self, &exponent); /* self == float_part * 2**exponent exactly */
@@ -1817,7 +1863,7 @@ PyTypeObject PyFloat_Type = {
0, /* tp_as_mapping */
(hashfunc)float_hash, /* tp_hash */
0, /* tp_call */
- (reprfunc)float_str, /* tp_str */
+ (reprfunc)float_repr, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 2cf2cdf..10fb8b3 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -31,17 +31,19 @@ frame_getlocals(PyFrameObject *f, void *closure)
return f->f_locals;
}
-static PyObject *
-frame_getlineno(PyFrameObject *f, void *closure)
+int
+PyFrame_GetLineNumber(PyFrameObject *f)
{
- int lineno;
-
if (f->f_trace)
- lineno = f->f_lineno;
+ return f->f_lineno;
else
- lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ return PyCode_Addr2Line(f->f_code, f->f_lasti);
+}
- return PyLong_FromLong(lineno);
+static PyObject *
+frame_getlineno(PyFrameObject *f, void *closure)
+{
+ return PyLong_FromLong(PyFrame_GetLineNumber(f));
}
/* Setter for f_lineno - you can set f_lineno from within a trace function in
@@ -345,16 +347,14 @@ frame_gettrace(PyFrameObject *f, void *closure)
static int
frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
{
- /* We rely on f_lineno being accurate when f_trace is set. */
+ PyObject* old_value;
- PyObject* old_value = f->f_trace;
+ /* We rely on f_lineno being accurate when f_trace is set. */
+ f->f_lineno = PyFrame_GetLineNumber(f);
+ old_value = f->f_trace;
Py_XINCREF(v);
f->f_trace = v;
-
- if (v != NULL)
- f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
-
Py_XDECREF(old_value);
return 0;
@@ -391,7 +391,7 @@ static PyGetSetDef frame_getsetlist[] = {
the local variables in f_localsplus are NULL.
2. We also maintain a separate free list of stack frames (just like
- integers are allocated in a special way -- see intobject.c). When
+ floats are allocated in a special way -- see floatobject.c). When
a stack frame is on the free list, only the following members have
a meaning:
ob_type == &Frametype
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index c2ad964..45f9f57 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -3,7 +3,6 @@
#include "Python.h"
#include "code.h"
-#include "eval.h"
#include "structmember.h"
PyObject *
@@ -628,7 +627,7 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw)
}
result = PyEval_EvalCodeEx(
- (PyCodeObject *)PyFunction_GET_CODE(func),
+ PyFunction_GET_CODE(func),
PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
&PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
k, nk, d, nd,
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 34ee7dc..3fa1b4e 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -2,8 +2,6 @@
#include "Python.h"
#include "frameobject.h"
-#include "genobject.h"
-#include "ceval.h"
#include "structmember.h"
#include "opcode.h"
diff --git a/Objects/iterobject.c b/Objects/iterobject.c
index b534b4a..91a93f5 100644
--- a/Objects/iterobject.c
+++ b/Objects/iterobject.c
@@ -177,9 +177,7 @@ calliter_iternext(calliterobject *it)
Py_DECREF(args);
if (result != NULL) {
int ok;
- ok = PyObject_RichCompareBool(result,
- it->it_sentinel,
- Py_EQ);
+ ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
if (ok == 0)
return result; /* Common case, fast path */
Py_DECREF(result);
diff --git a/Objects/listobject.c b/Objects/listobject.c
index b3bb21d..73624f0 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -940,6 +940,71 @@ reverse_slice(PyObject **lo, PyObject **hi)
* pieces to this algorithm; read listsort.txt for overviews and details.
*/
+/* A sortslice contains a pointer to an array of keys and a pointer to
+ * an array of corresponding values. In other words, keys[i]
+ * corresponds with values[i]. If values == NULL, then the keys are
+ * also the values.
+ *
+ * Several convenience routines are provided here, so that keys and
+ * values are always moved in sync.
+ */
+
+typedef struct {
+ PyObject **keys;
+ PyObject **values;
+} sortslice;
+
+Py_LOCAL_INLINE(void)
+sortslice_copy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j)
+{
+ s1->keys[i] = s2->keys[j];
+ if (s1->values != NULL)
+ s1->values[i] = s2->values[j];
+}
+
+Py_LOCAL_INLINE(void)
+sortslice_copy_incr(sortslice *dst, sortslice *src)
+{
+ *dst->keys++ = *src->keys++;
+ if (dst->values != NULL)
+ *dst->values++ = *src->values++;
+}
+
+Py_LOCAL_INLINE(void)
+sortslice_copy_decr(sortslice *dst, sortslice *src)
+{
+ *dst->keys-- = *src->keys--;
+ if (dst->values != NULL)
+ *dst->values-- = *src->values--;
+}
+
+
+Py_LOCAL_INLINE(void)
+sortslice_memcpy(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j,
+ Py_ssize_t n)
+{
+ memcpy(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n);
+ if (s1->values != NULL)
+ memcpy(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n);
+}
+
+Py_LOCAL_INLINE(void)
+sortslice_memmove(sortslice *s1, Py_ssize_t i, sortslice *s2, Py_ssize_t j,
+ Py_ssize_t n)
+{
+ memmove(&s1->keys[i], &s2->keys[j], sizeof(PyObject *) * n);
+ if (s1->values != NULL)
+ memmove(&s1->values[i], &s2->values[j], sizeof(PyObject *) * n);
+}
+
+Py_LOCAL_INLINE(void)
+sortslice_advance(sortslice *slice, Py_ssize_t n)
+{
+ slice->keys += n;
+ if (slice->values != NULL)
+ slice->values += n;
+}
+
/* Comparison function: PyObject_RichCompareBool with Py_LT.
* Returns -1 on error, 1 if x < y, 0 if x >= y.
*/
@@ -965,19 +1030,19 @@ reverse_slice(PyObject **lo, PyObject **hi)
the input (nothing is lost or duplicated).
*/
static int
-binarysort(PyObject **lo, PyObject **hi, PyObject **start)
+binarysort(sortslice lo, PyObject **hi, PyObject **start)
{
register Py_ssize_t k;
register PyObject **l, **p, **r;
register PyObject *pivot;
- assert(lo <= start && start <= hi);
+ assert(lo.keys <= start && start <= hi);
/* assert [lo, start) is sorted */
- if (lo == start)
+ if (lo.keys == start)
++start;
for (; start < hi; ++start) {
/* set l to where *start belongs */
- l = lo;
+ l = lo.keys;
r = start;
pivot = *r;
/* Invariants:
@@ -1004,6 +1069,15 @@ binarysort(PyObject **lo, PyObject **hi, PyObject **start)
for (p = start; p > l; --p)
*p = *(p-1);
*l = pivot;
+ if (lo.values != NULL) {
+ Py_ssize_t offset = lo.values - lo.keys;
+ p = start + offset;
+ pivot = *p;
+ l += offset;
+ for (p = start + offset; p > l; --p)
+ *p = *(p-1);
+ *l = pivot;
+ }
}
return 0;
@@ -1272,7 +1346,7 @@ fail:
* a convenient way to pass state around among the helper functions.
*/
struct s_slice {
- PyObject **base;
+ sortslice base;
Py_ssize_t len;
};
@@ -1286,7 +1360,7 @@ typedef struct s_MergeState {
/* 'a' is temp storage to help with merges. It contains room for
* alloced entries.
*/
- PyObject **a; /* may point to temparray below */
+ sortslice a; /* may point to temparray below */
Py_ssize_t alloced;
/* A stack of n pending runs yet to be merged. Run #i starts at
@@ -1307,11 +1381,29 @@ typedef struct s_MergeState {
/* Conceptually a MergeState's constructor. */
static void
-merge_init(MergeState *ms)
+merge_init(MergeState *ms, Py_ssize_t list_size, int has_keyfunc)
{
assert(ms != NULL);
- ms->a = ms->temparray;
- ms->alloced = MERGESTATE_TEMP_SIZE;
+ if (has_keyfunc) {
+ /* The temporary space for merging will need at most half the list
+ * size rounded up. Use the minimum possible space so we can use the
+ * rest of temparray for other things. In particular, if there is
+ * enough extra space, listsort() will use it to store the keys.
+ */
+ ms->alloced = (list_size + 1) / 2;
+
+ /* ms->alloced describes how many keys will be stored at
+ ms->temparray, but we also need to store the values. Hence,
+ ms->alloced is capped at half of MERGESTATE_TEMP_SIZE. */
+ if (MERGESTATE_TEMP_SIZE / 2 < ms->alloced)
+ ms->alloced = MERGESTATE_TEMP_SIZE / 2;
+ ms->a.values = &ms->temparray[ms->alloced];
+ }
+ else {
+ ms->alloced = MERGESTATE_TEMP_SIZE;
+ ms->a.values = NULL;
+ }
+ ms->a.keys = ms->temparray;
ms->n = 0;
ms->min_gallop = MIN_GALLOP;
}
@@ -1324,10 +1416,8 @@ static void
merge_freemem(MergeState *ms)
{
assert(ms != NULL);
- if (ms->a != ms->temparray)
- PyMem_Free(ms->a);
- ms->a = ms->temparray;
- ms->alloced = MERGESTATE_TEMP_SIZE;
+ if (ms->a.keys != ms->temparray)
+ PyMem_Free(ms->a.keys);
}
/* Ensure enough temp memory for 'need' array slots is available.
@@ -1336,52 +1426,60 @@ merge_freemem(MergeState *ms)
static int
merge_getmem(MergeState *ms, Py_ssize_t need)
{
+ int multiplier;
+
assert(ms != NULL);
if (need <= ms->alloced)
return 0;
+
+ multiplier = ms->a.values != NULL ? 2 : 1;
+
/* Don't realloc! That can cost cycles to copy the old data, but
* we don't care what's in the block.
*/
merge_freemem(ms);
- if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+ if ((size_t)need > PY_SSIZE_T_MAX / sizeof(PyObject*) / multiplier) {
PyErr_NoMemory();
return -1;
}
- ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
- if (ms->a) {
+ ms->a.keys = (PyObject**)PyMem_Malloc(multiplier * need
+ * sizeof(PyObject *));
+ if (ms->a.keys != NULL) {
ms->alloced = need;
+ if (ms->a.values != NULL)
+ ms->a.values = &ms->a.keys[need];
return 0;
}
PyErr_NoMemory();
- merge_freemem(ms); /* reset to sane state */
return -1;
}
#define MERGE_GETMEM(MS, NEED) ((NEED) <= (MS)->alloced ? 0 : \
merge_getmem(MS, NEED))
-/* Merge the na elements starting at pa with the nb elements starting at pb
- * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
- * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
- * merge, and should have na <= nb. See listsort.txt for more info.
- * Return 0 if successful, -1 if error.
+/* Merge the na elements starting at ssa with the nb elements starting at
+ * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0.
+ * Must also have that ssa.keys[na-1] belongs at the end of the merge, and
+ * should have na <= nb. See listsort.txt for more info. Return 0 if
+ * successful, -1 if error.
*/
static Py_ssize_t
-merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
- PyObject **pb, Py_ssize_t nb)
+merge_lo(MergeState *ms, sortslice ssa, Py_ssize_t na,
+ sortslice ssb, Py_ssize_t nb)
{
Py_ssize_t k;
- PyObject **dest;
+ sortslice dest;
int result = -1; /* guilty until proved innocent */
Py_ssize_t min_gallop;
- assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+ assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0);
+ assert(ssa.keys + na == ssb.keys);
if (MERGE_GETMEM(ms, na) < 0)
return -1;
- memcpy(ms->a, pa, na * sizeof(PyObject*));
- dest = pa;
- pa = ms->a;
+ sortslice_memcpy(&ms->a, 0, &ssa, 0, na);
+ dest = ssa;
+ ssa = ms->a;
- *dest++ = *pb++;
+ sortslice_copy_incr(&dest, &ssb);
--nb;
if (nb == 0)
goto Succeed;
@@ -1398,11 +1496,11 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
*/
for (;;) {
assert(na > 1 && nb > 0);
- k = ISLT(*pb, *pa);
+ k = ISLT(ssb.keys[0], ssa.keys[0]);
if (k) {
if (k < 0)
goto Fail;
- *dest++ = *pb++;
+ sortslice_copy_incr(&dest, &ssb);
++bcount;
acount = 0;
--nb;
@@ -1412,7 +1510,7 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
break;
}
else {
- *dest++ = *pa++;
+ sortslice_copy_incr(&dest, &ssa);
++acount;
bcount = 0;
--na;
@@ -1433,14 +1531,14 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
assert(na > 1 && nb > 0);
min_gallop -= min_gallop > 1;
ms->min_gallop = min_gallop;
- k = gallop_right(*pb, pa, na, 0);
+ k = gallop_right(ssb.keys[0], ssa.keys, na, 0);
acount = k;
if (k) {
if (k < 0)
goto Fail;
- memcpy(dest, pa, k * sizeof(PyObject *));
- dest += k;
- pa += k;
+ sortslice_memcpy(&dest, 0, &ssa, 0, k);
+ sortslice_advance(&dest, k);
+ sortslice_advance(&ssa, k);
na -= k;
if (na == 1)
goto CopyB;
@@ -1451,24 +1549,24 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na,
if (na == 0)
goto Succeed;
}
- *dest++ = *pb++;
+ sortslice_copy_incr(&dest, &ssb);
--nb;
if (nb == 0)
goto Succeed;
- k = gallop_left(*pa, pb, nb, 0);
+ k = gallop_left(ssa.keys[0], ssb.keys, nb, 0);
bcount = k;
if (k) {
if (k < 0)
goto Fail;
- memmove(dest, pb, k * sizeof(PyObject *));
- dest += k;
- pb += k;
+ sortslice_memmove(&dest, 0, &ssb, 0, k);
+ sortslice_advance(&dest, k);
+ sortslice_advance(&ssb, k);
nb -= k;
if (nb == 0)
goto Succeed;
}
- *dest++ = *pa++;
+ sortslice_copy_incr(&dest, &ssa);
--na;
if (na == 1)
goto CopyB;
@@ -1480,43 +1578,46 @@ Succeed:
result = 0;
Fail:
if (na)
- memcpy(dest, pa, na * sizeof(PyObject*));
+ sortslice_memcpy(&dest, 0, &ssa, 0, na);
return result;
CopyB:
assert(na == 1 && nb > 0);
- /* The last element of pa belongs at the end of the merge. */
- memmove(dest, pb, nb * sizeof(PyObject *));
- dest[nb] = *pa;
+ /* The last element of ssa belongs at the end of the merge. */
+ sortslice_memmove(&dest, 0, &ssb, 0, nb);
+ sortslice_copy(&dest, nb, &ssa, 0);
return 0;
}
-/* Merge the na elements starting at pa with the nb elements starting at pb
- * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
- * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
- * merge, and should have na >= nb. See listsort.txt for more info.
- * Return 0 if successful, -1 if error.
+/* Merge the na elements starting at pa with the nb elements starting at
+ * ssb.keys = ssa.keys + na in a stable way, in-place. na and nb must be > 0.
+ * Must also have that ssa.keys[na-1] belongs at the end of the merge, and
+ * should have na >= nb. See listsort.txt for more info. Return 0 if
+ * successful, -1 if error.
*/
static Py_ssize_t
-merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t nb)
+merge_hi(MergeState *ms, sortslice ssa, Py_ssize_t na,
+ sortslice ssb, Py_ssize_t nb)
{
Py_ssize_t k;
- PyObject **dest;
+ sortslice dest, basea, baseb;
int result = -1; /* guilty until proved innocent */
- PyObject **basea;
- PyObject **baseb;
Py_ssize_t min_gallop;
- assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb);
+ assert(ms && ssa.keys && ssb.keys && na > 0 && nb > 0);
+ assert(ssa.keys + na == ssb.keys);
if (MERGE_GETMEM(ms, nb) < 0)
return -1;
- dest = pb + nb - 1;
- memcpy(ms->a, pb, nb * sizeof(PyObject*));
- basea = pa;
+ dest = ssb;
+ sortslice_advance(&dest, nb-1);
+ sortslice_memcpy(&ms->a, 0, &ssb, 0, nb);
+ basea = ssa;
baseb = ms->a;
- pb = ms->a + nb - 1;
- pa += na - 1;
+ ssb.keys = ms->a.keys + nb - 1;
+ if (ssb.values != NULL)
+ ssb.values = ms->a.values + nb - 1;
+ sortslice_advance(&ssa, na - 1);
- *dest-- = *pa--;
+ sortslice_copy_decr(&dest, &ssa);
--na;
if (na == 0)
goto Succeed;
@@ -1533,11 +1634,11 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t
*/
for (;;) {
assert(na > 0 && nb > 1);
- k = ISLT(*pb, *pa);
+ k = ISLT(ssb.keys[0], ssa.keys[0]);
if (k) {
if (k < 0)
goto Fail;
- *dest-- = *pa--;
+ sortslice_copy_decr(&dest, &ssa);
++acount;
bcount = 0;
--na;
@@ -1547,7 +1648,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t
break;
}
else {
- *dest-- = *pb--;
+ sortslice_copy_decr(&dest, &ssb);
++bcount;
acount = 0;
--nb;
@@ -1568,33 +1669,33 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t
assert(na > 0 && nb > 1);
min_gallop -= min_gallop > 1;
ms->min_gallop = min_gallop;
- k = gallop_right(*pb, basea, na, na-1);
+ k = gallop_right(ssb.keys[0], basea.keys, na, na-1);
if (k < 0)
goto Fail;
k = na - k;
acount = k;
if (k) {
- dest -= k;
- pa -= k;
- memmove(dest+1, pa+1, k * sizeof(PyObject *));
+ sortslice_advance(&dest, -k);
+ sortslice_advance(&ssa, -k);
+ sortslice_memmove(&dest, 1, &ssa, 1, k);
na -= k;
if (na == 0)
goto Succeed;
}
- *dest-- = *pb--;
+ sortslice_copy_decr(&dest, &ssb);
--nb;
if (nb == 1)
goto CopyA;
- k = gallop_left(*pa, baseb, nb, nb-1);
+ k = gallop_left(ssa.keys[0], baseb.keys, nb, nb-1);
if (k < 0)
goto Fail;
k = nb - k;
bcount = k;
if (k) {
- dest -= k;
- pb -= k;
- memcpy(dest+1, pb+1, k * sizeof(PyObject *));
+ sortslice_advance(&dest, -k);
+ sortslice_advance(&ssb, -k);
+ sortslice_memcpy(&dest, 1, &ssb, 1, k);
nb -= k;
if (nb == 1)
goto CopyA;
@@ -1605,7 +1706,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t
if (nb == 0)
goto Succeed;
}
- *dest-- = *pa--;
+ sortslice_copy_decr(&dest, &ssa);
--na;
if (na == 0)
goto Succeed;
@@ -1617,15 +1718,15 @@ Succeed:
result = 0;
Fail:
if (nb)
- memcpy(dest-(nb-1), baseb, nb * sizeof(PyObject*));
+ sortslice_memcpy(&dest, -(nb-1), &baseb, 0, nb);
return result;
CopyA:
assert(nb == 1 && na > 0);
- /* The first element of pb belongs at the front of the merge. */
- dest -= na;
- pa -= na;
- memmove(dest+1, pa+1, na * sizeof(PyObject *));
- *dest = *pb;
+ /* The first element of ssb belongs at the front of the merge. */
+ sortslice_memmove(&dest, 1-na, &ssa, 1-na, na);
+ sortslice_advance(&dest, -na);
+ sortslice_advance(&ssa, -na);
+ sortslice_copy(&dest, 0, &ssb, 0);
return 0;
}
@@ -1635,7 +1736,7 @@ CopyA:
static Py_ssize_t
merge_at(MergeState *ms, Py_ssize_t i)
{
- PyObject **pa, **pb;
+ sortslice ssa, ssb;
Py_ssize_t na, nb;
Py_ssize_t k;
@@ -1644,12 +1745,12 @@ merge_at(MergeState *ms, Py_ssize_t i)
assert(i >= 0);
assert(i == ms->n - 2 || i == ms->n - 3);
- pa = ms->pending[i].base;
+ ssa = ms->pending[i].base;
na = ms->pending[i].len;
- pb = ms->pending[i+1].base;
+ ssb = ms->pending[i+1].base;
nb = ms->pending[i+1].len;
assert(na > 0 && nb > 0);
- assert(pa + na == pb);
+ assert(ssa.keys + na == ssb.keys);
/* Record the length of the combined runs; if i is the 3rd-last
* run now, also slide over the last run (which isn't involved
@@ -1663,10 +1764,10 @@ merge_at(MergeState *ms, Py_ssize_t i)
/* Where does b start in a? Elements in a before that can be
* ignored (already in place).
*/
- k = gallop_right(*pb, pa, na, 0);
+ k = gallop_right(*ssb.keys, ssa.keys, na, 0);
if (k < 0)
return -1;
- pa += k;
+ sortslice_advance(&ssa, k);
na -= k;
if (na == 0)
return 0;
@@ -1674,7 +1775,7 @@ merge_at(MergeState *ms, Py_ssize_t i)
/* Where does a end in b? Elements in b after that can be
* ignored (already in place).
*/
- nb = gallop_left(pa[na-1], pb, nb, nb-1);
+ nb = gallop_left(ssa.keys[na-1], ssb.keys, nb, nb-1);
if (nb <= 0)
return nb;
@@ -1682,9 +1783,9 @@ merge_at(MergeState *ms, Py_ssize_t i)
* min(na, nb) elements.
*/
if (na <= nb)
- return merge_lo(ms, pa, na, pb, nb);
+ return merge_lo(ms, ssa, na, ssb, nb);
else
- return merge_hi(ms, pa, na, pb, nb);
+ return merge_hi(ms, ssa, na, ssb, nb);
}
/* Examine the stack of runs waiting to be merged, merging adjacent runs
@@ -1765,103 +1866,12 @@ merge_compute_minrun(Py_ssize_t n)
return n + r;
}
-/* Special wrapper to support stable sorting using the decorate-sort-undecorate
- pattern. Holds a key which is used for comparisons and the original record
- which is returned during the undecorate phase. By exposing only the key
- during comparisons, the underlying sort stability characteristics are left
- unchanged. Also, the comparison function will only see the key instead of
- a full record. */
-
-typedef struct {
- PyObject_HEAD
- PyObject *key;
- PyObject *value;
-} sortwrapperobject;
-
-PyDoc_STRVAR(sortwrapper_doc, "Object wrapper with a custom sort key.");
-static PyObject *
-sortwrapper_richcompare(sortwrapperobject *, sortwrapperobject *, int);
static void
-sortwrapper_dealloc(sortwrapperobject *);
-
-PyTypeObject PySortWrapper_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "sortwrapper", /* tp_name */
- sizeof(sortwrapperobject), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)sortwrapper_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- sortwrapper_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- (richcmpfunc)sortwrapper_richcompare, /* tp_richcompare */
-};
-
-
-static PyObject *
-sortwrapper_richcompare(sortwrapperobject *a, sortwrapperobject *b, int op)
-{
- if (!PyObject_TypeCheck(b, &PySortWrapper_Type)) {
- PyErr_SetString(PyExc_TypeError,
- "expected a sortwrapperobject");
- return NULL;
- }
- return PyObject_RichCompare(a->key, b->key, op);
-}
-
-static void
-sortwrapper_dealloc(sortwrapperobject *so)
+reverse_sortslice(sortslice *s, Py_ssize_t n)
{
- Py_XDECREF(so->key);
- Py_XDECREF(so->value);
- PyObject_Del(so);
-}
-
-/* Returns a new reference to a sortwrapper.
- Consumes the references to the two underlying objects. */
-
-static PyObject *
-build_sortwrapper(PyObject *key, PyObject *value)
-{
- sortwrapperobject *so;
-
- so = PyObject_New(sortwrapperobject, &PySortWrapper_Type);
- if (so == NULL)
- return NULL;
- so->key = key;
- so->value = value;
- return (PyObject *)so;
-}
-
-/* Returns a new reference to the value underlying the wrapper. */
-static PyObject *
-sortwrapper_getvalue(PyObject *so)
-{
- PyObject *value;
-
- if (!PyObject_TypeCheck(so, &PySortWrapper_Type)) {
- PyErr_SetString(PyExc_TypeError,
- "expected a sortwrapperobject");
- return NULL;
- }
- value = ((sortwrapperobject *)so)->value;
- Py_INCREF(value);
- return value;
+ reverse_slice(s->keys, &s->keys[n]);
+ if (s->values != NULL)
+ reverse_slice(s->values, &s->values[n]);
}
/* An adaptive, stable, natural mergesort. See listsort.txt.
@@ -1873,9 +1883,9 @@ static PyObject *
listsort(PyListObject *self, PyObject *args, PyObject *kwds)
{
MergeState ms;
- PyObject **lo, **hi;
Py_ssize_t nremaining;
Py_ssize_t minrun;
+ sortslice lo;
Py_ssize_t saved_ob_size, saved_allocated;
PyObject **saved_ob_item;
PyObject **final_ob_item;
@@ -1883,8 +1893,8 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds)
int reverse = 0;
PyObject *keyfunc = NULL;
Py_ssize_t i;
- PyObject *key, *value, *kvpair;
static char *kwlist[] = {"key", "reverse", 0};
+ PyObject **keys;
assert(self != NULL);
assert (PyList_Check(self));
@@ -1913,59 +1923,70 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds)
self->ob_item = NULL;
self->allocated = -1; /* any operation will reset it to >= 0 */
- if (keyfunc != NULL) {
- for (i=0 ; i < saved_ob_size ; i++) {
- value = saved_ob_item[i];
- key = PyObject_CallFunctionObjArgs(keyfunc, value,
- NULL);
- if (key == NULL) {
- for (i=i-1 ; i>=0 ; i--) {
- kvpair = saved_ob_item[i];
- value = sortwrapper_getvalue(kvpair);
- saved_ob_item[i] = value;
- Py_DECREF(kvpair);
- }
- goto dsu_fail;
+ if (keyfunc == NULL) {
+ keys = NULL;
+ lo.keys = saved_ob_item;
+ lo.values = NULL;
+ }
+ else {
+ if (saved_ob_size < MERGESTATE_TEMP_SIZE/2)
+ /* Leverage stack space we allocated but won't otherwise use */
+ keys = &ms.temparray[saved_ob_size+1];
+ else {
+ keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size);
+ if (keys == NULL)
+ return NULL;
+ }
+
+ for (i = 0; i < saved_ob_size ; i++) {
+ keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i],
+ NULL);
+ if (keys[i] == NULL) {
+ for (i=i-1 ; i>=0 ; i--)
+ Py_DECREF(keys[i]);
+ if (keys != &ms.temparray[saved_ob_size+1])
+ PyMem_FREE(keys);
+ goto keyfunc_fail;
}
- kvpair = build_sortwrapper(key, value);
- if (kvpair == NULL)
- goto dsu_fail;
- saved_ob_item[i] = kvpair;
}
- }
- /* Reverse sort stability achieved by initially reversing the list,
- applying a stable forward sort, then reversing the final result. */
- if (reverse && saved_ob_size > 1)
- reverse_slice(saved_ob_item, saved_ob_item + saved_ob_size);
+ lo.keys = keys;
+ lo.values = saved_ob_item;
+ }
- merge_init(&ms);
+ merge_init(&ms, saved_ob_size, keys != NULL);
nremaining = saved_ob_size;
if (nremaining < 2)
goto succeed;
+ /* Reverse sort stability achieved by initially reversing the list,
+ applying a stable forward sort, then reversing the final result. */
+ if (reverse) {
+ if (keys != NULL)
+ reverse_slice(&keys[0], &keys[saved_ob_size]);
+ reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]);
+ }
+
/* March over the array once, left to right, finding natural runs,
* and extending short natural runs to minrun elements.
*/
- lo = saved_ob_item;
- hi = lo + nremaining;
minrun = merge_compute_minrun(nremaining);
do {
int descending;
Py_ssize_t n;
/* Identify next run. */
- n = count_run(lo, hi, &descending);
+ n = count_run(lo.keys, lo.keys + nremaining, &descending);
if (n < 0)
goto fail;
if (descending)
- reverse_slice(lo, lo + n);
+ reverse_sortslice(&lo, n);
/* If short, extend to min(minrun, nremaining). */
if (n < minrun) {
const Py_ssize_t force = nremaining <= minrun ?
nremaining : minrun;
- if (binarysort(lo, lo + force, lo + n) < 0)
+ if (binarysort(lo, lo.keys + force, lo.keys + n) < 0)
goto fail;
n = force;
}
@@ -1977,27 +1998,27 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds)
if (merge_collapse(&ms) < 0)
goto fail;
/* Advance to find next run. */
- lo += n;
+ sortslice_advance(&lo, n);
nremaining -= n;
} while (nremaining);
- assert(lo == hi);
if (merge_force_collapse(&ms) < 0)
goto fail;
assert(ms.n == 1);
- assert(ms.pending[0].base == saved_ob_item);
+ assert(keys == NULL
+ ? ms.pending[0].base.keys == saved_ob_item
+ : ms.pending[0].base.keys == &keys[0]);
assert(ms.pending[0].len == saved_ob_size);
+ lo = ms.pending[0].base;
succeed:
result = Py_None;
fail:
- if (keyfunc != NULL) {
- for (i=0 ; i < saved_ob_size ; i++) {
- kvpair = saved_ob_item[i];
- value = sortwrapper_getvalue(kvpair);
- saved_ob_item[i] = value;
- Py_DECREF(kvpair);
- }
+ if (keys != NULL) {
+ for (i = 0; i < saved_ob_size; i++)
+ Py_DECREF(keys[i]);
+ if (keys != &ms.temparray[saved_ob_size+1])
+ PyMem_FREE(keys);
}
if (self->allocated != -1 && result != NULL) {
@@ -2013,7 +2034,7 @@ fail:
merge_freemem(&ms);
-dsu_fail:
+keyfunc_fail:
final_ob_item = self->ob_item;
i = Py_SIZE(self);
Py_SIZE(self) = saved_ob_size;
@@ -2098,7 +2119,8 @@ static PyObject *
listindex(PyListObject *self, PyObject *args)
{
Py_ssize_t i, start=0, stop=Py_SIZE(self);
- PyObject *v;
+ PyObject *v, *format_tuple, *err_string;
+ static PyObject *err_format = NULL;
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
_PyEval_SliceIndex, &start,
@@ -2121,7 +2143,20 @@ listindex(PyListObject *self, PyObject *args)
else if (cmp < 0)
return NULL;
}
- PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list");
+ if (err_format == NULL) {
+ err_format = PyUnicode_FromString("%r is not in list");
+ if (err_format == NULL)
+ return NULL;
+ }
+ format_tuple = PyTuple_Pack(1, v);
+ if (format_tuple == NULL)
+ return NULL;
+ err_string = PyUnicode_Format(err_format, format_tuple);
+ Py_DECREF(format_tuple);
+ if (err_string == NULL)
+ return NULL;
+ PyErr_SetObject(PyExc_ValueError, err_string);
+ Py_DECREF(err_string);
return NULL;
}
@@ -2364,7 +2399,7 @@ list_subscript(PyListObject* self, PyObject* item)
PyObject* it;
PyObject **src, **dest;
- if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+ if (PySlice_GetIndicesEx(item, Py_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
}
@@ -2413,7 +2448,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
+ if (PySlice_GetIndicesEx(item, Py_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return -1;
}
@@ -2582,7 +2617,7 @@ PyTypeObject PyList_Type = {
0, /* tp_as_number */
&list_as_sequence, /* tp_as_sequence */
&list_as_mapping, /* tp_as_mapping */
- (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
@@ -2848,4 +2883,3 @@ listreviter_len(listreviterobject *it)
len = 0;
return PyLong_FromSsize_t(len);
}
-
diff --git a/Objects/lnotab_notes.txt b/Objects/lnotab_notes.txt
new file mode 100644
index 0000000..d247edd
--- /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 6f998ce..552f8f0 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -4,7 +4,6 @@
#include "Python.h"
#include "longintrepr.h"
-#include "structseq.h"
#include <float.h>
#include <ctype.h>
@@ -95,14 +94,10 @@ maybe_small_long(PyLongObject *v)
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))
-#define SIGCHECK(PyTryBlock) \
- if (--_Py_Ticker < 0) { \
- _Py_Ticker = _Py_CheckInterval; \
- if (PyErr_CheckSignals()) PyTryBlock \
- }
-
-/* forward declaration */
-static int bits_in_digit(digit d);
+#define SIGCHECK(PyTryBlock) \
+ do { \
+ if (PyErr_CheckSignals()) PyTryBlock \
+ } while(0)
/* Normalize (remove leading zeros from) a long int object.
Doesn't attempt to free the storage--in most cases, due to the nature
@@ -284,12 +279,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) {
@@ -349,9 +344,10 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
if (!PyLong_Check(vv)) {
PyNumberMethods *nb;
- if ((nb = vv->ob_type->tp_as_number) == NULL ||
- nb->nb_int == NULL) {
- PyErr_SetString(PyExc_TypeError, "an integer is required");
+ nb = vv->ob_type->tp_as_number;
+ if (nb == NULL || nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
return -1;
}
vv = (*nb->nb_int) (vv);
@@ -389,14 +385,14 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
}
while (--i >= 0) {
prev = x;
- x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
- *overflow = Py_SIZE(v) > 0 ? 1 : -1;
+ *overflow = sign;
goto exit;
}
}
- /* Haven't lost any bits, but casting to long requires extra care
- * (see comment above).
+ /* Haven't lost any bits, but casting to long requires extra
+ * care (see comment above).
*/
if (x <= (unsigned long)LONG_MAX) {
res = (long)x * sign;
@@ -405,11 +401,11 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
res = LONG_MIN;
}
else {
- *overflow = Py_SIZE(v) > 0 ? 1 : -1;
+ *overflow = sign;
/* res is already set to -1 */
}
}
- exit:
+ exit:
if (do_decref) {
Py_DECREF(vv);
}
@@ -464,7 +460,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;
}
@@ -479,7 +475,7 @@ PyLong_AsSsize_t(PyObject *vv) {
}
/* else overflow */
- overflow:
+ overflow:
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C ssize_t");
return -1;
@@ -509,7 +505,7 @@ PyLong_AsUnsignedLong(PyObject *vv)
x = 0;
if (i < 0) {
PyErr_SetString(PyExc_OverflowError,
- "can't convert negative value to unsigned int");
+ "can't convert negative value to unsigned int");
return (unsigned long) -1;
}
switch (i) {
@@ -518,10 +514,11 @@ PyLong_AsUnsignedLong(PyObject *vv)
}
while (--i >= 0) {
prev = x;
- x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
PyErr_SetString(PyExc_OverflowError,
- "python int too large to convert to C unsigned long");
+ "python int too large to convert "
+ "to C unsigned long");
return (unsigned long) -1;
}
}
@@ -561,7 +558,7 @@ PyLong_AsSize_t(PyObject *vv)
}
while (--i >= 0) {
prev = x;
- x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
if ((x >> PyLong_SHIFT) != prev) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to C size_t");
@@ -599,7 +596,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;
}
@@ -676,7 +673,7 @@ _PyLong_NumBits(PyObject *vv)
}
return result;
-Overflow:
+ Overflow:
PyErr_SetString(PyExc_OverflowError, "int has too many bits "
"to express in a platform size_t");
return (size_t)-1;
@@ -686,7 +683,7 @@ PyObject *
_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
int little_endian, int is_signed)
{
- const unsigned char* pstartbyte;/* LSB of bytes */
+ const unsigned char* pstartbyte; /* LSB of bytes */
int incr; /* direction to move pstartbyte */
const unsigned char* pendbyte; /* MSB of bytes */
size_t numsignificantbytes; /* number of bytes that matter */
@@ -774,8 +771,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n,
if (accumbits >= PyLong_SHIFT) {
/* There's enough to fill a Python digit. */
assert(idigit < ndigits);
- v->ob_digit[idigit] = (digit)(accum &
- PyLong_MASK);
+ v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);
++idigit;
accum >>= PyLong_SHIFT;
accumbits -= PyLong_SHIFT;
@@ -800,9 +796,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 */
@@ -815,7 +811,7 @@ _PyLong_AsByteArray(PyLongObject* v,
ndigits = -(Py_SIZE(v));
if (!is_signed) {
PyErr_SetString(PyExc_OverflowError,
- "can't convert negative int to unsigned");
+ "can't convert negative int to unsigned");
return -1;
}
do_twos_comp = 1;
@@ -861,8 +857,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++;
@@ -922,230 +917,12 @@ _PyLong_AsByteArray(PyLongObject* v,
return 0;
-Overflow:
+ Overflow:
PyErr_SetString(PyExc_OverflowError, "int 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. Rounds to the nearest double,
- using the round-half-to-even rule in the case of a tie. */
-
-double
-PyLong_AsDouble(PyObject *vv)
-{
- PyLongObject *v = (PyLongObject *)vv;
- Py_ssize_t rnd_digit, rnd_bit, m, n;
- digit lsb, *d;
- int round_up = 0;
- double x;
-
- if (vv == NULL || !PyLong_Check(vv)) {
- PyErr_BadInternalCall();
- return -1.0;
- }
-
- /* Notes on the method: for simplicity, assume v is positive and >=
- 2**DBL_MANT_DIG. (For negative v we just ignore the sign until the
- end; for small v no rounding is necessary.) Write n for the number
- of bits in v, so that 2**(n-1) <= v < 2**n, and n > DBL_MANT_DIG.
-
- Some terminology: the *rounding bit* of v is the 1st bit of v that
- will be rounded away (bit n - DBL_MANT_DIG - 1); the *parity bit*
- is the bit immediately above. The round-half-to-even rule says
- that we round up if the rounding bit is set, unless v is exactly
- halfway between two floats and the parity bit is zero.
-
- Write d[0] ... d[m] for the digits of v, least to most significant.
- Let rnd_bit be the index of the rounding bit, and rnd_digit the
- index of the PyLong digit containing the rounding bit. Then the
- bits of the digit d[rnd_digit] look something like:
-
- rounding bit
- |
- v
- msb -> sssssrttttttttt <- lsb
- ^
- |
- parity bit
-
- where 's' represents a 'significant bit' that will be included in
- the mantissa of the result, 'r' is the rounding bit, and 't'
- represents a 'trailing bit' following the rounding bit. Note that
- if the rounding bit is at the top of d[rnd_digit] then the parity
- bit will be the lsb of d[rnd_digit+1]. If we set
-
- lsb = 1 << (rnd_bit % PyLong_SHIFT)
-
- then d[rnd_digit] & (PyLong_BASE - 2*lsb) selects just the
- significant bits of d[rnd_digit], d[rnd_digit] & (lsb-1) gets the
- trailing bits, and d[rnd_digit] & lsb gives the rounding bit.
-
- We initialize the double x to the integer given by digits
- d[rnd_digit:m-1], but with the rounding bit and trailing bits of
- d[rnd_digit] masked out. So the value of x comes from the top
- DBL_MANT_DIG bits of v, multiplied by 2*lsb. Note that in the loop
- that produces x, all floating-point operations are exact (assuming
- that FLT_RADIX==2). Now if we're rounding down, the value we want
- to return is simply
-
- x * 2**(PyLong_SHIFT * rnd_digit).
-
- and if we're rounding up, it's
-
- (x + 2*lsb) * 2**(PyLong_SHIFT * rnd_digit).
-
- Under the round-half-to-even rule, we round up if, and only
- if, the rounding bit is set *and* at least one of the
- following three conditions is satisfied:
-
- (1) the parity bit is set, or
- (2) at least one of the trailing bits of d[rnd_digit] is set, or
- (3) at least one of the digits d[i], 0 <= i < rnd_digit
- is nonzero.
-
- Finally, we have to worry about overflow. If v >= 2**DBL_MAX_EXP,
- or equivalently n > DBL_MAX_EXP, then overflow occurs. If v <
- 2**DBL_MAX_EXP then we're usually safe, but there's a corner case
- to consider: if v is very close to 2**DBL_MAX_EXP then it's
- possible that v is rounded up to exactly 2**DBL_MAX_EXP, and then
- again overflow occurs.
- */
-
- if (Py_SIZE(v) == 0)
- return 0.0;
- m = ABS(Py_SIZE(v)) - 1;
- d = v->ob_digit;
- assert(d[m]); /* v should be normalized */
-
- /* fast path for case where 0 < abs(v) < 2**DBL_MANT_DIG */
- if (m < DBL_MANT_DIG / PyLong_SHIFT ||
- (m == DBL_MANT_DIG / PyLong_SHIFT &&
- d[m] < (digit)1 << DBL_MANT_DIG%PyLong_SHIFT)) {
- x = d[m];
- while (--m >= 0)
- x = x*PyLong_BASE + d[m];
- return Py_SIZE(v) < 0 ? -x : x;
- }
-
- /* if m is huge then overflow immediately; otherwise, compute the
- number of bits n in v. The condition below implies n (= #bits) >=
- m * PyLong_SHIFT + 1 > DBL_MAX_EXP, hence v >= 2**DBL_MAX_EXP. */
- if (m > (DBL_MAX_EXP-1)/PyLong_SHIFT)
- goto overflow;
- n = m * PyLong_SHIFT + bits_in_digit(d[m]);
- if (n > DBL_MAX_EXP)
- goto overflow;
-
- /* find location of rounding bit */
- assert(n > DBL_MANT_DIG); /* dealt with |v| < 2**DBL_MANT_DIG above */
- rnd_bit = n - DBL_MANT_DIG - 1;
- rnd_digit = rnd_bit/PyLong_SHIFT;
- lsb = (digit)1 << (rnd_bit%PyLong_SHIFT);
-
- /* Get top DBL_MANT_DIG bits of v. Assumes PyLong_SHIFT <
- DBL_MANT_DIG, so we'll need bits from at least 2 digits of v. */
- x = d[m];
- assert(m > rnd_digit);
- while (--m > rnd_digit)
- x = x*PyLong_BASE + d[m];
- x = x*PyLong_BASE + (d[m] & (PyLong_BASE-2*lsb));
-
- /* decide whether to round up, using round-half-to-even */
- assert(m == rnd_digit);
- if (d[m] & lsb) { /* if (rounding bit is set) */
- digit parity_bit;
- if (lsb == PyLong_BASE/2)
- parity_bit = d[m+1] & 1;
- else
- parity_bit = d[m] & 2*lsb;
- if (parity_bit)
- round_up = 1;
- else if (d[m] & (lsb-1))
- round_up = 1;
- else {
- while (--m >= 0) {
- if (d[m]) {
- round_up = 1;
- break;
- }
- }
- }
- }
-
- /* and round up if necessary */
- if (round_up) {
- x += 2*lsb;
- if (n == DBL_MAX_EXP &&
- x == ldexp((double)(2*lsb), DBL_MANT_DIG)) {
- /* overflow corner case */
- goto overflow;
- }
- }
-
- /* shift, adjust for sign, and return */
- x = ldexp(x, rnd_digit*PyLong_SHIFT);
- return Py_SIZE(v) < 0 ? -x : x;
-
- overflow:
- PyErr_SetString(PyExc_OverflowError,
- "Python int too large to convert to C double");
- return -1.0;
-}
-
/* Create a new long (or int) object from a C pointer */
PyObject *
@@ -1209,6 +986,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. */
@@ -1394,9 +1172,8 @@ PyLong_AsLongLong(PyObject *vv)
case 0: return 0;
case 1: return v->ob_digit[0];
}
- res = _PyLong_AsByteArray(
- (PyLongObject *)vv, (unsigned char *)&bytes,
- SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
if (res < 0)
@@ -1427,9 +1204,8 @@ PyLong_AsUnsignedLongLong(PyObject *vv)
case 1: return v->ob_digit[0];
}
- res = _PyLong_AsByteArray(
- (PyLongObject *)vv, (unsigned char *)&bytes,
- SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
if (res < 0)
@@ -1466,7 +1242,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv)
i = -i;
}
while (--i >= 0) {
- x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
}
return x * sign;
}
@@ -1507,13 +1283,110 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op)
}
#undef IS_LITTLE_ENDIAN
-#endif /* HAVE_LONG_LONG */
+/* Get a C long long int from a Python long or Python int object.
+ On overflow, returns -1 and sets *overflow to 1 or -1 depending
+ on the sign of the result. Otherwise *overflow is 0.
+
+ For other errors (e.g., type error), returns -1 and sets an error
+ condition.
+*/
+
+PY_LONG_LONG
+PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
+{
+ /* This version by Tim Peters */
+ register PyLongObject *v;
+ unsigned PY_LONG_LONG x, prev;
+ PY_LONG_LONG res;
+ Py_ssize_t i;
+ int sign;
+ int do_decref = 0; /* if nb_int was called */
+
+ *overflow = 0;
+ if (vv == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ if (!PyLong_Check(vv)) {
+ PyNumberMethods *nb;
+ nb = vv->ob_type->tp_as_number;
+ if (nb == NULL || nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ return -1;
+ }
+ vv = (*nb->nb_int) (vv);
+ if (vv == NULL)
+ return -1;
+ do_decref = 1;
+ if (!PyLong_Check(vv)) {
+ Py_DECREF(vv);
+ PyErr_SetString(PyExc_TypeError,
+ "nb_int should return int object");
+ return -1;
+ }
+ }
-#define CHECK_BINOP(v,w) \
- if (!PyLong_Check(v) || !PyLong_Check(w)) { \
- Py_INCREF(Py_NotImplemented); \
- return Py_NotImplemented; \
+ res = -1;
+ v = (PyLongObject *)vv;
+ i = Py_SIZE(v);
+
+ switch (i) {
+ case -1:
+ res = -(sdigit)v->ob_digit[0];
+ break;
+ case 0:
+ res = 0;
+ break;
+ case 1:
+ res = v->ob_digit[0];
+ break;
+ default:
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -(i);
+ }
+ while (--i >= 0) {
+ prev = x;
+ x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ if ((x >> PyLong_SHIFT) != prev) {
+ *overflow = sign;
+ goto exit;
+ }
+ }
+ /* Haven't lost any bits, but casting to long requires extra
+ * care (see comment above).
+ */
+ if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) {
+ res = (PY_LONG_LONG)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_LLONG_MIN) {
+ res = PY_LLONG_MIN;
+ }
+ else {
+ *overflow = sign;
+ /* res is already set to -1 */
+ }
}
+ exit:
+ if (do_decref) {
+ Py_DECREF(vv);
+ }
+ return res;
+}
+
+#endif /* HAVE_LONG_LONG */
+
+#define CHECK_BINOP(v,w) \
+ do { \
+ if (!PyLong_Check(v) || !PyLong_Check(w)) { \
+ Py_INCREF(Py_NotImplemented); \
+ return Py_NotImplemented; \
+ } \
+ } while(0)
/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
2**k if d is nonzero, else 0. */
@@ -1640,7 +1513,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;
}
@@ -1665,8 +1538,122 @@ divrem1(PyLongObject *a, digit n, digit *prem)
return long_normalize(z);
}
-/* Convert a long int object to a string, using a given conversion base.
- Return a string object.
+/* Convert a long integer to a base 10 string. Returns a new non-shared
+ string. (Return value is non-shared so that callers can modify the
+ returned value if necessary.) */
+
+static PyObject *
+long_to_decimal_string(PyObject *aa)
+{
+ PyLongObject *scratch, *a;
+ PyObject *str;
+ Py_ssize_t size, strlen, size_a, i, j;
+ digit *pout, *pin, rem, tenpow;
+ Py_UNICODE *p;
+ int negative;
+
+ a = (PyLongObject *)aa;
+ if (a == NULL || !PyLong_Check(a)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ size_a = ABS(Py_SIZE(a));
+ negative = Py_SIZE(a) < 0;
+
+ /* quick and dirty upper bound for the number of digits
+ required to express a in base _PyLong_DECIMAL_BASE:
+
+ #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))
+
+ But log2(a) < size_a * PyLong_SHIFT, and
+ log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
+ > 3 * _PyLong_DECIMAL_SHIFT
+ */
+ if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long is too large to format");
+ return NULL;
+ }
+ /* the expression size_a * PyLong_SHIFT is now safe from overflow */
+ size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
+ scratch = _PyLong_New(size);
+ if (scratch == NULL)
+ return NULL;
+
+ /* convert array of base _PyLong_BASE digits in pin to an array of
+ base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
+ Volume 2 (3rd edn), section 4.4, Method 1b). */
+ pin = a->ob_digit;
+ pout = scratch->ob_digit;
+ size = 0;
+ for (i = size_a; --i >= 0; ) {
+ digit hi = pin[i];
+ for (j = 0; j < size; j++) {
+ twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
+ hi = (digit)(z / _PyLong_DECIMAL_BASE);
+ pout[j] = (digit)(z - (twodigits)hi *
+ _PyLong_DECIMAL_BASE);
+ }
+ while (hi) {
+ pout[size++] = hi % _PyLong_DECIMAL_BASE;
+ hi /= _PyLong_DECIMAL_BASE;
+ }
+ /* check for keyboard interrupt */
+ SIGCHECK({
+ Py_DECREF(scratch);
+ return NULL;
+ });
+ }
+ /* pout should have at least one digit, so that the case when a = 0
+ works correctly */
+ if (size == 0)
+ pout[size++] = 0;
+
+ /* calculate exact length of output string, and allocate */
+ strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
+ tenpow = 10;
+ rem = pout[size-1];
+ while (rem >= tenpow) {
+ tenpow *= 10;
+ strlen++;
+ }
+ str = PyUnicode_FromUnicode(NULL, strlen);
+ if (str == NULL) {
+ Py_DECREF(scratch);
+ return NULL;
+ }
+
+ /* fill the string right-to-left */
+ p = PyUnicode_AS_UNICODE(str) + strlen;
+ *p = '\0';
+ /* pout[0] through pout[size-2] contribute exactly
+ _PyLong_DECIMAL_SHIFT digits each */
+ for (i=0; i < size - 1; i++) {
+ rem = pout[i];
+ for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {
+ *--p = '0' + rem % 10;
+ rem /= 10;
+ }
+ }
+ /* pout[size-1]: always produce at least one decimal digit */
+ rem = pout[i];
+ do {
+ *--p = '0' + rem % 10;
+ rem /= 10;
+ } while (rem != 0);
+
+ /* and sign */
+ if (negative)
+ *--p = '-';
+
+ /* check we've counted correctly */
+ assert(p == PyUnicode_AS_UNICODE(str));
+ Py_DECREF(scratch);
+ return (PyObject *)str;
+}
+
+/* Convert a long int object to a string, using a given conversion base,
+ which should be one of 2, 8, 10 or 16. Return a string object.
If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */
PyObject *
@@ -1676,32 +1663,44 @@ _PyLong_Format(PyObject *aa, int base)
PyObject *str;
Py_ssize_t i, sz;
Py_ssize_t size_a;
- Py_UNICODE *p;
+ Py_UNICODE *p, sign = '\0';
int bits;
- char sign = '\0';
+
+ assert(base == 2 || base == 8 || base == 10 || base == 16);
+ if (base == 10)
+ return long_to_decimal_string((PyObject *)a);
if (a == NULL || !PyLong_Check(a)) {
PyErr_BadInternalCall();
return NULL;
}
- assert(base >= 2 && base <= 36);
size_a = ABS(Py_SIZE(a));
/* Compute a rough upper bound for the length of the string */
- i = base;
- bits = 0;
- while (i > 1) {
- ++bits;
- i >>= 1;
- }
- i = 5;
- /* ensure we don't get signed overflow in sz calculation */
- if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {
+ switch (base) {
+ case 16:
+ bits = 4;
+ break;
+ case 8:
+ bits = 3;
+ break;
+ case 2:
+ bits = 1;
+ break;
+ default:
+ assert(0); /* shouldn't ever get here */
+ bits = 0; /* to silence gcc warning */
+ }
+ /* compute length of output string: allow 2 characters for prefix and
+ 1 for possible '-' sign. */
+ if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) {
PyErr_SetString(PyExc_OverflowError,
"int is too large to format");
return NULL;
}
- sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;
+ /* now size_a * PyLong_SHIFT + 3 <= PY_SSIZE_T_MAX, so the RHS below
+ is safe from overflow */
+ sz = 3 + (size_a * PyLong_SHIFT + (bits - 1)) / bits;
assert(sz >= 0);
str = PyUnicode_FromUnicode(NULL, sz);
if (str == NULL)
@@ -1714,106 +1713,33 @@ _PyLong_Format(PyObject *aa, int base)
if (Py_SIZE(a) == 0) {
*--p = '0';
}
- else if ((base & (base - 1)) == 0) {
+ else {
/* JRH: special case for power-of-2 bases */
twodigits accum = 0;
int accumbits = 0; /* # of bits in accum */
- int basebits = 1; /* # of bits in base-1 */
- i = base;
- while ((i >>= 1) > 1)
- ++basebits;
-
for (i = 0; i < size_a; ++i) {
accum |= (twodigits)a->ob_digit[i] << accumbits;
accumbits += PyLong_SHIFT;
- assert(accumbits >= basebits);
+ assert(accumbits >= bits);
do {
- char cdigit = (char)(accum & (base - 1));
+ Py_UNICODE cdigit;
+ cdigit = (Py_UNICODE)(accum & (base - 1));
cdigit += (cdigit < 10) ? '0' : 'a'-10;
assert(p > PyUnicode_AS_UNICODE(str));
*--p = cdigit;
- accumbits -= basebits;
- accum >>= basebits;
- } while (i < size_a-1 ? accumbits >= basebits :
- accum > 0);
- }
- }
- else {
- /* Not 0, and base not a power of 2. Divide repeatedly by
- base, but for speed use the highest power of base that
- fits in a digit. */
- Py_ssize_t size = size_a;
- digit *pin = a->ob_digit;
- PyLongObject *scratch;
- /* powbasw <- largest power of base that fits in a digit. */
- digit powbase = base; /* powbase == base ** power */
- int power = 1;
- for (;;) {
- twodigits newpow = powbase * (twodigits)base;
- if (newpow >> PyLong_SHIFT)
- /* doesn't fit in a digit */
- break;
- powbase = (digit)newpow;
- ++power;
- }
-
- /* Get a scratch area for repeated division. */
- scratch = _PyLong_New(size);
- if (scratch == NULL) {
- Py_DECREF(str);
- return NULL;
+ accumbits -= bits;
+ accum >>= bits;
+ } while (i < size_a-1 ? accumbits >= bits : accum > 0);
}
-
- /* Repeatedly divide by powbase. */
- do {
- int ntostore = power;
- digit rem = inplace_divrem1(scratch->ob_digit,
- pin, size, powbase);
- pin = scratch->ob_digit; /* no need to use a again */
- if (pin[size - 1] == 0)
- --size;
- SIGCHECK({
- Py_DECREF(scratch);
- Py_DECREF(str);
- return NULL;
- })
-
- /* Break rem into digits. */
- assert(ntostore > 0);
- do {
- digit nextrem = (digit)(rem / base);
- char c = (char)(rem - nextrem * base);
- assert(p > PyUnicode_AS_UNICODE(str));
- c += (c < 10) ? '0' : 'a'-10;
- *--p = c;
- rem = nextrem;
- --ntostore;
- /* Termination is a bit delicate: must not
- store leading zeroes, so must get out if
- remaining quotient and rem are both 0. */
- } while (ntostore && (size || rem));
- } while (size != 0);
- Py_DECREF(scratch);
}
- if (base == 16) {
+ if (base == 16)
*--p = 'x';
- *--p = '0';
- }
- else if (base == 8) {
+ else if (base == 8)
*--p = 'o';
- *--p = '0';
- }
- else if (base == 2) {
+ else /* (base == 2) */
*--p = 'b';
- *--p = '0';
- }
- else if (base != 10) {
- *--p = '#';
- *--p = '0' + base%10;
- if (base > 10)
- *--p = '0' + base/10;
- }
+ *--p = '0';
if (sign)
*--p = sign;
if (p != PyUnicode_AS_UNICODE(str)) {
@@ -2072,8 +1998,8 @@ digit beyond the first.
twodigits convmax = base;
int i = 1;
- log_base_BASE[base] = log((double)base) /
- log((double)PyLong_BASE);
+ log_base_BASE[base] = (log((double)base) /
+ log((double)PyLong_BASE));
for (;;) {
twodigits next = convmax * base;
if (next > PyLong_BASE)
@@ -2117,7 +2043,7 @@ digit beyond the first.
c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
for (i = 1; i < convwidth && str != scan; ++i, ++str) {
c = (twodigits)(c * base +
- (int)_PyLong_DigitValue[Py_CHARMASK(*str)]);
+ (int)_PyLong_DigitValue[Py_CHARMASK(*str)]);
assert(c < PyLong_BASE);
}
@@ -2190,7 +2116,7 @@ digit beyond the first.
long_normalize(z);
return (PyObject *) maybe_small_long(z);
- onError:
+ onError:
Py_XDECREF(z);
slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
strobj = PyUnicode_FromStringAndSize(orig_str, slen);
@@ -2207,17 +2133,34 @@ PyObject *
PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
{
PyObject *result;
- char *buffer = (char *)PyMem_MALLOC(length+1);
+ PyObject *asciidig;
+ char *buffer, *end;
+ Py_ssize_t i, buflen;
+ Py_UNICODE *ptr;
- if (buffer == NULL)
+ asciidig = PyUnicode_TransformDecimalToASCII(u, length);
+ if (asciidig == NULL)
return NULL;
-
- if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
- PyMem_FREE(buffer);
+ /* Replace non-ASCII whitespace with ' ' */
+ ptr = PyUnicode_AS_UNICODE(asciidig);
+ for (i = 0; i < length; i++) {
+ Py_UNICODE ch = ptr[i];
+ if (ch > 127 && Py_UNICODE_ISSPACE(ch))
+ ptr[i] = ' ';
+ }
+ buffer = _PyUnicode_AsStringAndSize(asciidig, &buflen);
+ if (buffer == NULL) {
+ Py_DECREF(asciidig);
return NULL;
}
- result = PyLong_FromString(buffer, NULL, base);
- PyMem_FREE(buffer);
+ result = PyLong_FromString(buffer, &end, base);
+ if (result != NULL && end != buffer + buflen) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for int()");
+ Py_DECREF(result);
+ result = NULL;
+ }
+ Py_DECREF(asciidig);
return result;
}
@@ -2346,12 +2289,12 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
single-digit quotient q, remainder in vk[0:size_w]. */
SIGCHECK({
- Py_DECREF(a);
- Py_DECREF(w);
- Py_DECREF(v);
- *prem = NULL;
- return NULL;
- })
+ Py_DECREF(a);
+ Py_DECREF(w);
+ Py_DECREF(v);
+ *prem = NULL;
+ return NULL;
+ });
/* estimate quotient digit q; may overestimate by 1 (rare) */
vtop = vk[size_w];
@@ -2377,7 +2320,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
(stwodigits)q * (stwodigits)w0[i];
vk[i] = (digit)z & PyLong_MASK;
zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
- z, PyLong_SHIFT);
+ z, PyLong_SHIFT);
}
/* add w back if q was too large (this branch taken rarely) */
@@ -2406,6 +2349,153 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
return long_normalize(a);
}
+/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <=
+ abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is
+ rounded to DBL_MANT_DIG significant bits using round-half-to-even.
+ If a == 0, return 0.0 and set *e = 0. If the resulting exponent
+ e is larger than PY_SSIZE_T_MAX, raise OverflowError and return
+ -1.0. */
+
+/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */
+#if DBL_MANT_DIG == 53
+#define EXP2_DBL_MANT_DIG 9007199254740992.0
+#else
+#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))
+#endif
+
+double
+_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
+{
+ Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;
+ /* See below for why x_digits is always large enough. */
+ digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT];
+ double dx;
+ /* Correction term for round-half-to-even rounding. For a digit x,
+ "x + half_even_correction[x & 7]" gives x rounded to the nearest
+ multiple of 4, rounding ties to a multiple of 8. */
+ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
+
+ a_size = ABS(Py_SIZE(a));
+ if (a_size == 0) {
+ /* Special case for 0: significand 0.0, exponent 0. */
+ *e = 0;
+ return 0.0;
+ }
+ a_bits = bits_in_digit(a->ob_digit[a_size-1]);
+ /* The following is an overflow-free version of the check
+ "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */
+ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&
+ (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||
+ a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))
+ goto overflow;
+ a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;
+
+ /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size]
+ (shifting left if a_bits <= DBL_MANT_DIG + 2).
+
+ Number of digits needed for result: write // for floor division.
+ Then if shifting left, we end up using
+
+ 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT
+
+ digits. If shifting right, we use
+
+ a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT
+
+ digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with
+ the inequalities
+
+ m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT
+ m // PyLong_SHIFT - n // PyLong_SHIFT <=
+ 1 + (m - n - 1) // PyLong_SHIFT,
+
+ valid for any integers m and n, we find that x_size satisfies
+
+ x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT
+
+ in both cases.
+ */
+ if (a_bits <= DBL_MANT_DIG + 2) {
+ shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;
+ shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;
+ x_size = 0;
+ while (x_size < shift_digits)
+ x_digits[x_size++] = 0;
+ rem = v_lshift(x_digits + x_size, a->ob_digit, a_size,
+ (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 */
static void
@@ -2414,22 +2504,13 @@ long_dealloc(PyObject *v)
Py_TYPE(v)->tp_free(v);
}
-static PyObject *
-long_repr(PyObject *v)
-{
- return _PyLong_Format(v, 10);
-}
-
static int
long_compare(PyLongObject *a, PyLongObject *b)
{
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));
@@ -2487,16 +2568,13 @@ long_richcompare(PyObject *self, PyObject *other, int op)
return v;
}
-static long
+static Py_hash_t
long_hash(PyLongObject *v)
{
- unsigned long x;
+ Py_uhash_t x;
Py_ssize_t i;
int sign;
- /* This is designed so that Python ints and longs with the
- same value hash to the same value, otherwise comparisons
- of mapping keys will turn out weird */
i = Py_SIZE(v);
switch(i) {
case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0];
@@ -2509,23 +2587,42 @@ long_hash(PyLongObject *v)
sign = -1;
i = -(i);
}
- /* The following loop produces a C unsigned long x such that x is
- congruent to the absolute value of v modulo ULONG_MAX. The
- resulting x is nonzero if and only if v is. */
while (--i >= 0) {
- /* Force a native long #-bits (32 or 64) circular shift */
- x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);
+ /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we
+ want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo
+ _PyHASH_MODULUS.
+
+ The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS
+ amounts to a rotation of the bits of x. To see this, write
+
+ x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z
+
+ where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top
+ PyLong_SHIFT bits of x (those that are shifted out of the
+ original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) &
+ _PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT
+ bits of x, shifted up. Then since 2**_PyHASH_BITS is
+ congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is
+ congruent to y modulo _PyHASH_MODULUS. So
+
+ x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS).
+
+ The right-hand side is just the result of rotating the
+ _PyHASH_BITS bits of x left by PyLong_SHIFT places; since
+ not all _PyHASH_BITS bits of x are 1s, the same is true
+ after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is
+ the reduction of x*2**PyLong_SHIFT modulo
+ _PyHASH_MODULUS. */
+ x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) |
+ (x >> (_PyHASH_BITS - PyLong_SHIFT));
x += v->ob_digit[i];
- /* If the addition above overflowed we compensate by
- incrementing. This preserves the value modulo
- ULONG_MAX. */
- if (x < v->ob_digit[i])
- x++;
+ if (x >= _PyHASH_MODULUS)
+ x -= _PyHASH_MODULUS;
}
x = x * sign;
- if (x == (unsigned long)-1)
- x = (unsigned long)-2;
- return (long)x;
+ if (x == (Py_uhash_t)-1)
+ x = (Py_uhash_t)-2;
+ return (Py_hash_t)x;
}
@@ -2543,8 +2640,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)
@@ -2579,8 +2676,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: */
@@ -2708,9 +2805,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);
@@ -2746,9 +2843,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;
@@ -2772,7 +2869,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;
@@ -2961,7 +3061,7 @@ k_mul(PyLongObject *a, PyLongObject *b)
return long_normalize(ret);
- fail:
+ fail:
Py_XDECREF(ret);
Py_XDECREF(ah);
Py_XDECREF(al);
@@ -3071,7 +3171,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;
@@ -3183,47 +3283,267 @@ long_div(PyObject *a, PyObject *b)
return (PyObject *)div;
}
+/* PyLong/PyLong -> float, with correctly rounded result. */
+
+#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
+#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
+
static PyObject *
-long_true_divide(PyObject *a, PyObject *b)
+long_true_divide(PyObject *v, PyObject *w)
{
- double ad, bd;
- int failed, aexp = -1, bexp = -1;
+ PyLongObject *a, *b, *x;
+ Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;
+ digit mask, low;
+ int inexact, negate, a_is_small, b_is_small;
+ double dx, result;
- CHECK_BINOP(a, b);
- ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp);
- bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp);
- failed = (ad == -1.0 || bd == -1.0) && PyErr_Occurred();
- if (failed)
- return NULL;
- /* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x,
- but should really be set correctly after successful calls to
- _PyLong_AsScaledDouble() */
- assert(aexp >= 0 && bexp >= 0);
+ CHECK_BINOP(v, w);
+ a = (PyLongObject *)v;
+ b = (PyLongObject *)w;
+
+ /*
+ Method in a nutshell:
+
+ 0. reduce to case a, b > 0; filter out obvious underflow/overflow
+ 1. choose a suitable integer 'shift'
+ 2. use integer arithmetic to compute x = floor(2**-shift*a/b)
+ 3. adjust x for correct rounding
+ 4. convert x to a double dx with the same value
+ 5. return ldexp(dx, shift).
+
+ In more detail:
+
+ 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b
+ returns either 0.0 or -0.0, depending on the sign of b. For a and
+ b both nonzero, ignore signs of a and b, and add the sign back in
+ at the end. Now write a_bits and b_bits for the bit lengths of a
+ and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise
+ for b). Then
+
+ 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).
+
+ So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and
+ so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP -
+ DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of
+ the way, we can assume that
+
+ DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.
+
+ 1. The integer 'shift' is chosen so that x has the right number of
+ bits for a double, plus two or three extra bits that will be used
+ in the rounding decisions. Writing a_bits and b_bits for the
+ number of significant bits in a and b respectively, a
+ straightforward formula for shift is:
+
+ shift = a_bits - b_bits - DBL_MANT_DIG - 2
+
+ This is fine in the usual case, but if a/b is smaller than the
+ smallest normal float then it can lead to double rounding on an
+ IEEE 754 platform, giving incorrectly rounded results. So we
+ adjust the formula slightly. The actual formula used is:
+
+ shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2
+
+ 2. The quantity x is computed by first shifting a (left -shift bits
+ if shift <= 0, right shift bits if shift > 0) and then dividing by
+ b. For both the shift and the division, we keep track of whether
+ the result is inexact, in a flag 'inexact'; this information is
+ needed at the rounding stage.
+
+ With the choice of shift above, together with our assumption that
+ a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows
+ that x >= 1.
+
+ 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace
+ this with an exactly representable float of the form
+
+ round(x/2**extra_bits) * 2**(extra_bits+shift).
+
+ For float representability, we need x/2**extra_bits <
+ 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -
+ DBL_MANT_DIG. This translates to the condition:
+
+ extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG
+
+ To round, we just modify the bottom digit of x in-place; this can
+ end up giving a digit with value > PyLONG_MASK, but that's not a
+ problem since digits can hold values up to 2*PyLONG_MASK+1.
+
+ With the original choices for shift above, extra_bits will always
+ be 2 or 3. Then rounding under the round-half-to-even rule, we
+ round up iff the most significant of the extra bits is 1, and
+ either: (a) the computation of x in step 2 had an inexact result,
+ or (b) at least one other of the extra bits is 1, or (c) the least
+ significant bit of x (above those to be rounded) is 1.
+
+ 4. Conversion to a double is straightforward; all floating-point
+ operations involved in the conversion are exact, so there's no
+ danger of rounding errors.
+
+ 5. Use ldexp(x, shift) to compute x*2**shift, the final result.
+ The result will always be exactly representable as a double, except
+ in the case that it overflows. To avoid dependence on the exact
+ behaviour of ldexp on overflow, we check for overflow before
+ applying ldexp. The result of ldexp is adjusted for sign before
+ returning.
+ */
- if (bd == 0.0) {
+ /* Reduce to case where a and b are both positive. */
+ a_size = ABS(Py_SIZE(a));
+ b_size = ABS(Py_SIZE(b));
+ negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0);
+ if (b_size == 0) {
PyErr_SetString(PyExc_ZeroDivisionError,
- "int division or modulo by zero");
- return NULL;
+ "division by zero");
+ goto error;
}
-
- /* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */
- ad /= bd; /* overflow/underflow impossible here */
- aexp -= bexp;
- if (aexp > INT_MAX / PyLong_SHIFT)
+ if (a_size == 0)
+ goto underflow_or_zero;
+
+ /* Fast path for a and b small (exactly representable in a double).
+ Relies on floating-point division being correctly rounded; results
+ may be subject to double rounding on x86 machines that operate with
+ the x87 FPU set to 64-bit precision. */
+ a_is_small = a_size <= MANT_DIG_DIGITS ||
+ (a_size == MANT_DIG_DIGITS+1 &&
+ a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+ b_is_small = b_size <= MANT_DIG_DIGITS ||
+ (b_size == MANT_DIG_DIGITS+1 &&
+ b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+ if (a_is_small && b_is_small) {
+ double da, db;
+ da = a->ob_digit[--a_size];
+ while (a_size > 0)
+ da = da * PyLong_BASE + a->ob_digit[--a_size];
+ db = b->ob_digit[--b_size];
+ while (b_size > 0)
+ db = db * PyLong_BASE + b->ob_digit[--b_size];
+ result = da / db;
+ goto success;
+ }
+
+ /* Catch obvious cases of underflow and overflow */
+ diff = a_size - b_size;
+ if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)
+ /* Extreme overflow */
goto overflow;
- else if (aexp < -(INT_MAX / PyLong_SHIFT))
- return PyFloat_FromDouble(0.0); /* underflow to 0 */
- errno = 0;
- ad = ldexp(ad, aexp * PyLong_SHIFT);
- if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */
+ else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)
+ /* Extreme underflow */
+ goto underflow_or_zero;
+ /* Next line is now safe from overflowing a Py_ssize_t */
+ diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) -
+ bits_in_digit(b->ob_digit[b_size - 1]);
+ /* Now diff = a_bits - b_bits. */
+ if (diff > DBL_MAX_EXP)
goto overflow;
- return PyFloat_FromDouble(ad);
+ else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)
+ goto underflow_or_zero;
+
+ /* Choose value for shift; see comments for step 1 above. */
+ shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;
+
+ inexact = 0;
+
+ /* x = abs(a * 2**-shift) */
+ if (shift <= 0) {
+ Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;
+ digit rem;
+ /* x = a << -shift */
+ if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {
+ /* In practice, it's probably impossible to end up
+ here. Both a and b would have to be enormous,
+ using close to SIZE_T_MAX bytes of memory each. */
+ PyErr_SetString(PyExc_OverflowError,
+ "intermediate overflow during division");
+ goto error;
+ }
+ x = _PyLong_New(a_size + shift_digits + 1);
+ if (x == NULL)
+ goto error;
+ for (i = 0; i < shift_digits; i++)
+ x->ob_digit[i] = 0;
+ rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit,
+ a_size, -shift % PyLong_SHIFT);
+ x->ob_digit[a_size + shift_digits] = rem;
+ }
+ else {
+ Py_ssize_t shift_digits = shift / PyLong_SHIFT;
+ digit rem;
+ /* x = a >> shift */
+ assert(a_size >= shift_digits);
+ x = _PyLong_New(a_size - shift_digits);
+ if (x == NULL)
+ goto error;
+ rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits,
+ a_size - shift_digits, shift % PyLong_SHIFT);
+ /* set inexact if any of the bits shifted out is nonzero */
+ if (rem)
+ inexact = 1;
+ while (!inexact && shift_digits > 0)
+ if (a->ob_digit[--shift_digits])
+ inexact = 1;
+ }
+ long_normalize(x);
+ x_size = Py_SIZE(x);
+
+ /* x //= b. If the remainder is nonzero, set inexact. We own the only
+ reference to x, so it's safe to modify it in-place. */
+ if (b_size == 1) {
+ digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size,
+ b->ob_digit[0]);
+ long_normalize(x);
+ if (rem)
+ inexact = 1;
+ }
+ else {
+ PyLongObject *div, *rem;
+ div = x_divrem(x, b, &rem);
+ Py_DECREF(x);
+ x = div;
+ if (x == NULL)
+ goto error;
+ if (Py_SIZE(rem))
+ inexact = 1;
+ Py_DECREF(rem);
+ }
+ x_size = ABS(Py_SIZE(x));
+ assert(x_size > 0); /* result of division is never zero */
+ x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]);
+
+ /* The number of extra bits that have to be rounded away. */
+ extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;
+ assert(extra_bits == 2 || extra_bits == 3);
+
+ /* Round by directly modifying the low digit of x. */
+ mask = (digit)1 << (extra_bits - 1);
+ low = x->ob_digit[0] | inexact;
+ if (low & mask && low & (3*mask-1))
+ low += mask;
+ x->ob_digit[0] = low & ~(mask-1U);
+
+ /* Convert x to a double dx; the conversion is exact. */
+ dx = x->ob_digit[--x_size];
+ while (x_size > 0)
+ dx = dx * PyLong_BASE + x->ob_digit[--x_size];
+ Py_DECREF(x);
+
+ /* Check whether ldexp result will overflow a double. */
+ if (shift + x_bits >= DBL_MAX_EXP &&
+ (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))
+ goto overflow;
+ result = ldexp(dx, (int)shift);
+
+ success:
+ return PyFloat_FromDouble(negate ? -result : result);
-overflow:
+ underflow_or_zero:
+ return PyFloat_FromDouble(negate ? -0.0 : 0.0);
+
+ overflow:
PyErr_SetString(PyExc_OverflowError,
- "int/int too large for a float");
+ "integer division result too large for a float");
+ error:
return NULL;
-
}
static PyObject *
@@ -3298,7 +3618,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 {
@@ -3364,26 +3684,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) */
@@ -3392,9 +3714,9 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
digit bi = b->ob_digit[i];
for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
- MULT(z, z, z)
+ MULT(z, z, z);
if (bi & j)
- MULT(z, a, z)
+ MULT(z, a, z);
}
}
}
@@ -3403,7 +3725,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];
@@ -3411,9 +3733,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);
}
}
}
@@ -3428,13 +3750,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]);
@@ -3489,15 +3811,14 @@ long_abs(PyLongObject *v)
static int
long_bool(PyLongObject *v)
{
- return ABS(Py_SIZE(v)) != 0;
+ return Py_SIZE(v) != 0;
}
static PyObject *
long_rshift(PyLongObject *a, PyLongObject *b)
{
PyLongObject *z = NULL;
- long shiftby;
- Py_ssize_t newsize, wordshift, loshift, hishift, i, j;
+ Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;
digit lomask, himask;
CHECK_BINOP(a, b);
@@ -3516,8 +3837,7 @@ long_rshift(PyLongObject *a, PyLongObject *b)
Py_DECREF(a2);
}
else {
-
- shiftby = PyLong_AsLong((PyObject *)b);
+ shiftby = PyLong_AsSsize_t((PyObject *)b);
if (shiftby == -1L && PyErr_Occurred())
goto rshift_error;
if (shiftby < 0) {
@@ -3541,12 +3861,11 @@ long_rshift(PyLongObject *a, PyLongObject *b)
for (i = 0, j = wordshift; i < newsize; i++, j++) {
z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
if (i+1 < newsize)
- z->ob_digit[i] |=
- (a->ob_digit[j+1] << hishift) & himask;
+ z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;
}
z = long_normalize(z);
}
-rshift_error:
+ rshift_error:
return (PyObject *) maybe_small_long(z);
}
@@ -3558,27 +3877,21 @@ long_lshift(PyObject *v, PyObject *w)
PyLongObject *a = (PyLongObject*)v;
PyLongObject *b = (PyLongObject*)w;
PyLongObject *z = NULL;
- long shiftby;
- Py_ssize_t oldsize, newsize, wordshift, remshift, i, j;
+ Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;
twodigits accum;
CHECK_BINOP(a, b);
- shiftby = PyLong_AsLong((PyObject *)b);
+ shiftby = PyLong_AsSsize_t((PyObject *)b);
if (shiftby == -1L && PyErr_Occurred())
goto lshift_error;
if (shiftby < 0) {
PyErr_SetString(PyExc_ValueError, "negative shift count");
goto lshift_error;
}
- if ((long)(int)shiftby != shiftby) {
- PyErr_SetString(PyExc_ValueError,
- "outrageous left shift count");
- goto lshift_error;
- }
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
- wordshift = (int)shiftby / PyLong_SHIFT;
- remshift = (int)shiftby - wordshift * PyLong_SHIFT;
+ wordshift = shiftby / PyLong_SHIFT;
+ remshift = shiftby - wordshift * PyLong_SHIFT;
oldsize = ABS(Py_SIZE(a));
newsize = oldsize + wordshift;
@@ -3602,116 +3915,150 @@ long_lshift(PyObject *v, PyObject *w)
else
assert(!accum);
z = long_normalize(z);
-lshift_error:
+ lshift_error:
return (PyObject *) maybe_small_long(z);
}
+/* Compute two's complement of digit vector a[0:m], writing result to
+ z[0:m]. The digit vector a need not be normalized, but should not
+ be entirely zero. a and z may point to the same digit vector. */
+
+static void
+v_complement(digit *z, digit *a, Py_ssize_t m)
+{
+ Py_ssize_t i;
+ digit carry = 1;
+ for (i = 0; i < m; ++i) {
+ carry += a[i] ^ PyLong_MASK;
+ z[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ }
+ assert(carry == 0);
+}
/* Bitwise and/xor/or operations */
static PyObject *
long_bitwise(PyLongObject *a,
int op, /* '&', '|', '^' */
- PyLongObject *b)
+ PyLongObject *b)
{
- digit maska, maskb; /* 0 or PyLong_MASK */
- int negz;
+ int nega, negb, negz;
Py_ssize_t size_a, size_b, size_z, i;
PyLongObject *z;
- digit diga, digb;
- PyObject *v;
- if (Py_SIZE(a) < 0) {
- a = (PyLongObject *) long_invert(a);
- if (a == NULL)
+ /* Bitwise operations for negative numbers operate as though
+ on a two's complement representation. So convert arguments
+ from sign-magnitude to two's complement, and convert the
+ result back to sign-magnitude at the end. */
+
+ /* If a is negative, replace it by its two's complement. */
+ size_a = ABS(Py_SIZE(a));
+ nega = Py_SIZE(a) < 0;
+ if (nega) {
+ z = _PyLong_New(size_a);
+ if (z == NULL)
return NULL;
- maska = PyLong_MASK;
+ v_complement(z->ob_digit, a->ob_digit, size_a);
+ a = z;
}
- else {
+ else
+ /* Keep reference count consistent. */
Py_INCREF(a);
- maska = 0;
- }
- if (Py_SIZE(b) < 0) {
- b = (PyLongObject *) long_invert(b);
- if (b == NULL) {
+
+ /* Same for b. */
+ size_b = ABS(Py_SIZE(b));
+ negb = Py_SIZE(b) < 0;
+ if (negb) {
+ z = _PyLong_New(size_b);
+ if (z == NULL) {
Py_DECREF(a);
return NULL;
}
- maskb = PyLong_MASK;
+ v_complement(z->ob_digit, b->ob_digit, size_b);
+ b = z;
}
- else {
+ else
Py_INCREF(b);
- maskb = 0;
+
+ /* Swap a and b if necessary to ensure size_a >= size_b. */
+ if (size_a < size_b) {
+ z = a; a = b; b = z;
+ size_z = size_a; size_a = size_b; size_b = size_z;
+ negz = nega; nega = negb; negb = negz;
}
- negz = 0;
+ /* JRH: The original logic here was to allocate the result value (z)
+ as the longer of the two operands. However, there are some cases
+ where the result is guaranteed to be shorter than that: AND of two
+ positives, OR of two negatives: use the shorter number. AND with
+ mixed signs: use the positive number. OR with mixed signs: use the
+ negative number.
+ */
switch (op) {
case '^':
- if (maska != maskb) {
- maska ^= PyLong_MASK;
- negz = -1;
- }
+ negz = nega ^ negb;
+ size_z = size_a;
break;
case '&':
- if (maska && maskb) {
- op = '|';
- maska ^= PyLong_MASK;
- maskb ^= PyLong_MASK;
- negz = -1;
- }
+ negz = nega & negb;
+ size_z = negb ? size_a : size_b;
break;
case '|':
- if (maska || maskb) {
- op = '&';
- maska ^= PyLong_MASK;
- maskb ^= PyLong_MASK;
- negz = -1;
- }
+ negz = nega | negb;
+ size_z = negb ? size_b : size_a;
break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
}
- /* JRH: The original logic here was to allocate the result value (z)
- as the longer of the two operands. However, there are some cases
- where the result is guaranteed to be shorter than that: AND of two
- positives, OR of two negatives: use the shorter number. AND with
- mixed signs: use the positive number. OR with mixed signs: use the
- negative number. After the transformations above, op will be '&'
- iff one of these cases applies, and mask will be non-0 for operands
- whose length should be ignored.
- */
-
- size_a = Py_SIZE(a);
- size_b = Py_SIZE(b);
- size_z = op == '&'
- ? (maska
- ? size_b
- : (maskb ? size_a : MIN(size_a, size_b)))
- : MAX(size_a, size_b);
- z = _PyLong_New(size_z);
+ /* We allow an extra digit if z is negative, to make sure that
+ the final two's complement of z doesn't overflow. */
+ z = _PyLong_New(size_z + negz);
if (z == NULL) {
Py_DECREF(a);
Py_DECREF(b);
return NULL;
}
- for (i = 0; i < size_z; ++i) {
- diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
- digb = (i < size_b ? b->ob_digit[i] : 0) ^ maskb;
- switch (op) {
- case '&': z->ob_digit[i] = diga & digb; break;
- case '|': z->ob_digit[i] = diga | digb; break;
- case '^': z->ob_digit[i] = diga ^ digb; break;
- }
+ /* Compute digits for overlap of a and b. */
+ switch(op) {
+ case '&':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
+ break;
+ case '|':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];
+ break;
+ case '^':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ /* Copy any remaining digits of a, inverting if necessary. */
+ if (op == '^' && negb)
+ for (; i < size_z; ++i)
+ z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;
+ else if (i < size_z)
+ memcpy(&z->ob_digit[i], &a->ob_digit[i],
+ (size_z-i)*sizeof(digit));
+
+ /* Complement result if negative. */
+ if (negz) {
+ Py_SIZE(z) = -(Py_SIZE(z));
+ z->ob_digit[size_z] = PyLong_MASK;
+ v_complement(z->ob_digit, z->ob_digit, size_z+1);
}
Py_DECREF(a);
Py_DECREF(b);
- z = long_normalize(z);
- if (negz == 0)
- return (PyObject *) maybe_small_long(z);
- v = long_invert(z);
- Py_DECREF(z);
- return v;
+ return (PyObject *)maybe_small_long(long_normalize(z));
}
static PyObject *
@@ -3767,23 +4114,34 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyObject *x = NULL;
- int base = -909; /* unlikely! */
+ PyObject *obase = NULL, *x = NULL;
+ long base;
+ int overflow;
static char *kwlist[] = {"x", "base", 0};
if (type != &PyLong_Type)
return long_subtype_new(type, args, kwds); /* Wimp out */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
- &x, &base))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:int", kwlist,
+ &x, &obase))
return NULL;
if (x == NULL)
return PyLong_FromLong(0L);
- if (base == -909)
+ if (obase == NULL)
return PyNumber_Long(x);
- else if (PyUnicode_Check(x))
+
+ base = PyLong_AsLongAndOverflow(obase, &overflow);
+ if (base == -1 && PyErr_Occurred())
+ return NULL;
+ if (overflow || (base != 0 && base < 2) || base > 36) {
+ PyErr_SetString(PyExc_ValueError,
+ "int() arg 2 must be >= 2 and <= 36");
+ return NULL;
+ }
+
+ if (PyUnicode_Check(x))
return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
PyUnicode_GET_SIZE(x),
- base);
+ (int)base);
else if (PyByteArray_Check(x) || PyBytes_Check(x)) {
/* Since PyLong_FromString doesn't have a length parameter,
* check here for possible NULs in the string. */
@@ -3797,15 +4155,15 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* We only see this if there's a null byte in x,
x is a bytes or buffer, *and* a base is given. */
PyErr_Format(PyExc_ValueError,
- "invalid literal for int() with base %d: %R",
- base, x);
+ "invalid literal for int() with base %d: %R",
+ (int)base, x);
return NULL;
}
- return PyLong_FromString(string, NULL, base);
+ return PyLong_FromString(string, NULL, (int)base);
}
else {
PyErr_SetString(PyExc_TypeError,
- "int() can't convert non-string with explicit base");
+ "int() can't convert non-string with explicit base");
return NULL;
}
}
@@ -3870,140 +4228,169 @@ long__format__(PyObject *self, PyObject *args)
PyUnicode_GET_SIZE(format_spec));
}
-static PyObject *
-long_round(PyObject *self, PyObject *args)
+/* Return a pair (q, r) such that a = b * q + r, and
+ abs(r) <= abs(b)/2, with equality possible only if q is even.
+ In other words, q == a / b, rounded to the nearest integer using
+ round-half-to-even. */
+
+PyObject *
+_PyLong_DivmodNear(PyObject *a, PyObject *b)
{
- PyObject *o_ndigits=NULL, *temp;
- PyLongObject *pow=NULL, *q=NULL, *r=NULL, *ndigits=NULL, *one;
- int errcode;
- digit q_mod_4;
-
- /* Notes on the algorithm: to round to the nearest 10**n (n positive),
- the straightforward method is:
-
- (1) divide by 10**n
- (2) round to nearest integer (round to even in case of tie)
- (3) multiply result by 10**n.
-
- But the rounding step involves examining the fractional part of the
- quotient to see whether it's greater than 0.5 or not. Since we
- want to do the whole calculation in integer arithmetic, it's
- simpler to do:
-
- (1) divide by (10**n)/2
- (2) round to nearest multiple of 2 (multiple of 4 in case of tie)
- (3) multiply result by (10**n)/2.
-
- Then all we need to know about the fractional part of the quotient
- arising in step (2) is whether it's zero or not.
-
- Doing both a multiplication and division is wasteful, and is easily
- avoided if we just figure out how much to adjust the original input
- by to do the rounding.
-
- Here's the whole algorithm expressed in Python.
-
- def round(self, ndigits = None):
- """round(int, int) -> int"""
- if ndigits is None or ndigits >= 0:
- return self
- pow = 10**-ndigits >> 1
- q, r = divmod(self, pow)
- self -= r
- if (q & 1 != 0):
- if (q & 2 == r == 0):
- self -= pow
- else:
- self += pow
- return self
+ PyLongObject *quo = NULL, *rem = NULL;
+ PyObject *one = NULL, *twice_rem, *result, *temp;
+ int cmp, quo_is_odd, quo_is_neg;
+
+ /* Equivalent Python code:
+
+ def divmod_near(a, b):
+ q, r = divmod(a, b)
+ # round up if either r / b > 0.5, or r / b == 0.5 and q is odd.
+ # The expression r / b > 0.5 is equivalent to 2 * r > b if b is
+ # positive, 2 * r < b if b negative.
+ greater_than_half = 2*r > b if b > 0 else 2*r < b
+ exactly_half = 2*r == b
+ if greater_than_half or exactly_half and q % 2 == 1:
+ q += 1
+ r -= b
+ return q, r
*/
+ if (!PyLong_Check(a) || !PyLong_Check(b)) {
+ PyErr_SetString(PyExc_TypeError,
+ "non-integer arguments in division");
+ return NULL;
+ }
+
+ /* Do a and b have different signs? If so, quotient is negative. */
+ quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0);
+
+ one = PyLong_FromLong(1L);
+ if (one == NULL)
+ return NULL;
+
+ if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0)
+ goto error;
+
+ /* compare twice the remainder with the divisor, to see
+ if we need to adjust the quotient and remainder */
+ twice_rem = long_lshift((PyObject *)rem, one);
+ if (twice_rem == NULL)
+ goto error;
+ if (quo_is_neg) {
+ temp = long_neg((PyLongObject*)twice_rem);
+ Py_DECREF(twice_rem);
+ twice_rem = temp;
+ if (twice_rem == NULL)
+ goto error;
+ }
+ cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b);
+ Py_DECREF(twice_rem);
+
+ quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0);
+ if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) {
+ /* fix up quotient */
+ if (quo_is_neg)
+ temp = long_sub(quo, (PyLongObject *)one);
+ else
+ temp = long_add(quo, (PyLongObject *)one);
+ Py_DECREF(quo);
+ quo = (PyLongObject *)temp;
+ if (quo == NULL)
+ goto error;
+ /* and remainder */
+ if (quo_is_neg)
+ temp = long_add(rem, (PyLongObject *)b);
+ else
+ temp = long_sub(rem, (PyLongObject *)b);
+ Py_DECREF(rem);
+ rem = (PyLongObject *)temp;
+ if (rem == NULL)
+ goto error;
+ }
+
+ result = PyTuple_New(2);
+ if (result == NULL)
+ goto error;
+
+ /* PyTuple_SET_ITEM steals references */
+ PyTuple_SET_ITEM(result, 0, (PyObject *)quo);
+ PyTuple_SET_ITEM(result, 1, (PyObject *)rem);
+ Py_DECREF(one);
+ return result;
+
+ error:
+ Py_XDECREF(quo);
+ Py_XDECREF(rem);
+ Py_XDECREF(one);
+ return NULL;
+}
+
+static PyObject *
+long_round(PyObject *self, PyObject *args)
+{
+ PyObject *o_ndigits=NULL, *temp, *result, *ndigits;
+
+ /* To round an integer m to the nearest 10**n (n positive), we make use of
+ * the divmod_near operation, defined by:
+ *
+ * divmod_near(a, b) = (q, r)
+ *
+ * where q is the nearest integer to the quotient a / b (the
+ * nearest even integer in the case of a tie) and r == a - q * b.
+ * Hence q * b = a - r is the nearest multiple of b to a,
+ * preferring even multiples in the case of a tie.
+ *
+ * So the nearest multiple of 10**n to m is:
+ *
+ * m - divmod_near(m, 10**n)[1].
+ */
if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
return NULL;
if (o_ndigits == NULL)
return long_long(self);
- ndigits = (PyLongObject *)PyNumber_Index(o_ndigits);
+ ndigits = PyNumber_Index(o_ndigits);
if (ndigits == NULL)
return NULL;
+ /* if ndigits >= 0 then no rounding is necessary; return self unchanged */
if (Py_SIZE(ndigits) >= 0) {
Py_DECREF(ndigits);
return long_long(self);
}
- Py_INCREF(self); /* to keep refcounting simple */
- /* we now own references to self, ndigits */
-
- /* pow = 10 ** -ndigits >> 1 */
- pow = (PyLongObject *)PyLong_FromLong(10L);
- if (pow == NULL)
- goto error;
- temp = long_neg(ndigits);
+ /* result = self - divmod_near(self, 10 ** -ndigits)[1] */
+ temp = long_neg((PyLongObject*)ndigits);
Py_DECREF(ndigits);
- ndigits = (PyLongObject *)temp;
+ ndigits = temp;
if (ndigits == NULL)
- goto error;
- temp = long_pow((PyObject *)pow, (PyObject *)ndigits, Py_None);
- Py_DECREF(pow);
- pow = (PyLongObject *)temp;
- if (pow == NULL)
- goto error;
- assert(PyLong_Check(pow)); /* check long_pow returned a long */
- one = (PyLongObject *)PyLong_FromLong(1L);
- if (one == NULL)
- goto error;
- temp = long_rshift(pow, one);
- Py_DECREF(one);
- Py_DECREF(pow);
- pow = (PyLongObject *)temp;
- if (pow == NULL)
- goto error;
+ return NULL;
- /* q, r = divmod(self, pow) */
- errcode = l_divmod((PyLongObject *)self, pow, &q, &r);
- if (errcode == -1)
- goto error;
+ result = PyLong_FromLong(10L);
+ if (result == NULL) {
+ Py_DECREF(ndigits);
+ return NULL;
+ }
- /* self -= r */
- temp = long_sub((PyLongObject *)self, r);
- Py_DECREF(self);
- self = temp;
- if (self == NULL)
- goto error;
+ temp = long_pow(result, ndigits, Py_None);
+ Py_DECREF(ndigits);
+ Py_DECREF(result);
+ result = temp;
+ if (result == NULL)
+ return NULL;
- /* get value of quotient modulo 4 */
- if (Py_SIZE(q) == 0)
- q_mod_4 = 0;
- else if (Py_SIZE(q) > 0)
- q_mod_4 = q->ob_digit[0] & 3;
- else
- q_mod_4 = (PyLong_BASE-q->ob_digit[0]) & 3;
+ temp = _PyLong_DivmodNear(self, result);
+ Py_DECREF(result);
+ result = temp;
+ if (result == NULL)
+ return NULL;
- if ((q_mod_4 & 1) == 1) {
- /* q is odd; round self up or down by adding or subtracting pow */
- if (q_mod_4 == 1 && Py_SIZE(r) == 0)
- temp = (PyObject *)long_sub((PyLongObject *)self, pow);
- else
- temp = (PyObject *)long_add((PyLongObject *)self, pow);
- Py_DECREF(self);
- self = temp;
- if (self == NULL)
- goto error;
- }
- Py_DECREF(q);
- Py_DECREF(r);
- Py_DECREF(pow);
- Py_DECREF(ndigits);
- return self;
+ temp = long_sub((PyLongObject *)self,
+ (PyLongObject *)PyTuple_GET_ITEM(result, 1));
+ Py_DECREF(result);
+ result = temp;
- error:
- Py_XDECREF(q);
- Py_XDECREF(r);
- Py_XDECREF(pow);
- Py_XDECREF(self);
- Py_XDECREF(ndigits);
- return NULL;
+ return result;
}
static PyObject *
@@ -4065,7 +4452,7 @@ long_bit_length(PyLongObject *v)
return (PyObject *)result;
-error:
+ error:
Py_DECREF(result);
return NULL;
}
@@ -4087,6 +4474,187 @@ long_is_finite(PyObject *v)
}
#endif
+
+static PyObject *
+long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds)
+{
+ PyObject *byteorder_str;
+ PyObject *is_signed_obj = NULL;
+ Py_ssize_t length;
+ int little_endian;
+ int is_signed;
+ PyObject *bytes;
+ static char *kwlist[] = {"length", "byteorder", "signed", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist,
+ &length, &byteorder_str,
+ &is_signed_obj))
+ return NULL;
+
+ if (args != NULL && Py_SIZE(args) > 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "'signed' is a keyword-only argument");
+ return NULL;
+ }
+
+ if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little"))
+ little_endian = 1;
+ else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big"))
+ little_endian = 0;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "byteorder must be either 'little' or 'big'");
+ return NULL;
+ }
+
+ if (is_signed_obj != NULL) {
+ int cmp = PyObject_IsTrue(is_signed_obj);
+ if (cmp < 0)
+ return NULL;
+ is_signed = cmp ? 1 : 0;
+ }
+ else {
+ /* If the signed argument was omitted, use False as the
+ default. */
+ is_signed = 0;
+ }
+
+ if (length < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "length argument must be non-negative");
+ return NULL;
+ }
+
+ bytes = PyBytes_FromStringAndSize(NULL, length);
+ if (bytes == NULL)
+ return NULL;
+
+ if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes),
+ length, little_endian, is_signed) < 0) {
+ Py_DECREF(bytes);
+ return NULL;
+ }
+
+ return bytes;
+}
+
+PyDoc_STRVAR(long_to_bytes_doc,
+"int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\
+\n\
+Return an array of bytes representing an integer.\n\
+\n\
+The integer is represented using length bytes. An OverflowError is\n\
+raised if the integer is not representable with the given number of\n\
+bytes.\n\
+\n\
+The byteorder argument determines the byte order used to represent the\n\
+integer. If byteorder is 'big', the most significant byte is at the\n\
+beginning of the byte array. If byteorder is 'little', the most\n\
+significant byte is at the end of the byte array. To request the native\n\
+byte order of the host system, use `sys.byteorder' as the byte order value.\n\
+\n\
+The signed keyword-only argument determines whether two's complement is\n\
+used to represent the integer. If signed is False and a negative integer\n\
+is given, an OverflowError is raised.");
+
+static PyObject *
+long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *byteorder_str;
+ PyObject *is_signed_obj = NULL;
+ int little_endian;
+ int is_signed;
+ PyObject *obj;
+ PyObject *bytes;
+ PyObject *long_obj;
+ static char *kwlist[] = {"bytes", "byteorder", "signed", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist,
+ &obj, &byteorder_str,
+ &is_signed_obj))
+ return NULL;
+
+ if (args != NULL && Py_SIZE(args) > 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "'signed' is a keyword-only argument");
+ return NULL;
+ }
+
+ if (!PyUnicode_CompareWithASCIIString(byteorder_str, "little"))
+ little_endian = 1;
+ else if (!PyUnicode_CompareWithASCIIString(byteorder_str, "big"))
+ little_endian = 0;
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "byteorder must be either 'little' or 'big'");
+ return NULL;
+ }
+
+ if (is_signed_obj != NULL) {
+ int cmp = PyObject_IsTrue(is_signed_obj);
+ if (cmp < 0)
+ return NULL;
+ is_signed = cmp ? 1 : 0;
+ }
+ else {
+ /* If the signed argument was omitted, use False as the
+ default. */
+ is_signed = 0;
+ }
+
+ bytes = PyObject_Bytes(obj);
+ if (bytes == NULL)
+ return NULL;
+
+ long_obj = _PyLong_FromByteArray(
+ (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
+ little_endian, is_signed);
+ Py_DECREF(bytes);
+
+ /* If from_bytes() was used on subclass, allocate new subclass
+ * instance, initialize it with decoded long value and return it.
+ */
+ if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) {
+ PyLongObject *newobj;
+ int i;
+ Py_ssize_t n = ABS(Py_SIZE(long_obj));
+
+ newobj = (PyLongObject *)type->tp_alloc(type, n);
+ if (newobj == NULL) {
+ Py_DECREF(long_obj);
+ return NULL;
+ }
+ assert(PyLong_Check(newobj));
+ Py_SIZE(newobj) = Py_SIZE(long_obj);
+ for (i = 0; i < n; i++) {
+ newobj->ob_digit[i] =
+ ((PyLongObject *)long_obj)->ob_digit[i];
+ }
+ Py_DECREF(long_obj);
+ return (PyObject *)newobj;
+ }
+
+ return long_obj;
+}
+
+PyDoc_STRVAR(long_from_bytes_doc,
+"int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\
+\n\
+Return the integer represented by the given array of bytes.\n\
+\n\
+The bytes argument must either support the buffer protocol or be an\n\
+iterable object producing bytes. Bytes and bytearray are examples of\n\
+built-in objects that support the buffer protocol.\n\
+\n\
+The byteorder argument determines the byte order used to represent the\n\
+integer. If byteorder is 'big', the most significant byte is at the\n\
+beginning of the byte array. If byteorder is 'little', the most\n\
+significant byte is at the end of the byte array. To request the native\n\
+byte order of the host system, use `sys.byteorder' as the byte order value.\n\
+\n\
+The signed keyword-only argument indicates whether two's complement is\n\
+used to represent the integer.");
+
static PyMethodDef long_methods[] = {
{"conjugate", (PyCFunction)long_long, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
@@ -4096,6 +4664,10 @@ static PyMethodDef long_methods[] = {
{"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
"Returns always True."},
#endif
+ {"to_bytes", (PyCFunction)long_to_bytes,
+ METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc},
+ {"from_bytes", (PyCFunction)long_from_bytes,
+ METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc},
{"__trunc__", (PyCFunction)long_long, METH_NOARGS,
"Truncating an Integral returns itself."},
{"__floor__", (PyCFunction)long_long, METH_NOARGS,
@@ -4142,40 +4714,40 @@ string, use the optional base. It is an error to supply a base when\n\
converting a non-string.");
static PyNumberMethods long_as_number = {
- (binaryfunc) long_add, /*nb_add*/
- (binaryfunc) long_sub, /*nb_subtract*/
- (binaryfunc) long_mul, /*nb_multiply*/
- long_mod, /*nb_remainder*/
- long_divmod, /*nb_divmod*/
- long_pow, /*nb_power*/
- (unaryfunc) long_neg, /*nb_negative*/
- (unaryfunc) long_long, /*tp_positive*/
- (unaryfunc) long_abs, /*tp_absolute*/
- (inquiry) long_bool, /*tp_bool*/
- (unaryfunc) long_invert, /*nb_invert*/
- long_lshift, /*nb_lshift*/
- (binaryfunc) long_rshift, /*nb_rshift*/
- long_and, /*nb_and*/
- long_xor, /*nb_xor*/
- long_or, /*nb_or*/
- long_long, /*nb_int*/
- 0, /*nb_reserved*/
- long_float, /*nb_float*/
- 0, /* nb_inplace_add */
- 0, /* nb_inplace_subtract */
- 0, /* nb_inplace_multiply */
- 0, /* nb_inplace_remainder */
- 0, /* nb_inplace_power */
- 0, /* nb_inplace_lshift */
- 0, /* nb_inplace_rshift */
- 0, /* nb_inplace_and */
- 0, /* nb_inplace_xor */
- 0, /* nb_inplace_or */
- long_div, /* nb_floor_divide */
- long_true_divide, /* nb_true_divide */
- 0, /* nb_inplace_floor_divide */
- 0, /* nb_inplace_true_divide */
- long_long, /* nb_index */
+ (binaryfunc)long_add, /*nb_add*/
+ (binaryfunc)long_sub, /*nb_subtract*/
+ (binaryfunc)long_mul, /*nb_multiply*/
+ long_mod, /*nb_remainder*/
+ long_divmod, /*nb_divmod*/
+ long_pow, /*nb_power*/
+ (unaryfunc)long_neg, /*nb_negative*/
+ (unaryfunc)long_long, /*tp_positive*/
+ (unaryfunc)long_abs, /*tp_absolute*/
+ (inquiry)long_bool, /*tp_bool*/
+ (unaryfunc)long_invert, /*nb_invert*/
+ long_lshift, /*nb_lshift*/
+ (binaryfunc)long_rshift, /*nb_rshift*/
+ long_and, /*nb_and*/
+ long_xor, /*nb_xor*/
+ long_or, /*nb_or*/
+ long_long, /*nb_int*/
+ 0, /*nb_reserved*/
+ long_float, /*nb_float*/
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ long_div, /* nb_floor_divide */
+ long_true_divide, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+ long_long, /* nb_index */
};
PyTypeObject PyLong_Type = {
@@ -4188,13 +4760,13 @@ PyTypeObject PyLong_Type = {
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
- long_repr, /* tp_repr */
+ long_to_decimal_string, /* tp_repr */
&long_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)long_hash, /* tp_hash */
0, /* tp_call */
- long_repr, /* tp_str */
+ long_to_decimal_string, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
@@ -4231,8 +4803,7 @@ internal representation of integers. The attributes are read only.");
static PyStructSequence_Field int_info_fields[] = {
{"bits_per_digit", "size of a digit in bits"},
- {"sizeof_digit", "size in bytes of the C type used to "
- "represent a digit"},
+ {"sizeof_digit", "size in bytes of the C type used to represent a digit"},
{NULL, NULL}
};
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index 9b77ea7..2e32b2a 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -3,6 +3,23 @@
#include "Python.h"
+#define IS_RELEASED(memobj) \
+ (((PyMemoryViewObject *) memobj)->view.buf == NULL)
+
+#define CHECK_RELEASED(memobj) \
+ if (IS_RELEASED(memobj)) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "operation forbidden on released memoryview object"); \
+ return NULL; \
+ }
+
+#define CHECK_RELEASED_INT(memobj) \
+ if (IS_RELEASED(memobj)) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "operation forbidden on released memoryview object"); \
+ return -1; \
+ }
+
static Py_ssize_t
get_shape0(Py_buffer *buf)
{
@@ -34,6 +51,7 @@ static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
int res = 0;
+ CHECK_RELEASED_INT(self);
if (self->view.obj != NULL)
res = PyObject_GetBuffer(self->view.obj, view, flags);
if (view)
@@ -57,11 +75,15 @@ PyMemoryView_FromBuffer(Py_buffer *info)
{
PyMemoryViewObject *mview;
+ if (info->buf == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "cannot make memory view from a buffer with a NULL data pointer");
+ return NULL;
+ }
mview = (PyMemoryViewObject *)
PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
if (mview == NULL)
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(). */
@@ -91,8 +113,6 @@ PyMemoryView_FromObject(PyObject *base)
return NULL;
}
- mview->base = base;
- Py_INCREF(base);
return (PyObject *)mview;
}
@@ -270,8 +290,6 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
if (PyBuffer_IsContiguous(view, fort)) {
/* no copy needed */
- Py_INCREF(obj);
- mem->base = obj;
_PyObject_GC_TRACK(mem);
return (PyObject *)mem;
}
@@ -303,21 +321,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
Py_DECREF(mem);
return NULL;
}
- }
- if (buffertype == PyBUF_SHADOW) {
- /* return a shadowed memory-view object */
- view->buf = dest;
- mem->base = PyTuple_Pack(2, obj, bytes);
- Py_DECREF(bytes);
- if (mem->base == NULL) {
- Py_DECREF(mem);
- return NULL;
- }
- }
- else {
PyBuffer_Release(view); /* XXX ? */
- /* steal the reference */
- mem->base = bytes;
}
_PyObject_GC_TRACK(mem);
return (PyObject *)mem;
@@ -327,12 +331,14 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
static PyObject *
memory_format_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyUnicode_FromString(self->view.format);
}
static PyObject *
memory_itemsize_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyLong_FromSsize_t(self->view.itemsize);
}
@@ -348,8 +354,9 @@ _IntTupleFromSsizet(int len, Py_ssize_t *vals)
return Py_None;
}
intTuple = PyTuple_New(len);
- if (!intTuple) return NULL;
- for(i=0; i<len; i++) {
+ if (!intTuple)
+ return NULL;
+ for (i=0; i<len; i++) {
o = PyLong_FromSsize_t(vals[i]);
if (!o) {
Py_DECREF(intTuple);
@@ -363,30 +370,35 @@ _IntTupleFromSsizet(int len, Py_ssize_t *vals)
static PyObject *
memory_shape_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}
static PyObject *
memory_strides_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}
static PyObject *
memory_suboffsets_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}
static PyObject *
memory_readonly_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyBool_FromLong(self->view.readonly);
}
static PyObject *
memory_ndim_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyLong_FromLong(self->view.ndim);
}
@@ -405,6 +417,7 @@ static PyGetSetDef memory_getsetlist[] ={
static PyObject *
memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
{
+ CHECK_RELEASED(mem);
return PyObject_CallFunctionObjArgs(
(PyObject *) &PyBytes_Type, mem, NULL);
}
@@ -420,6 +433,7 @@ memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
PyObject *res, *item;
char *buf;
+ CHECK_RELEASED(mem);
if (strcmp(view->format, "B") || view->itemsize != 1) {
PyErr_SetString(PyExc_NotImplementedError,
"tolist() only supports byte views");
@@ -446,9 +460,37 @@ memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
return res;
}
+static void
+do_release(PyMemoryViewObject *self)
+{
+ if (self->view.obj != NULL) {
+ PyBuffer_Release(&(self->view));
+ }
+ self->view.obj = NULL;
+ self->view.buf = NULL;
+}
+
+static PyObject *
+memory_enter(PyObject *self, PyObject *args)
+{
+ CHECK_RELEASED(self);
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *
+memory_exit(PyObject *self, PyObject *args)
+{
+ do_release((PyMemoryViewObject *) self);
+ Py_RETURN_NONE;
+}
+
static PyMethodDef memory_methods[] = {
+ {"release", memory_exit, METH_NOARGS},
{"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
{"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+ {"__enter__", memory_enter, METH_NOARGS},
+ {"__exit__", memory_exit, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
@@ -457,43 +499,24 @@ 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);
- }
+ do_release(self);
PyObject_GC_Del(self);
}
static PyObject *
memory_repr(PyMemoryViewObject *self)
{
- return PyUnicode_FromFormat("<memory at %p>", self);
+ if (IS_RELEASED(self))
+ return PyUnicode_FromFormat("<released memory at %p>", self);
+ else
+ return PyUnicode_FromFormat("<memory at %p>", self);
}
/* Sequence methods */
static Py_ssize_t
memory_length(PyMemoryViewObject *self)
{
+ CHECK_RELEASED_INT(self);
return get_shape0(&self->view);
}
@@ -505,6 +528,7 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t result)
{
Py_buffer *view = &(self->view);
+ CHECK_RELEASED(self);
if (view->ndim == 0) {
PyErr_SetString(PyExc_IndexError,
"invalid indexing of 0-dim memory");
@@ -554,6 +578,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
Py_buffer *view;
view = &(self->view);
+ CHECK_RELEASED(self);
if (view->ndim == 0) {
if (key == Py_Ellipsis ||
(PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
@@ -576,7 +601,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ if (PySlice_GetIndicesEx(key, get_shape0(view),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
}
@@ -623,6 +648,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
Py_buffer *view = &(self->view);
char *srcbuf, *destbuf;
+ CHECK_RELEASED_INT(self);
if (view->readonly) {
PyErr_SetString(PyExc_TypeError,
"cannot modify read-only memory");
@@ -654,7 +680,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
else if (PySlice_Check(key)) {
Py_ssize_t stop, step;
- if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
+ if (PySlice_GetIndicesEx(key, get_shape0(view),
&start, &stop, &step, &len) < 0) {
return -1;
}
@@ -715,6 +741,11 @@ memory_richcompare(PyObject *v, PyObject *w, int op)
ww.obj = NULL;
if (op != Py_EQ && op != Py_NE)
goto _notimpl;
+ if ((PyMemoryView_Check(v) && IS_RELEASED(v)) ||
+ (PyMemoryView_Check(w) && IS_RELEASED(w))) {
+ equal = (v == w);
+ goto _end;
+ }
if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
PyErr_Clear();
goto _notimpl;
@@ -750,8 +781,6 @@ _notimpl:
static int
memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
{
- if (self->base != NULL)
- Py_VISIT(self->base);
if (self->view.obj != NULL)
Py_VISIT(self->view.obj);
return 0;
@@ -760,7 +789,6 @@ memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
static int
memory_clear(PyMemoryViewObject *self)
{
- Py_CLEAR(self->base);
PyBuffer_Release(&self->view);
return 0;
}
@@ -774,10 +802,10 @@ static PyMappingMethods memory_as_mapping = {
};
static PySequenceMethods memory_as_sequence = {
- 0, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (ssizeargfunc)memory_item, /* sq_item */
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)memory_item, /* sq_item */
};
/* Buffer methods */
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 356d161..f1a9f4b 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -224,10 +224,10 @@ meth_richcompare(PyObject *self, PyObject *other, int op)
return res;
}
-static long
+static Py_hash_t
meth_hash(PyCFunctionObject *a)
{
- long x,y;
+ Py_hash_t x, y;
if (a->m_self == NULL)
x = 0;
else {
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index d96d7bd..f31b5da 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -56,10 +56,6 @@ PyModule_New(const char *name)
return NULL;
}
-static char api_version_warning[] =
-"Python C API version mismatch for module %.100s:\
- This Python has API version %d, module %.100s has version %d.";
-
PyObject *
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
{
@@ -79,13 +75,14 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version)
module->m_base.m_index = max_module_number;
}
name = module->m_name;
- if (module_api_version != PYTHON_API_VERSION) {
- char message[512];
- PyOS_snprintf(message, sizeof(message),
- api_version_warning, name,
- PYTHON_API_VERSION, name,
- module_api_version);
- if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1))
+ if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) {
+ int err;
+ err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
+ "Python C API version mismatch for module %.100s: "
+ "This Python has API version %d, module %.100s has version %d.",
+ name,
+ PYTHON_API_VERSION, name, module_api_version);
+ if (err)
return NULL;
}
/* Make sure name is fully qualified.
@@ -192,8 +189,8 @@ PyModule_GetName(PyObject *m)
return _PyUnicode_AsString(nameobj);
}
-const char *
-PyModule_GetFilename(PyObject *m)
+PyObject*
+PyModule_GetFilenameObject(PyObject *m)
{
PyObject *d;
PyObject *fileobj;
@@ -209,7 +206,21 @@ PyModule_GetFilename(PyObject *m)
PyErr_SetString(PyExc_SystemError, "module filename missing");
return NULL;
}
- return _PyUnicode_AsString(fileobj);
+ Py_INCREF(fileobj);
+ return fileobj;
+}
+
+const char *
+PyModule_GetFilename(PyObject *m)
+{
+ PyObject *fileobj;
+ char *utf8;
+ fileobj = PyModule_GetFilenameObject(m);
+ if (fileobj == NULL)
+ return NULL;
+ utf8 = _PyUnicode_AsString(fileobj);
+ Py_DECREF(fileobj);
+ return utf8;
}
PyModuleDef*
@@ -254,10 +265,15 @@ _PyModule_Clear(PyObject *m)
pos = 0;
while (PyDict_Next(d, &pos, &key, &value)) {
if (value != Py_None && PyUnicode_Check(key)) {
- const char *s = _PyUnicode_AsString(key);
- if (s[0] == '_' && s[1] != '_') {
- if (Py_VerboseFlag > 1)
- PySys_WriteStderr("# clear[1] %s\n", s);
+ Py_UNICODE *u = PyUnicode_AS_UNICODE(key);
+ if (u[0] == '_' && u[1] != '_') {
+ if (Py_VerboseFlag > 1) {
+ const char *s = _PyUnicode_AsString(key);
+ if (s != NULL)
+ PySys_WriteStderr("# clear[1] %s\n", s);
+ else
+ PyErr_Clear();
+ }
PyDict_SetItem(d, key, Py_None);
}
}
@@ -267,10 +283,17 @@ _PyModule_Clear(PyObject *m)
pos = 0;
while (PyDict_Next(d, &pos, &key, &value)) {
if (value != Py_None && PyUnicode_Check(key)) {
- const char *s = _PyUnicode_AsString(key);
- if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
- if (Py_VerboseFlag > 1)
- PySys_WriteStderr("# clear[2] %s\n", s);
+ Py_UNICODE *u = PyUnicode_AS_UNICODE(key);
+ if (u[0] != '_'
+ || PyUnicode_CompareWithASCIIString(key, "__builtins__") != 0)
+ {
+ if (Py_VerboseFlag > 1) {
+ const char *s = _PyUnicode_AsString(key);
+ if (s != NULL)
+ PySys_WriteStderr("# clear[2] %s\n", s);
+ else
+ PyErr_Clear();
+ }
PyDict_SetItem(d, key, Py_None);
}
}
@@ -325,19 +348,21 @@ static PyObject *
module_repr(PyModuleObject *m)
{
const char *name;
- const char *filename;
+ PyObject *filename, *repr;
name = PyModule_GetName((PyObject *)m);
if (name == NULL) {
PyErr_Clear();
name = "?";
}
- filename = PyModule_GetFilename((PyObject *)m);
+ filename = PyModule_GetFilenameObject((PyObject *)m);
if (filename == NULL) {
PyErr_Clear();
return PyUnicode_FromFormat("<module '%s' (built-in)>", name);
}
- return PyUnicode_FromFormat("<module '%s' from '%s'>", name, filename);
+ repr = PyUnicode_FromFormat("<module '%s' from '%U'>", name, filename);
+ Py_DECREF(filename);
+ return repr;
}
static int
diff --git a/Objects/object.c b/Objects/object.c
index ac57cd7..a91c46a 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2,7 +2,6 @@
/* Generic object operations; and implementation of None (NoObject) */
#include "Python.h"
-#include "sliceobject.h" /* For PyEllipsis_Type */
#include "frameobject.h"
#ifdef __cplusplus
@@ -536,10 +535,12 @@ do_richcompare(PyObject *v, PyObject *w, int op)
{
richcmpfunc f;
PyObject *res;
+ int checked_reverse_op = 0;
if (v->ob_type != w->ob_type &&
PyType_IsSubtype(w->ob_type, v->ob_type) &&
(f = w->ob_type->tp_richcompare) != NULL) {
+ checked_reverse_op = 1;
res = (*f)(w, v, _Py_SwappedOp[op]);
if (res != Py_NotImplemented)
return res;
@@ -551,7 +552,7 @@ do_richcompare(PyObject *v, PyObject *w, int op)
return res;
Py_DECREF(res);
}
- if ((f = w->ob_type->tp_richcompare) != NULL) {
+ if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) {
res = (*f)(w, v, _Py_SwappedOp[op]);
if (res != Py_NotImplemented)
return res;
@@ -634,77 +635,118 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
All the utility functions (_Py_Hash*()) return "-1" to signify an error.
*/
-long
+/* For numeric types, the hash of a number x is based on the reduction
+ of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that
+ hash(x) == hash(y) whenever x and y are numerically equal, even if
+ x and y have different types.
+
+ A quick summary of the hashing strategy:
+
+ (1) First define the 'reduction of x modulo P' for any rational
+ number x; this is a standard extension of the usual notion of
+ reduction modulo P for integers. If x == p/q (written in lowest
+ terms), the reduction is interpreted as the reduction of p times
+ the inverse of the reduction of q, all modulo P; if q is exactly
+ divisible by P then define the reduction to be infinity. So we've
+ got a well-defined map
+
+ reduce : { rational numbers } -> { 0, 1, 2, ..., P-1, infinity }.
+
+ (2) Now for a rational number x, define hash(x) by:
+
+ reduce(x) if x >= 0
+ -reduce(-x) if x < 0
+
+ If the result of the reduction is infinity (this is impossible for
+ integers, floats and Decimals) then use the predefined hash value
+ _PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead.
+ _PyHASH_INF, -_PyHASH_INF and _PyHASH_NAN are also used for the
+ hashes of float and Decimal infinities and nans.
+
+ A selling point for the above strategy is that it makes it possible
+ to compute hashes of decimal and binary floating-point numbers
+ efficiently, even if the exponent of the binary or decimal number
+ is large. The key point is that
+
+ reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS)
+
+ provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a
+ binary or decimal float is never infinity, since the denominator is a power
+ of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have,
+ for nonnegative x,
+
+ reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS
+
+ reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS
+
+ and reduce(10**e) can be computed efficiently by the usual modular
+ exponentiation algorithm. For reduce(2**e) it's even better: since
+ P is of the form 2**n-1, reduce(2**e) is 2**(e mod n), and multiplication
+ by 2**(e mod n) modulo 2**n-1 just amounts to a rotation of bits.
+
+ */
+
+Py_hash_t
_Py_HashDouble(double v)
{
- double intpart, fractpart;
- int expo;
- long hipart;
- long x; /* the final hash value */
- /* This is designed so that Python numbers of different types
- * that compare equal hash to the same value; otherwise comparisons
- * of mapping keys will turn out weird.
- */
+ int e, sign;
+ double m;
+ Py_uhash_t x, y;
- 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;
- x = PyObject_Hash(plong);
- Py_DECREF(plong);
- return x;
- }
- /* Fits in a C long == a Python int, so is its own hash. */
- x = (long)intpart;
- if (x == -1)
- x = -2;
- return x;
- }
- /* The fractional part is non-zero, so we don't have to worry about
- * making this match the hash of some other type.
- * Use frexp to get at the bits in the double.
- * Since the VAX D double format has 56 mantissa bits, which is the
- * most of any double format in use, each of these parts may have as
- * many as (but no more than) 56 significant bits.
- * So, assuming sizeof(long) >= 4, each part can be broken into two
- * longs; frexp and multiplication are used to do that.
- * Also, since the Cray double format has 15 exponent bits, which is
- * the most of any double format in use, shifting the exponent field
- * left by 15 won't overflow a long (again assuming sizeof(long) >= 4).
- */
- v = frexp(v, &expo);
- v *= 2147483648.0; /* 2**31 */
- hipart = (long)v; /* take the top 32 bits */
- v = (v - (double)hipart) * 2147483648.0; /* get the next 32 bits */
- x = hipart + (long)v + (expo << 15);
- if (x == -1)
- x = -2;
- return x;
+ if (!Py_IS_FINITE(v)) {
+ if (Py_IS_INFINITY(v))
+ return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
+ else
+ return _PyHASH_NAN;
+ }
+
+ m = frexp(v, &e);
+
+ sign = 1;
+ if (m < 0) {
+ sign = -1;
+ m = -m;
+ }
+
+ /* process 28 bits at a time; this should work well both for binary
+ and hexadecimal floating point. */
+ x = 0;
+ while (m) {
+ x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28);
+ m *= 268435456.0; /* 2**28 */
+ e -= 28;
+ y = (Py_uhash_t)m; /* pull out integer part */
+ m -= y;
+ x += y;
+ if (x >= _PyHASH_MODULUS)
+ x -= _PyHASH_MODULUS;
+ }
+
+ /* adjust for the exponent; first reduce it modulo _PyHASH_BITS */
+ e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS);
+ x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e);
+
+ x = x * sign;
+ if (x == (Py_uhash_t)-1)
+ x = (Py_uhash_t)-2;
+ return (Py_hash_t)x;
}
-long
+Py_hash_t
_Py_HashPointer(void *p)
{
- long x;
+ Py_hash_t x;
size_t y = (size_t)p;
/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
excessive hash collisions for dicts and sets */
y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
- x = (long)y;
+ x = (Py_hash_t)y;
if (x == -1)
x = -2;
return x;
}
-long
+Py_hash_t
PyObject_HashNotImplemented(PyObject *v)
{
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
@@ -712,7 +754,7 @@ PyObject_HashNotImplemented(PyObject *v)
return -1;
}
-long
+Py_hash_t
PyObject_Hash(PyObject *v)
{
PyTypeObject *tp = Py_TYPE(v);
@@ -934,31 +976,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
goto done;
}
-#if 0 /* XXX this is not quite _PyType_Lookup anymore */
- /* Inline _PyType_Lookup */
- {
- Py_ssize_t i, n;
- PyObject *mro, *base, *dict;
-
- /* Look in tp_dict of types in MRO */
- mro = tp->tp_mro;
- assert(mro != NULL);
- assert(PyTuple_Check(mro));
- n = PyTuple_GET_SIZE(mro);
- for (i = 0; i < n; i++) {
- base = PyTuple_GET_ITEM(mro, i);
- assert(PyType_Check(base));
- dict = ((PyTypeObject *)base)->tp_dict;
- assert(dict && PyDict_Check(dict));
- descr = PyDict_GetItem(dict, name);
- if (descr != NULL)
- break;
- }
- }
-#else
descr = _PyType_Lookup(tp, name);
-#endif
-
Py_XINCREF(descr);
f = NULL;
@@ -1553,10 +1571,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyStaticMethod_Type) < 0)
Py_FatalError("Can't initialize static method type");
-#ifndef WITHOUT_COMPLEX
if (PyType_Ready(&PyComplex_Type) < 0)
Py_FatalError("Can't initialize complex type");
-#endif
+
if (PyType_Ready(&PyFloat_Type) < 0)
Py_FatalError("Can't initialize float type");
@@ -1739,10 +1756,6 @@ _Py_GetObjects(PyObject *self, PyObject *args)
#endif
-/* Hack to force loading of cobject.o */
-PyTypeObject *_Py_cobject_hack = &PyCObject_Type;
-
-
/* Hack to force loading of pycapsule.o */
PyTypeObject *_PyCapsule_hack = &PyCapsule_Type;
@@ -1887,6 +1900,19 @@ _PyTrash_destroy_chain(void)
}
}
+#ifndef Py_TRACE_REFS
+/* For Py_LIMITED_API, we need an out-of-line version of _Py_Dealloc.
+ Define this here, so we can undefine the macro. */
+#undef _Py_Dealloc
+PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
+void
+_Py_Dealloc(PyObject *op)
+{
+ _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA
+ (*Py_TYPE(op)->tp_dealloc)(op);
+}
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index af12f41..3916262 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,
@@ -736,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
@@ -938,6 +960,11 @@ PyObject_Free(void *p)
if (p == NULL) /* free(NULL) has no effect */
return;
+#ifdef WITH_VALGRIND
+ if (UNLIKELY(running_on_valgrind > 0))
+ goto redirect;
+#endif
+
pool = POOL_ADDR(p);
if (Py_ADDRESS_IN_RANGE(p, pool)) {
/* We allocated this address. */
@@ -1132,6 +1159,9 @@ PyObject_Free(void *p)
return;
}
+#ifdef WITH_VALGRIND
+redirect:
+#endif
/* We didn't allocate this address. */
free(p);
}
@@ -1164,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 */
@@ -1191,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
@@ -1255,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
@@ -1345,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 */
@@ -1362,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);
@@ -1376,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;
@@ -1405,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;
@@ -1417,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;
@@ -1445,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;
@@ -1496,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;
@@ -1519,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)
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 33a4d9d..58d373c 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -14,6 +14,7 @@ typedef struct {
PyObject *start;
PyObject *stop;
PyObject *step;
+ PyObject *length;
} rangeobject;
/* Helper function for validating step. Always returns a new reference or
@@ -43,6 +44,31 @@ validate_step(PyObject *step)
return step;
}
+static PyObject *
+compute_range_length(PyObject *start, PyObject *stop, PyObject *step);
+
+static rangeobject *
+make_range_object(PyTypeObject *type, PyObject *start,
+ PyObject *stop, PyObject *step)
+{
+ rangeobject *obj = NULL;
+ PyObject *length;
+ length = compute_range_length(start, stop, step);
+ if (length == NULL) {
+ return NULL;
+ }
+ obj = PyObject_New(rangeobject, type);
+ if (obj == NULL) {
+ Py_DECREF(length);
+ return NULL;
+ }
+ obj->start = start;
+ obj->stop = stop;
+ obj->step = step;
+ obj->length = length;
+ return obj;
+}
+
/* XXX(nnorwitz): should we error check if the user passes any empty ranges?
range(-10)
range(0, -5)
@@ -51,7 +77,7 @@ validate_step(PyObject *step)
static PyObject *
range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
- rangeobject *obj = NULL;
+ rangeobject *obj;
PyObject *start = NULL, *stop = NULL, *step = NULL;
if (!_PyArg_NoKeywords("range()", kw))
@@ -97,15 +123,11 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
}
- obj = PyObject_New(rangeobject, &PyRange_Type);
- if (obj == NULL)
- goto Fail;
- obj->start = start;
- obj->stop = stop;
- obj->step = step;
- return (PyObject *) obj;
+ obj = make_range_object(type, start, stop, step);
+ if (obj != NULL)
+ return (PyObject *) obj;
-Fail:
+ /* Failed to create object, release attributes */
Py_XDECREF(start);
Py_XDECREF(stop);
Py_XDECREF(step);
@@ -115,7 +137,7 @@ Fail:
PyDoc_STRVAR(range_doc,
"range([start,] stop[, step]) -> range object\n\
\n\
-Returns an iterator that generates the numbers in the range on demand.");
+Returns a virtual sequence of numbers from start to stop by step.");
static void
range_dealloc(rangeobject *r)
@@ -123,6 +145,7 @@ range_dealloc(rangeobject *r)
Py_DECREF(r->start);
Py_DECREF(r->stop);
Py_DECREF(r->step);
+ Py_DECREF(r->length);
PyObject_Del(r);
}
@@ -131,7 +154,7 @@ range_dealloc(rangeobject *r)
* PyLong_Check(). Return NULL when there is an error.
*/
static PyObject*
-range_length_obj(rangeobject *r)
+compute_range_length(PyObject *start, PyObject *stop, PyObject *step)
{
/* -------------------------------------------------------------
Algorithm is equal to that of get_len_of_range(), but it operates
@@ -139,7 +162,6 @@ range_length_obj(rangeobject *r)
---------------------------------------------------------------*/
int cmp_result;
PyObject *lo, *hi;
- PyObject *step = NULL;
PyObject *diff = NULL;
PyObject *one = NULL;
PyObject *tmp1 = NULL, *tmp2 = NULL, *result;
@@ -148,20 +170,19 @@ range_length_obj(rangeobject *r)
PyObject *zero = PyLong_FromLong(0);
if (zero == NULL)
return NULL;
- cmp_result = PyObject_RichCompareBool(r->step, zero, Py_GT);
+ cmp_result = PyObject_RichCompareBool(step, zero, Py_GT);
Py_DECREF(zero);
if (cmp_result == -1)
return NULL;
if (cmp_result == 1) {
- lo = r->start;
- hi = r->stop;
- step = r->step;
+ lo = start;
+ hi = stop;
Py_INCREF(step);
} else {
- lo = r->stop;
- hi = r->start;
- step = PyNumber_Negative(r->step);
+ lo = stop;
+ hi = start;
+ step = PyNumber_Negative(step);
if (!step)
return NULL;
}
@@ -206,45 +227,451 @@ range_length_obj(rangeobject *r)
static Py_ssize_t
range_length(rangeobject *r)
{
- PyObject *len = range_length_obj(r);
- Py_ssize_t result = -1;
- if (len) {
- result = PyLong_AsSsize_t(len);
- Py_DECREF(len);
- }
- return result;
+ return PyLong_AsSsize_t(r->length);
}
-/* range(...)[x] is necessary for: seq[:] = range(...) */
+static PyObject *
+compute_item(rangeobject *r, PyObject *i)
+{
+ PyObject *incr, *result;
+ /* PyLong equivalent to:
+ * return r->start + (i * r->step)
+ */
+ incr = PyNumber_Multiply(i, r->step);
+ if (!incr)
+ return NULL;
+ result = PyNumber_Add(r->start, incr);
+ Py_DECREF(incr);
+ return result;
+}
static PyObject *
-range_item(rangeobject *r, Py_ssize_t i)
+compute_range_item(rangeobject *r, PyObject *arg)
{
- Py_ssize_t len = range_length(r);
- PyObject *rem, *incr, *result;
-
- /* XXX(nnorwitz): should negative indices be supported? */
- /* XXX(nnorwitz): should support range[x] where x > PY_SSIZE_T_MAX? */
- if (i < 0 || i >= len) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_IndexError,
- "range object index out of range");
+ int cmp_result;
+ PyObject *i, *result;
+
+ PyObject *zero = PyLong_FromLong(0);
+ if (zero == NULL)
return NULL;
+
+ /* PyLong equivalent to:
+ * if (arg < 0) {
+ * i = r->length + arg
+ * } else {
+ * i = arg
+ * }
+ */
+ cmp_result = PyObject_RichCompareBool(arg, zero, Py_LT);
+ if (cmp_result == -1) {
+ Py_DECREF(zero);
+ return NULL;
+ }
+ if (cmp_result == 1) {
+ i = PyNumber_Add(r->length, arg);
+ if (!i) {
+ Py_DECREF(zero);
+ return NULL;
+ }
+ } else {
+ i = arg;
+ Py_INCREF(i);
}
- /* XXX(nnorwitz): optimize for short ints. */
- rem = PyLong_FromSsize_t(i);
- if (!rem)
+ /* PyLong equivalent to:
+ * if (i < 0 || i >= r->length) {
+ * <report index out of bounds>
+ * }
+ */
+ cmp_result = PyObject_RichCompareBool(i, zero, Py_LT);
+ Py_DECREF(zero);
+ if (cmp_result == 0) {
+ cmp_result = PyObject_RichCompareBool(i, r->length, Py_GE);
+ }
+ if (cmp_result == -1) {
+ Py_DECREF(i);
+ return NULL;
+ }
+ if (cmp_result == 1) {
+ Py_DECREF(i);
+ PyErr_SetString(PyExc_IndexError,
+ "range object index out of range");
return NULL;
- incr = PyNumber_Multiply(rem, r->step);
- Py_DECREF(rem);
- if (!incr)
+ }
+
+ result = compute_item(r, i);
+ Py_DECREF(i);
+ return result;
+}
+
+static PyObject *
+range_item(rangeobject *r, Py_ssize_t i)
+{
+ PyObject *res, *arg = PyLong_FromLong(i);
+ if (!arg) {
return NULL;
- result = PyNumber_Add(r->start, incr);
- Py_DECREF(incr);
+ }
+ res = compute_range_item(r, arg);
+ Py_DECREF(arg);
+ return res;
+}
+
+/* Additional helpers, since the standard slice helpers
+ * all clip to PY_SSIZE_T_MAX
+ */
+
+/* Replace _PyEval_SliceIndex */
+static PyObject *
+compute_slice_element(PyObject *obj)
+{
+ PyObject *result = NULL;
+ if (obj != NULL) {
+ if (PyIndex_Check(obj)) {
+ result = PyNumber_Index(obj);
+ }
+ }
+ if (result == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "slice indices must be integers or "
+ "None or have an __index__ method");
+ }
return result;
}
+/* Replace PySlice_GetIndicesEx
+ * Result indicates whether or not the slice is empty
+ * (-1 = error, 0 = empty slice, 1 = slice contains elements)
+ */
+static int
+compute_slice_indices(rangeobject *r, PySliceObject *slice,
+ PyObject **start, PyObject **stop, PyObject **step)
+{
+ int cmp_result, has_elements;
+ Py_ssize_t clamped_step = 0;
+ PyObject *zero = NULL, *one = NULL, *neg_one = NULL, *candidate = NULL;
+ PyObject *tmp_start = NULL, *tmp_stop = NULL, *tmp_step = NULL;
+ zero = PyLong_FromLong(0);
+ if (zero == NULL) goto Fail;
+ one = PyLong_FromLong(1);
+ if (one == NULL) goto Fail;
+ neg_one = PyLong_FromLong(-1);
+ if (neg_one == NULL) goto Fail;
+
+ /* Calculate step value */
+ if (slice->step == Py_None) {
+ clamped_step = 1;
+ tmp_step = one;
+ Py_INCREF(tmp_step);
+ } else {
+ if (!_PyEval_SliceIndex(slice->step, &clamped_step)) goto Fail;
+ if (clamped_step == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "slice step cannot be zero");
+ goto Fail;
+ }
+ tmp_step = compute_slice_element(slice->step);
+ if (tmp_step == NULL) goto Fail;
+ }
+
+ /* Calculate start value */
+ if (slice->start == Py_None) {
+ if (clamped_step < 0) {
+ tmp_start = PyNumber_Subtract(r->length, one);
+ if (tmp_start == NULL) goto Fail;
+ } else {
+ tmp_start = zero;
+ Py_INCREF(tmp_start);
+ }
+ } else {
+ candidate = compute_slice_element(slice->start);
+ if (candidate == NULL) goto Fail;
+ cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* candidate < 0 */
+ tmp_start = PyNumber_Add(r->length, candidate);
+ if (tmp_start == NULL) goto Fail;
+ Py_CLEAR(candidate);
+ } else {
+ /* candidate >= 0 */
+ tmp_start = candidate;
+ candidate = NULL;
+ }
+ cmp_result = PyObject_RichCompareBool(tmp_start, zero, Py_LT);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* tmp_start < 0 */
+ Py_CLEAR(tmp_start);
+ if (clamped_step < 0) {
+ tmp_start = neg_one;
+ } else {
+ tmp_start = zero;
+ }
+ Py_INCREF(tmp_start);
+ } else {
+ /* tmp_start >= 0 */
+ cmp_result = PyObject_RichCompareBool(tmp_start, r->length, Py_GE);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* tmp_start >= r->length */
+ Py_CLEAR(tmp_start);
+ if (clamped_step < 0) {
+ tmp_start = PyNumber_Subtract(r->length, one);
+ if (tmp_start == NULL) goto Fail;
+ } else {
+ tmp_start = r->length;
+ Py_INCREF(tmp_start);
+ }
+ }
+ }
+ }
+
+ /* Calculate stop value */
+ if (slice->stop == Py_None) {
+ if (clamped_step < 0) {
+ tmp_stop = neg_one;
+ } else {
+ tmp_stop = r->length;
+ }
+ Py_INCREF(tmp_stop);
+ } else {
+ candidate = compute_slice_element(slice->stop);
+ if (candidate == NULL) goto Fail;
+ cmp_result = PyObject_RichCompareBool(candidate, zero, Py_LT);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* candidate < 0 */
+ tmp_stop = PyNumber_Add(r->length, candidate);
+ if (tmp_stop == NULL) goto Fail;
+ Py_CLEAR(candidate);
+ } else {
+ /* candidate >= 0 */
+ tmp_stop = candidate;
+ candidate = NULL;
+ }
+ cmp_result = PyObject_RichCompareBool(tmp_stop, zero, Py_LT);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* tmp_stop < 0 */
+ Py_CLEAR(tmp_stop);
+ if (clamped_step < 0) {
+ tmp_stop = neg_one;
+ } else {
+ tmp_stop = zero;
+ }
+ Py_INCREF(tmp_stop);
+ } else {
+ /* tmp_stop >= 0 */
+ cmp_result = PyObject_RichCompareBool(tmp_stop, r->length, Py_GE);
+ if (cmp_result == -1) goto Fail;
+ if (cmp_result) {
+ /* tmp_stop >= r->length */
+ Py_CLEAR(tmp_stop);
+ if (clamped_step < 0) {
+ tmp_stop = PyNumber_Subtract(r->length, one);
+ if (tmp_stop == NULL) goto Fail;
+ } else {
+ tmp_stop = r->length;
+ Py_INCREF(tmp_stop);
+ }
+ }
+ }
+ }
+
+ /* Check if the slice is empty or not */
+ if (clamped_step < 0) {
+ has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_GT);
+ } else {
+ has_elements = PyObject_RichCompareBool(tmp_start, tmp_stop, Py_LT);
+ }
+ if (has_elements == -1) goto Fail;
+
+ *start = tmp_start;
+ *stop = tmp_stop;
+ *step = tmp_step;
+ Py_DECREF(neg_one);
+ Py_DECREF(one);
+ Py_DECREF(zero);
+ return has_elements;
+
+ Fail:
+ Py_XDECREF(tmp_start);
+ Py_XDECREF(tmp_stop);
+ Py_XDECREF(tmp_step);
+ Py_XDECREF(candidate);
+ Py_XDECREF(neg_one);
+ Py_XDECREF(one);
+ Py_XDECREF(zero);
+ return -1;
+}
+
+static PyObject *
+compute_slice(rangeobject *r, PyObject *_slice)
+{
+ PySliceObject *slice = (PySliceObject *) _slice;
+ rangeobject *result;
+ PyObject *start = NULL, *stop = NULL, *step = NULL;
+ PyObject *substart = NULL, *substop = NULL, *substep = NULL;
+ int has_elements;
+
+ has_elements = compute_slice_indices(r, slice, &start, &stop, &step);
+ if (has_elements == -1) return NULL;
+
+ substep = PyNumber_Multiply(r->step, step);
+ if (substep == NULL) goto fail;
+ Py_CLEAR(step);
+
+ substart = compute_item(r, start);
+ if (substart == NULL) goto fail;
+ Py_CLEAR(start);
+
+ if (has_elements) {
+ substop = compute_item(r, stop);
+ if (substop == NULL) goto fail;
+ } else {
+ substop = substart;
+ Py_INCREF(substop);
+ }
+ Py_CLEAR(stop);
+
+ result = make_range_object(Py_TYPE(r), substart, substop, substep);
+ if (result != NULL) {
+ return (PyObject *) result;
+ }
+fail:
+ Py_XDECREF(start);
+ Py_XDECREF(stop);
+ Py_XDECREF(step);
+ Py_XDECREF(substart);
+ Py_XDECREF(substop);
+ Py_XDECREF(substep);
+ return NULL;
+}
+
+/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
+static int
+range_contains_long(rangeobject *r, PyObject *ob)
+{
+ int cmp1, cmp2, cmp3;
+ PyObject *tmp1 = NULL;
+ PyObject *tmp2 = NULL;
+ PyObject *zero = NULL;
+ int result = -1;
+
+ zero = PyLong_FromLong(0);
+ if (zero == NULL) /* MemoryError in int(0) */
+ goto end;
+
+ /* Check if the value can possibly be in the range. */
+
+ cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
+ if (cmp1 == -1)
+ goto end;
+ if (cmp1 == 1) { /* positive steps: start <= ob < stop */
+ cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
+ cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
+ }
+ else { /* negative steps: stop < ob <= start */
+ cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
+ cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
+ }
+
+ if (cmp2 == -1 || cmp3 == -1) /* TypeError */
+ goto end;
+ if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
+ result = 0;
+ goto end;
+ }
+
+ /* Check that the stride does not invalidate ob's membership. */
+ tmp1 = PyNumber_Subtract(ob, r->start);
+ if (tmp1 == NULL)
+ goto end;
+ tmp2 = PyNumber_Remainder(tmp1, r->step);
+ if (tmp2 == NULL)
+ goto end;
+ /* result = (int(ob) - start % step) == 0 */
+ result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
+ end:
+ Py_XDECREF(tmp1);
+ Py_XDECREF(tmp2);
+ Py_XDECREF(zero);
+ return result;
+}
+
+static int
+range_contains(rangeobject *r, PyObject *ob)
+{
+ if (PyLong_CheckExact(ob) || PyBool_Check(ob))
+ return range_contains_long(r, ob);
+
+ return (int)_PySequence_IterSearch((PyObject*)r, ob,
+ PY_ITERSEARCH_CONTAINS);
+}
+
+static PyObject *
+range_count(rangeobject *r, PyObject *ob)
+{
+ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
+ int result = range_contains_long(r, ob);
+ if (result == -1)
+ return NULL;
+ else if (result)
+ return PyLong_FromLong(1);
+ else
+ return PyLong_FromLong(0);
+ } else {
+ Py_ssize_t count;
+ count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
+ if (count == -1)
+ return NULL;
+ return PyLong_FromSsize_t(count);
+ }
+}
+
+static PyObject *
+range_index(rangeobject *r, PyObject *ob)
+{
+ int contains;
+
+ if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
+ Py_ssize_t index;
+ index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
+ if (index == -1)
+ return NULL;
+ return PyLong_FromSsize_t(index);
+ }
+
+ contains = range_contains_long(r, ob);
+ if (contains == -1)
+ return NULL;
+
+ if (contains) {
+ PyObject *idx, *tmp = PyNumber_Subtract(ob, r->start);
+ if (tmp == NULL)
+ return NULL;
+ /* idx = (ob - r.start) // r.step */
+ idx = PyNumber_FloorDivide(tmp, r->step);
+ Py_DECREF(tmp);
+ return idx;
+ }
+
+ /* object is not in the range */
+ PyErr_Format(PyExc_ValueError, "%R is not in range", ob);
+ return NULL;
+}
+
+static PySequenceMethods range_as_sequence = {
+ (lenfunc)range_length, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)range_item, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)range_contains, /* sq_contains */
+};
+
static PyObject *
range_repr(rangeobject *r)
{
@@ -269,16 +696,36 @@ range_repr(rangeobject *r)
static PyObject *
range_reduce(rangeobject *r, PyObject *args)
{
- return Py_BuildValue("(O(OOO))", Py_TYPE(r),
+ return Py_BuildValue("(O(OOO))", Py_TYPE(r),
r->start, r->stop, r->step);
}
-static PySequenceMethods range_as_sequence = {
- (lenfunc)range_length, /* sq_length */
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (ssizeargfunc)range_item, /* sq_item */
- 0, /* sq_slice */
+static PyObject *
+range_subscript(rangeobject* self, PyObject* item)
+{
+ if (PyIndex_Check(item)) {
+ PyObject *i, *result;
+ i = PyNumber_Index(item);
+ if (!i)
+ return NULL;
+ result = compute_range_item(self, i);
+ Py_DECREF(i);
+ return result;
+ }
+ if (PySlice_Check(item)) {
+ return compute_slice(self, item);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "range indices must be integers or slices, not %.200s",
+ item->ob_type->tp_name);
+ return NULL;
+}
+
+
+static PyMappingMethods range_as_mapping = {
+ (lenfunc)range_length, /* mp_length */
+ (binaryfunc)range_subscript, /* mp_subscript */
+ (objobjargproc)0, /* mp_ass_subscript */
};
static PyObject * range_iter(PyObject *seq);
@@ -287,10 +734,18 @@ static PyObject * range_reverse(PyObject *seq);
PyDoc_STRVAR(reverse_doc,
"Returns a reverse iterator.");
+PyDoc_STRVAR(count_doc,
+"rangeobject.count(value) -> integer -- return number of occurrences of value");
+
+PyDoc_STRVAR(index_doc,
+"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n"
+"Raises ValueError if the value is not present.");
+
static PyMethodDef range_methods[] = {
- {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
- reverse_doc},
- {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
+ {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+ {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
+ {"count", (PyCFunction)range_count, METH_O, count_doc},
+ {"index", (PyCFunction)range_index, METH_O, index_doc},
{NULL, NULL} /* sentinel */
};
@@ -307,7 +762,7 @@ PyTypeObject PyRange_Type = {
(reprfunc)range_repr, /* tp_repr */
0, /* tp_as_number */
&range_as_sequence, /* tp_as_sequence */
- 0, /* tp_as_mapping */
+ &range_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
@@ -367,22 +822,6 @@ rangeiter_len(rangeiterobject *r)
return PyLong_FromLong(r->len - r->index);
}
-typedef struct {
- PyObject_HEAD
- PyObject *index;
- PyObject *start;
- PyObject *step;
- PyObject *len;
-} longrangeiterobject;
-
-static PyObject *
-longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
-{
- return PyNumber_Subtract(r->len, r->index);
-}
-
-static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
-
PyDoc_STRVAR(length_hint_doc,
"Private method returning an estimate of len(list(it)).");
@@ -392,6 +831,8 @@ static PyMethodDef rangeiter_methods[] = {
{NULL, NULL} /* sentinel */
};
+static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw);
+
PyTypeObject PyRangeIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"range_iterator", /* tp_name */
@@ -466,7 +907,7 @@ get_len_of_range(long lo, long hi, long step)
is not representable as a C long, OverflowError is raised. */
static PyObject *
-int_range_iter(long start, long stop, long step)
+fast_range_iter(long start, long stop, long step)
{
rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type);
unsigned long ulen;
@@ -498,7 +939,21 @@ rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw)
&start, &stop, &step))
return NULL;
- return int_range_iter(start, stop, step);
+ return fast_range_iter(start, stop, step);
+}
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *index;
+ PyObject *start;
+ PyObject *step;
+ PyObject *len;
+} longrangeiterobject;
+
+static PyObject *
+longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
+{
+ return PyNumber_Subtract(r->len, r->index);
}
static PyMethodDef longrangeiter_methods[] = {
@@ -612,7 +1067,7 @@ range_iter(PyObject *seq)
PyErr_Clear();
goto long_range;
}
- int_it = int_range_iter(lstart, lstop, lstep);
+ int_it = fast_range_iter(lstart, lstop, lstep);
if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) {
PyErr_Clear();
goto long_range;
@@ -627,14 +1082,11 @@ range_iter(PyObject *seq)
/* Do all initialization here, so we can DECREF on failure. */
it->start = r->start;
it->step = r->step;
+ it->len = r->length;
Py_INCREF(it->start);
Py_INCREF(it->step);
+ Py_INCREF(it->len);
- it->len = it->index = NULL;
-
- it->len = range_length_obj(r);
- if (!it->len)
- goto create_failure;
it->index = PyLong_FromLong(0);
if (!it->index)
goto create_failure;
@@ -651,7 +1103,7 @@ range_reverse(PyObject *seq)
{
rangeobject *range = (rangeobject*) seq;
longrangeiterobject *it;
- PyObject *one, *sum, *diff, *len = NULL, *product;
+ PyObject *one, *sum, *diff, *product;
long lstart, lstop, lstep, new_start, new_stop;
unsigned long ulen;
@@ -714,7 +1166,7 @@ range_reverse(PyObject *seq)
new_stop = lstart - lstep;
new_start = (long)(new_stop + ulen * lstep);
- return int_range_iter(new_start, new_stop, -lstep);
+ return fast_range_iter(new_start, new_stop, -lstep);
long_range:
it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
@@ -722,18 +1174,14 @@ long_range:
return NULL;
/* start + (len - 1) * step */
- len = range_length_obj(range);
- if (!len)
- goto create_failure;
-
- /* Steal reference to len. */
- it->len = len;
+ it->len = range->length;
+ Py_INCREF(it->len);
one = PyLong_FromLong(1);
if (!one)
goto create_failure;
- diff = PyNumber_Subtract(len, one);
+ diff = PyNumber_Subtract(it->len, one);
Py_DECREF(one);
if (!diff)
goto create_failure;
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 7aa1a7f..48edad8 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -75,7 +75,7 @@ NULL if the rich comparison returns an error.
*/
static setentry *
-set_lookkey(PySetObject *so, PyObject *key, register long hash)
+set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash)
{
register Py_ssize_t i;
register size_t perturb;
@@ -157,7 +157,7 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash)
* see if the comparison altered the table.
*/
static setentry *
-set_lookkey_unicode(PySetObject *so, PyObject *key, register long hash)
+set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash)
{
register Py_ssize_t i;
register size_t perturb;
@@ -211,10 +211,10 @@ Used by the public insert routine.
Eats a reference to key.
*/
static int
-set_insert_key(register PySetObject *so, PyObject *key, long hash)
+set_insert_key(register PySetObject *so, PyObject *key, Py_hash_t hash)
{
register setentry *entry;
- typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long);
+ typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, Py_hash_t);
assert(so->lookup != NULL);
entry = so->lookup(so, key, hash);
@@ -248,7 +248,7 @@ Note that no refcounts are changed by this routine; if needed, the caller
is responsible for incref'ing `key`.
*/
static void
-set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+set_insert_clean(register PySetObject *so, PyObject *key, Py_hash_t hash)
{
register size_t i;
register size_t perturb;
@@ -349,7 +349,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
} else {
/* ACTIVE */
--i;
- set_insert_clean(so, entry->key, (long) entry->hash);
+ set_insert_clean(so, entry->key, entry->hash);
}
}
@@ -365,7 +365,7 @@ set_add_entry(register PySetObject *so, setentry *entry)
{
register Py_ssize_t n_used;
PyObject *key = entry->key;
- long hash = entry->hash;
+ Py_hash_t hash = entry->hash;
assert(so->fill <= so->mask); /* at least one empty slot */
n_used = so->used;
@@ -382,7 +382,7 @@ set_add_entry(register PySetObject *so, setentry *entry)
static int
set_add_key(register PySetObject *so, PyObject *key)
{
- register long hash;
+ register Py_hash_t hash;
register Py_ssize_t n_used;
if (!PyUnicode_CheckExact(key) ||
@@ -411,7 +411,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry)
{ register setentry *entry;
PyObject *old_key;
- entry = (so->lookup)(so, oldentry->key, (long) oldentry->hash);
+ entry = (so->lookup)(so, oldentry->key, oldentry->hash);
if (entry == NULL)
return -1;
if (entry->key == NULL || entry->key == dummy)
@@ -427,7 +427,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry)
static int
set_discard_key(PySetObject *so, PyObject *key)
{
- register long hash;
+ register Py_hash_t hash;
register setentry *entry;
PyObject *old_key;
@@ -640,7 +640,7 @@ set_merge(PySetObject *so, PyObject *otherset)
{
PySetObject *other;
PyObject *key;
- long hash;
+ Py_hash_t hash;
register Py_ssize_t i;
register setentry *entry;
@@ -678,7 +678,7 @@ set_merge(PySetObject *so, PyObject *otherset)
static int
set_contains_key(PySetObject *so, PyObject *key)
{
- long hash;
+ Py_hash_t hash;
setentry *entry;
if (!PyUnicode_CheckExact(key) ||
@@ -700,7 +700,7 @@ set_contains_entry(PySetObject *so, setentry *entry)
PyObject *key;
setentry *lu_entry;
- lu_entry = (so->lookup)(so, entry->key, (long) entry->hash);
+ lu_entry = (so->lookup)(so, entry->key, entry->hash);
if (lu_entry == NULL)
return -1;
key = lu_entry->key;
@@ -764,25 +764,25 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
return 0;
}
-static long
+static Py_hash_t
frozenset_hash(PyObject *self)
{
PySetObject *so = (PySetObject *)self;
- long h, hash = 1927868237L;
+ Py_hash_t h, hash = 1927868237L;
setentry *entry;
Py_ssize_t pos = 0;
if (so->hash != -1)
return so->hash;
- hash *= (long) PySet_GET_SIZE(self) + 1;
+ hash *= PySet_GET_SIZE(self) + 1;
while (set_next(so, &pos, &entry)) {
/* Work to increase the bit dispersion for closely spaced hash
values. The is important because some use cases have many
combinations of a small number of elements with nearby
hashes so that many distinct combinations collapse to only
a handful of distinct hash values. */
- h = (long) entry->hash;
+ h = entry->hash;
hash ^= (h ^ (h << 16) ^ 89869747L) * 3644798167u;
}
hash = hash * 69069L + 907133923L;
@@ -929,7 +929,7 @@ set_update_internal(PySetObject *so, PyObject *other)
if (PyDict_CheckExact(other)) {
PyObject *value;
Py_ssize_t pos = 0;
- long hash;
+ Py_hash_t hash;
Py_ssize_t dictsize = PyDict_Size(other);
/* Do one big resize at the start, rather than
@@ -1117,9 +1117,9 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
{
Py_ssize_t t;
setentry *u;
- setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+ setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash);
setentry tab[PySet_MINSIZE];
- long h;
+ Py_hash_t h;
t = a->fill; a->fill = b->fill; b->fill = t;
t = a->used; a->used = b->used; b->used = t;
@@ -1288,7 +1288,7 @@ set_intersection(PySetObject *so, PyObject *other)
while ((key = PyIter_Next(it)) != NULL) {
int rv;
setentry entry;
- long hash = PyObject_Hash(key);
+ Py_hash_t hash = PyObject_Hash(key);
if (hash == -1) {
Py_DECREF(it);
@@ -1347,9 +1347,9 @@ set_intersection_multi(PySetObject *so, PyObject *args)
}
PyDoc_STRVAR(intersection_doc,
-"Return the intersection of two or more sets as a new set.\n\
+"Return the intersection of two sets as a new set.\n\
\n\
-(i.e. elements that are common to all of the sets.)");
+(i.e. all elements that are in both sets.)");
static PyObject *
set_intersection_update(PySetObject *so, PyObject *other)
@@ -1445,7 +1445,7 @@ set_isdisjoint(PySetObject *so, PyObject *other)
while ((key = PyIter_Next(it)) != NULL) {
int rv;
setentry entry;
- long hash = PyObject_Hash(key);;
+ Py_hash_t hash = PyObject_Hash(key);
if (hash == -1) {
Py_DECREF(key);
@@ -1528,6 +1528,20 @@ PyDoc_STRVAR(difference_update_doc,
"Remove all elements of another set from this set.");
static PyObject *
+set_copy_and_difference(PySetObject *so, PyObject *other)
+{
+ PyObject *result;
+
+ result = set_copy(so);
+ if (result == NULL)
+ return NULL;
+ if (set_difference_update_internal((PySetObject *) result, other) != -1)
+ return result;
+ Py_DECREF(result);
+ return NULL;
+}
+
+static PyObject *
set_difference(PySetObject *so, PyObject *other)
{
PyObject *result;
@@ -1535,13 +1549,13 @@ set_difference(PySetObject *so, PyObject *other)
Py_ssize_t pos = 0;
if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
- result = set_copy(so);
- if (result == NULL)
- return NULL;
- if (set_difference_update_internal((PySetObject *)result, other) != -1)
- return result;
- Py_DECREF(result);
- return NULL;
+ return set_copy_and_difference(so, other);
+ }
+
+ /* If len(so) much more than len(other), it's more efficient to simply copy
+ * so and then iterate other looking for common elements. */
+ if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
+ return set_copy_and_difference(so, other);
}
result = make_new_set_basetype(Py_TYPE(so), NULL);
@@ -1553,7 +1567,7 @@ set_difference(PySetObject *so, PyObject *other)
setentry entrycopy;
entrycopy.hash = entry->hash;
entrycopy.key = entry->key;
- if (!_PyDict_Contains(other, entry->key, (long) entry->hash)) {
+ if (!_PyDict_Contains(other, entry->key, entry->hash)) {
if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
Py_DECREF(result);
return NULL;
@@ -1563,6 +1577,7 @@ set_difference(PySetObject *so, PyObject *other)
return result;
}
+ /* Iterate over so, checking for common elements in other. */
while (set_next(so, &pos, &entry)) {
int rv = set_contains_entry((PySetObject *)other, entry);
if (rv == -1) {
@@ -1644,7 +1659,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
if (PyDict_CheckExact(other)) {
PyObject *value;
int rv;
- long hash;
+ Py_hash_t hash;
while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
setentry an_entry;
@@ -2117,7 +2132,7 @@ PyTypeObject PySet_Type = {
&set_as_number, /* tp_as_number */
&set_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */
- (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
@@ -2129,8 +2144,8 @@ PyTypeObject PySet_Type = {
(traverseproc)set_traverse, /* tp_traverse */
(inquiry)set_clear_internal, /* tp_clear */
(richcmpfunc)set_richcompare, /* tp_richcompare */
- offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
- (getiterfunc)set_iter, /* tp_iter */
+ offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)set_iter, /* tp_iter */
0, /* tp_iternext */
set_methods, /* tp_methods */
0, /* tp_members */
@@ -2311,7 +2326,7 @@ PySet_Add(PyObject *anyset, PyObject *key)
}
int
-_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
setentry *entry;
@@ -2322,7 +2337,7 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
if (set_next((PySetObject *)set, pos, &entry) == 0)
return 0;
*key = entry->key;
- *hash = (long) entry->hash;
+ *hash = entry->hash;
return 1;
}
@@ -2366,12 +2381,26 @@ test_c_api(PySetObject *so)
Py_ssize_t i;
PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
PyObject *ob = (PyObject *)so;
- long hash;
+ Py_hash_t hash;
+ PyObject *str;
- /* Verify preconditions and exercise type/size checks */
+ /* Verify preconditions */
assert(PyAnySet_Check(ob));
assert(PyAnySet_CheckExact(ob));
assert(!PyFrozenSet_CheckExact(ob));
+
+ /* so.clear(); so |= set("abc"); */
+ str = PyUnicode_FromString("abc");
+ if (str == NULL)
+ return NULL;
+ set_clear_internal(so);
+ if (set_update_internal(so, str) == -1) {
+ Py_DECREF(str);
+ return NULL;
+ }
+ Py_DECREF(str);
+
+ /* Exercise type/size checks */
assert(PySet_Size(ob) == 3);
assert(PySet_GET_SIZE(ob) == 3);
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index ee89006..51c53a8 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -99,9 +99,10 @@ _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
}
int
-PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+PySlice_GetIndices(PyObject *_r, Py_ssize_t length,
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
{
+ PySliceObject *r = (PySliceObject*)_r;
/* XXX support long ints */
if (r->step == Py_None) {
*step = 1;
@@ -130,9 +131,11 @@ PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
}
int
-PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
- Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length,
+ Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
+ Py_ssize_t *slicelength)
{
+ PySliceObject *r = (PySliceObject*)_r;
/* this is harder to get right than you might think */
Py_ssize_t defstart, defstop;
@@ -147,6 +150,13 @@ PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
"slice step cannot be zero");
return -1;
}
+ /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it
+ * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it
+ * guards against later undefined behaviour resulting from code that
+ * does "step = -step" as part of a slice reversal.
+ */
+ if (*step < -PY_SSIZE_T_MAX)
+ *step = -PY_SSIZE_T_MAX;
}
defstart = *step < 0 ? length-1 : 0;
@@ -248,7 +258,7 @@ slice_indices(PySliceObject* self, PyObject* len)
return NULL;
}
- if (PySlice_GetIndicesEx(self, ilen, &start, &stop,
+ if (PySlice_GetIndicesEx((PyObject*)self, ilen, &start, &stop,
&step, &slicelength) < 0) {
return NULL;
}
@@ -336,13 +346,6 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
return res;
}
-static long
-slice_hash(PySliceObject *v)
-{
- PyErr_SetString(PyExc_TypeError, "unhashable type");
- return -1L;
-}
-
PyTypeObject PySlice_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"slice", /* Name of this type */
@@ -357,7 +360,7 @@ PyTypeObject PySlice_Type = {
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
- (hashfunc)slice_hash, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt
index 60d919e..ab506d6 100644
--- a/Objects/stringlib/README.txt
+++ b/Objects/stringlib/README.txt
@@ -16,10 +16,6 @@ STRINGLIB_EMPTY
a PyObject representing the empty string, only to be used if
STRINGLIB_MUTABLE is 0
-int STRINGLIB_CMP(STRINGLIB_CHAR*, STRINGLIB_CHAR*, Py_ssize_t)
-
- compares two strings. returns 0 if they match, and non-zero if not.
-
Py_ssize_t STRINGLIB_LEN(PyObject*)
returns the length of the given string object (which must be of the
diff --git a/Objects/stringlib/count.h b/Objects/stringlib/count.h
index eba37e9..de34f96 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 8951276..739cf3d 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 23bccfb..e231c58 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 4407d71..ce615dc 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,17 +76,7 @@ stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
Py_ssize_t start, Py_ssize_t end)
{
- if (start < 0)
- start += str_len;
- if (start < 0)
- start = 0;
- if (end > str_len)
- end = str_len;
- if (end < 0)
- end += str_len;
- if (end < 0)
- end = 0;
-
+ ADJUST_INDICES(start, end, str_len);
return stringlib_rfind(str + start, end - start, sub, sub_len, start);
}
@@ -100,7 +91,7 @@ stringlib_contains_obj(PyObject* str, PyObject* sub)
) != -1;
}
-#endif /* STRINGLIB_STR */
+#endif /* STRINGLIB_WANT_CONTAINS_OBJ */
/*
This function is a helper for the "find" family (find, rfind, index,
@@ -149,7 +140,7 @@ stringlib_parse_args_finds(const char * function_name, PyObject *args,
#undef FORMAT_BUFFER_SIZE
-#ifdef FROM_UNICODE
+#if STRINGLIB_IS_UNICODE
/*
Wraps stringlib_parse_args_finds() and additionally ensures that the
@@ -179,13 +170,6 @@ stringlib_parse_args_finds_unicode(const char * function_name, PyObject *args,
return 0;
}
-#endif /* FROM_UNICODE */
+#endif /* STRINGLIB_IS_UNICODE */
#endif /* STRINGLIB_FIND_H */
-
-/*
-Local variables:
-c-basic-offset: 4
-indent-tabs-mode: nil
-End:
-*/
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h
index 4770863..4fdc62d 100644
--- a/Objects/stringlib/formatter.h
+++ b/Objects/stringlib/formatter.h
@@ -32,7 +32,7 @@ unknown_presentation_type(STRINGLIB_CHAR presentation_type,
PyErr_Format(PyExc_ValueError,
"Unknown format code '%c' "
"for object of type '%.200s'",
- presentation_type,
+ (char)presentation_type,
type_name);
#if STRINGLIB_IS_UNICODE
else
@@ -44,6 +44,24 @@ unknown_presentation_type(STRINGLIB_CHAR presentation_type,
#endif
}
+static void
+invalid_comma_type(STRINGLIB_CHAR presentation_type)
+{
+#if STRINGLIB_IS_UNICODE
+ /* See comment in unknown_presentation_type */
+ if (presentation_type > 32 && presentation_type < 128)
+#endif
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify ',' with '%c'.",
+ (char)presentation_type);
+#if STRINGLIB_IS_UNICODE
+ else
+ PyErr_Format(PyExc_ValueError,
+ "Cannot specify ',' with '\\x%x'.",
+ (unsigned int)presentation_type);
+#endif
+}
+
/*
get_integer consumes 0 or more decimal digit characters from an
input string, updates *result with the corresponding positive
@@ -277,8 +295,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
/* These are allowed. See PEP 378.*/
break;
default:
- PyErr_Format(PyExc_ValueError,
- "Cannot specify ',' with '%c'.", format->type);
+ invalid_comma_type(format->type);
return 0;
}
}
@@ -632,8 +649,8 @@ get_locale_info(int type, LocaleInfo *locale_info)
case LT_DEFAULT_LOCALE:
locale_info->decimal_point = ".";
locale_info->thousands_sep = ",";
- locale_info->grouping = "\3"; /* Group every 3 characters,
- trailing 0 means repeat
+ locale_info->grouping = "\3"; /* Group every 3 characters. The
+ (implicit) trailing 0 means repeat
infinitely. */
break;
case LT_NO_LOCALE:
@@ -759,14 +776,6 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
goto done;
}
- /* Error to specify a comma. */
- if (format->thousands_separators) {
- PyErr_SetString(PyExc_ValueError,
- "Thousands separators not allowed with integer"
- " format specifier 'c'");
- goto done;
- }
-
/* taken from unicodeobject.c formatchar() */
/* Integer input truncated to a character */
/* XXX: won't work for int */
@@ -932,20 +941,16 @@ format_float_internal(PyObject *value,
from a hard-code pseudo-locale */
LocaleInfo locale;
- /* Alternate is not allowed on floats. */
- if (format->alternate) {
- PyErr_SetString(PyExc_ValueError,
- "Alternate form (#) not allowed in float format "
- "specifier");
- goto done;
- }
+ if (format->alternate)
+ flags |= Py_DTSF_ALT;
if (type == '\0') {
- /* Omitted type specifier. This is like 'g' but with at least one
- digit after the decimal point, and different default precision.*/
- type = 'g';
- default_precision = PyFloat_STR_PRECISION;
+ /* Omitted type specifier. Behaves in the same way as repr(x)
+ and str(x) if no precision is given, else like 'g', but with
+ at least one digit after the decimal point. */
flags |= Py_DTSF_ADD_DOT_0;
+ type = 'r';
+ default_precision = 0;
}
if (type == 'n')
@@ -953,13 +958,6 @@ format_float_internal(PyObject *value,
format the result. We take care of that later. */
type = 'g';
-#if PY_VERSION_HEX < 0x0301000
- /* 'F' is the same as 'f', per the PEP */
- /* This is no longer the case in 3.x */
- if (type == 'F')
- type = 'f';
-#endif
-
val = PyFloat_AsDouble(value);
if (val == -1.0 && PyErr_Occurred())
goto done;
@@ -972,12 +970,8 @@ format_float_internal(PyObject *value,
if (precision < 0)
precision = default_precision;
-
-#if PY_VERSION_HEX < 0x03010000
- /* 3.1 no longer converts large 'f' to 'g'. */
- if ((type == 'f' || type == 'F') && fabs(val) >= 1e50)
+ else if (type == 'r')
type = 'g';
-#endif
/* Cast "type", because if we're in unicode we need to pass a
8-bit char. This is safe, because we've restricted what "type"
@@ -1105,15 +1099,7 @@ format_complex_internal(PyObject *value,
from a hard-code pseudo-locale */
LocaleInfo locale;
- /* Alternate is not allowed on complex. */
- if (format->alternate) {
- PyErr_SetString(PyExc_ValueError,
- "Alternate form (#) not allowed in complex format "
- "specifier");
- goto done;
- }
-
- /* Neither is zero pading. */
+ /* Zero padding is not allowed. */
if (format->fill_char == '0') {
PyErr_SetString(PyExc_ValueError,
"Zero padding is not allowed in complex format "
@@ -1136,10 +1122,13 @@ format_complex_internal(PyObject *value,
if (im == -1.0 && PyErr_Occurred())
goto done;
+ if (format->alternate)
+ flags |= Py_DTSF_ALT;
+
if (type == '\0') {
/* Omitted type specifier. Should be like str(self). */
- type = 'g';
- default_precision = PyFloat_STR_PRECISION;
+ type = 'r';
+ default_precision = 0;
if (re == 0.0 && copysign(1.0, re) == 1.0)
skip_re = 1;
else
@@ -1151,15 +1140,10 @@ format_complex_internal(PyObject *value,
format the result. We take care of that later. */
type = 'g';
-#if PY_VERSION_HEX < 0x03010000
- /* This is no longer the case in 3.x */
- /* 'F' is the same as 'f', per the PEP */
- if (type == 'F')
- type = 'f';
-#endif
-
if (precision < 0)
precision = default_precision;
+ else if (type == 'r')
+ type = 'g';
/* Cast "type", because if we're in unicode we need to pass a
8-bit char. This is safe, because we've restricted what "type"
diff --git a/Objects/stringlib/partition.h b/Objects/stringlib/partition.h
index 20c7507..0170bdd 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 0000000..60e7767
--- /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 b2095fd..6f10727 100644
--- a/Objects/stringlib/string_format.h
+++ b/Objects/stringlib/string_format.h
@@ -499,13 +499,16 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs,
PyObject *key = SubString_new_object(&first);
if (key == NULL)
goto error;
- if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
+
+ /* Use PyObject_GetItem instead of PyDict_GetItem because this
+ code is no longer just used with kwargs. It might be passed
+ a non-dict when called through format_map. */
+ if ((kwargs == NULL) || (obj = PyObject_GetItem(kwargs, key)) == NULL) {
PyErr_SetObject(PyExc_KeyError, key);
Py_DECREF(key);
goto error;
}
Py_DECREF(key);
- Py_INCREF(obj);
}
else {
/* look up in args */
@@ -1039,6 +1042,11 @@ do_string_format(PyObject *self, PyObject *args, PyObject *kwargs)
return build_string(&input, args, kwargs, recursion_depth, &auto_number);
}
+static PyObject *
+do_string_format_map(PyObject *self, PyObject *obj)
+{
+ return do_string_format(self, NULL, obj);
+}
/************************************************************************/
@@ -1180,10 +1188,15 @@ static PyTypeObject PyFormatterIter_Type = {
describing the parsed elements. It's a wrapper around
stringlib/string_format.h's MarkupIterator */
static PyObject *
-formatter_parser(STRINGLIB_OBJECT *self)
+formatter_parser(PyObject *ignored, STRINGLIB_OBJECT *self)
{
formatteriterobject *it;
+ if (!PyUnicode_Check(self)) {
+ PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name);
+ return NULL;
+ }
+
it = PyObject_New(formatteriterobject, &PyFormatterIter_Type);
if (it == NULL)
return NULL;
@@ -1315,7 +1328,7 @@ static PyTypeObject PyFieldNameIter_Type = {
field_name_split. The iterator it returns is a
FieldNameIterator */
static PyObject *
-formatter_field_name_split(STRINGLIB_OBJECT *self)
+formatter_field_name_split(PyObject *ignored, STRINGLIB_OBJECT *self)
{
SubString first;
Py_ssize_t first_idx;
@@ -1324,6 +1337,11 @@ formatter_field_name_split(STRINGLIB_OBJECT *self)
PyObject *first_obj = NULL;
PyObject *result = NULL;
+ if (!PyUnicode_Check(self)) {
+ PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name);
+ return NULL;
+ }
+
it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type);
if (it == NULL)
return NULL;
diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h
index a5672c7..1c49426 100644
--- a/Objects/stringlib/stringdefs.h
+++ b/Objects/stringlib/stringdefs.h
@@ -11,6 +11,8 @@
#define STRINGLIB_TYPE_NAME "string"
#define STRINGLIB_PARSE_CODE "S"
#define STRINGLIB_EMPTY nullstring
+#define STRINGLIB_ISSPACE Py_ISSPACE
+#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
#define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9'))
#define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1)
#define STRINGLIB_TOUPPER Py_TOUPPER
@@ -21,7 +23,7 @@
#define STRINGLIB_NEW PyBytes_FromStringAndSize
#define STRINGLIB_RESIZE _PyBytes_Resize
#define STRINGLIB_CHECK PyBytes_Check
-#define STRINGLIB_CMP memcmp
+#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact
#define STRINGLIB_TOSTR PyObject_Str
#define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping
#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale
diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h
index 4390e22..1e132e5 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 366acfe..09dae6d 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
#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale
@@ -34,23 +37,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/structseq.c b/Objects/structseq.c
index 7031225..ef17f49 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -3,7 +3,6 @@
#include "Python.h"
#include "structmember.h"
-#include "structseq.h"
static char visible_length_key[] = "n_sequence_fields";
static char real_length_key[] = "n_fields";
@@ -30,113 +29,42 @@ PyObject *
PyStructSequence_New(PyTypeObject *type)
{
PyStructSequence *obj;
+ Py_ssize_t size = REAL_SIZE_TP(type), i;
- obj = PyObject_New(PyStructSequence, type);
+ obj = PyObject_GC_NewVar(PyStructSequence, type, size);
if (obj == NULL)
return NULL;
+ /* Hack the size of the variable object, so invisible fields don't appear
+ to Python code. */
Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
+ for (i = 0; i < size; i++)
+ obj->ob_item[i] = NULL;
- return (PyObject*) obj;
+ return (PyObject*)obj;
}
-static void
-structseq_dealloc(PyStructSequence *obj)
-{
- Py_ssize_t i, size;
-
- size = REAL_SIZE(obj);
- for (i = 0; i < size; ++i) {
- Py_XDECREF(obj->ob_item[i]);
- }
- PyObject_Del(obj);
-}
-
-static Py_ssize_t
-structseq_length(PyStructSequence *obj)
+void
+PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v)
{
- return VISIBLE_SIZE(obj);
+ PyStructSequence_SET_ITEM(op, i, v);
}
-static PyObject*
-structseq_item(PyStructSequence *obj, Py_ssize_t i)
+PyObject*
+PyStructSequence_GetItem(PyObject* op, Py_ssize_t i)
{
- if (i < 0 || i >= VISIBLE_SIZE(obj)) {
- PyErr_SetString(PyExc_IndexError, "tuple index out of range");
- return NULL;
- }
- Py_INCREF(obj->ob_item[i]);
- return obj->ob_item[i];
+ return PyStructSequence_GET_ITEM(op, i);
}
-static PyObject*
-structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
-{
- PyTupleObject *np;
- Py_ssize_t i;
-
- if (low < 0)
- low = 0;
- if (high > VISIBLE_SIZE(obj))
- high = VISIBLE_SIZE(obj);
- if (high < low)
- high = low;
- np = (PyTupleObject *)PyTuple_New(high-low);
- if (np == NULL)
- return NULL;
- for(i = low; i < high; ++i) {
- PyObject *v = obj->ob_item[i];
- Py_INCREF(v);
- PyTuple_SET_ITEM(np, i-low, v);
- }
- return (PyObject *) np;
-}
-
-static PyObject *
-structseq_subscript(PyStructSequence *self, PyObject *item)
+static void
+structseq_dealloc(PyStructSequence *obj)
{
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
- return NULL;
-
- if (i < 0)
- i += VISIBLE_SIZE(self);
-
- if (i < 0 || i >= VISIBLE_SIZE(self)) {
- PyErr_SetString(PyExc_IndexError,
- "tuple index out of range");
- return NULL;
- }
- Py_INCREF(self->ob_item[i]);
- return self->ob_item[i];
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelen, cur, i;
- PyObject *result;
-
- if (PySlice_GetIndicesEx((PySliceObject *)item,
- VISIBLE_SIZE(self), &start, &stop,
- &step, &slicelen) < 0) {
- return NULL;
- }
- if (slicelen <= 0)
- return PyTuple_New(0);
- result = PyTuple_New(slicelen);
- if (result == NULL)
- return NULL;
- for (cur = start, i = 0; i < slicelen;
- cur += step, i++) {
- PyObject *v = self->ob_item[cur];
- Py_INCREF(v);
- PyTuple_SET_ITEM(result, i, v);
- }
- return result;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "structseq index must be integer");
- return NULL;
+ Py_ssize_t i, size;
+
+ size = REAL_SIZE(obj);
+ for (i = 0; i < size; ++i) {
+ Py_XDECREF(obj->ob_item[i]);
}
+ PyObject_GC_Del(obj);
}
static PyObject *
@@ -223,11 +151,6 @@ structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return (PyObject*) res;
}
-static PyObject *
-make_tuple(PyStructSequence *obj)
-{
- return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
-}
static PyObject *
structseq_repr(PyStructSequence *obj)
@@ -236,7 +159,6 @@ structseq_repr(PyStructSequence *obj)
#define REPR_BUFFER_SIZE 512
#define TYPE_MAXSIZE 100
- PyObject *tup;
PyTypeObject *typ = Py_TYPE(obj);
int i, removelast = 0;
Py_ssize_t len;
@@ -246,10 +168,6 @@ structseq_repr(PyStructSequence *obj)
/* pointer to end of writeable buffer; safes space for "...)\0" */
endofbuf= &buf[REPR_BUFFER_SIZE-5];
- if ((tup = make_tuple(obj)) == NULL) {
- return NULL;
- }
-
/* "typename(", limited to TYPE_MAXSIZE */
len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
strlen(typ->tp_name);
@@ -262,19 +180,17 @@ structseq_repr(PyStructSequence *obj)
char *cname, *crepr;
cname = typ->tp_members[i].name;
-
- val = PyTuple_GetItem(tup, i);
- if (cname == NULL || val == NULL) {
+ if (cname == NULL) {
+ PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL"
+ " for type %.500s", i, typ->tp_name);
return NULL;
}
+ val = PyStructSequence_GET_ITEM(obj, i);
repr = PyObject_Repr(val);
- if (repr == NULL) {
- Py_DECREF(tup);
+ if (repr == NULL)
return NULL;
- }
crepr = _PyUnicode_AsString(repr);
if (crepr == NULL) {
- Py_DECREF(tup);
Py_DECREF(repr);
return NULL;
}
@@ -300,7 +216,6 @@ structseq_repr(PyStructSequence *obj)
break;
}
}
- Py_DECREF(tup);
if (removelast) {
/* overwrite last ", " */
pbuf-=2;
@@ -312,62 +227,6 @@ structseq_repr(PyStructSequence *obj)
}
static PyObject *
-structseq_concat(PyStructSequence *obj, PyObject *b)
-{
- PyObject *tup, *result;
- tup = make_tuple(obj);
- result = PySequence_Concat(tup, b);
- Py_DECREF(tup);
- return result;
-}
-
-static PyObject *
-structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
-{
- PyObject *tup, *result;
- tup = make_tuple(obj);
- result = PySequence_Repeat(tup, n);
- Py_DECREF(tup);
- return result;
-}
-
-static int
-structseq_contains(PyStructSequence *obj, PyObject *o)
-{
- PyObject *tup;
- int result;
- tup = make_tuple(obj);
- if (!tup)
- return -1;
- result = PySequence_Contains(tup, o);
- Py_DECREF(tup);
- return result;
-}
-
-static long
-structseq_hash(PyObject *obj)
-{
- PyObject *tup;
- long result;
- tup = make_tuple((PyStructSequence*) obj);
- if (!tup)
- return -1;
- result = PyObject_Hash(tup);
- Py_DECREF(tup);
- return result;
-}
-
-static PyObject *
-structseq_richcompare(PyObject *obj, PyObject *o2, int op)
-{
- PyObject *tup, *result;
- tup = make_tuple((PyStructSequence*) obj);
- result = PyObject_RichCompare(tup, o2, op);
- Py_DECREF(tup);
- return result;
-}
-
-static PyObject *
structseq_reduce(PyStructSequence* self)
{
PyObject* tup;
@@ -409,33 +268,16 @@ structseq_reduce(PyStructSequence* self)
return result;
}
-static PySequenceMethods structseq_as_sequence = {
- (lenfunc)structseq_length,
- (binaryfunc)structseq_concat, /* sq_concat */
- (ssizeargfunc)structseq_repeat, /* sq_repeat */
- (ssizeargfunc)structseq_item, /* sq_item */
- 0, /* sq_slice */
- 0, /* sq_ass_item */
- 0, /* sq_ass_slice */
- (objobjproc)structseq_contains, /* sq_contains */
-};
-
-static PyMappingMethods structseq_as_mapping = {
- (lenfunc)structseq_length,
- (binaryfunc)structseq_subscript,
-};
-
static PyMethodDef structseq_methods[] = {
- {"__reduce__", (PyCFunction)structseq_reduce,
- METH_NOARGS, NULL},
+ {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL},
{NULL, NULL}
};
static PyTypeObject _struct_sequence_template = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
NULL, /* tp_name */
- 0, /* tp_basicsize */
- 0, /* tp_itemsize */
+ sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */
+ sizeof(PyObject *), /* tp_itemsize */
(destructor)structseq_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
@@ -443,19 +285,19 @@ static PyTypeObject _struct_sequence_template = {
0, /* tp_reserved */
(reprfunc)structseq_repr, /* tp_repr */
0, /* tp_as_number */
- &structseq_as_sequence, /* tp_as_sequence */
- &structseq_as_mapping, /* tp_as_mapping */
- structseq_hash, /* tp_hash */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
NULL, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- structseq_richcompare, /* tp_richcompare */
+ 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
@@ -494,11 +336,9 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
n_members = i;
memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
+ type->tp_base = &PyTuple_Type;
type->tp_name = desc->name;
type->tp_doc = desc->doc;
- type->tp_basicsize = sizeof(PyStructSequence)+
- sizeof(PyObject*)*(n_members-1);
- type->tp_itemsize = 0;
members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
if (members == NULL)
@@ -537,3 +377,11 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
SET_DICT_FROM_INT(real_length_key, n_members);
SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
}
+
+PyTypeObject*
+PyStructSequence_NewType(PyStructSequence_Desc *desc)
+{
+ PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
+ PyStructSequence_InitType(result, desc);
+ return result;
+}
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index aa3be82..72b79c9 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -312,13 +312,13 @@ Done:
1330111, 1412633, 1165069, 1247599, 1495177, 1577699
*/
-static long
+static Py_hash_t
tuplehash(PyTupleObject *v)
{
- register long x, y;
+ register Py_hash_t x, y;
register Py_ssize_t len = Py_SIZE(v);
register PyObject **p;
- long mult = 1000003L;
+ Py_hash_t mult = 1000003L;
x = 0x345678L;
p = v->ob_item;
while (--len >= 0) {
@@ -327,7 +327,7 @@ tuplehash(PyTupleObject *v)
return -1;
x = (x ^ y) * mult;
/* the cast might truncate len; that doesn't change hash stability */
- mult += (long)(82520L + len + len);
+ mult += (Py_hash_t)(82520L + len + len);
}
x += 97531L;
if (x == -1)
@@ -689,7 +689,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
PyObject* it;
PyObject **src, **dest;
- if (PySlice_GetIndicesEx((PySliceObject*)item,
+ if (PySlice_GetIndicesEx(item,
PyTuple_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 310a56c..8eaf51f 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1359,8 +1359,14 @@ consistent method resolution\norder (MRO) for bases");
i = 0;
while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) {
PyObject *name = class_name(k);
- off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s",
- name ? _PyUnicode_AsString(name) : "?");
+ char *name_str;
+ if (name != NULL) {
+ name_str = _PyUnicode_AsString(name);
+ if (name_str == NULL)
+ name_str = "?";
+ } else
+ name_str = "?";
+ off += PyOS_snprintf(buf + off, sizeof(buf) - off, " %s", name_str);
Py_XDECREF(name);
if (--n && (size_t)(off+1) < sizeof(buf)) {
buf[off++] = ',';
@@ -1898,6 +1904,12 @@ type_init(PyObject *cls, PyObject *args, PyObject *kwds)
return res;
}
+long
+PyType_GetFlags(PyTypeObject *type)
+{
+ return type->tp_flags;
+}
+
static PyObject *
type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
@@ -2232,6 +2244,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
for (i = 0; i < nslots; i++, mp++) {
mp->name = _PyUnicode_AsString(
PyTuple_GET_ITEM(slots, i));
+ if (mp->name == NULL) {
+ Py_DECREF(type);
+ return NULL;
+ }
mp->type = T_OBJECT_EX;
mp->offset = slotoffset;
@@ -2303,6 +2319,57 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
return (PyObject *)type;
}
+static short slotoffsets[] = {
+ -1, /* invalid slot */
+#include "typeslots.inc"
+};
+
+PyObject* PyType_FromSpec(PyType_Spec *spec)
+{
+ PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
+ char *res_start = (char*)res;
+ PyType_Slot *slot;
+
+ if (res == NULL)
+ return NULL;
+ res->ht_name = PyUnicode_FromString(spec->name);
+ if (!res->ht_name)
+ goto fail;
+ res->ht_type.tp_name = _PyUnicode_AsString(res->ht_name);
+ if (!res->ht_type.tp_name)
+ goto fail;
+
+ res->ht_type.tp_basicsize = spec->basicsize;
+ res->ht_type.tp_itemsize = spec->itemsize;
+ res->ht_type.tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE;
+
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot >= sizeof(slotoffsets)/sizeof(slotoffsets[0])) {
+ PyErr_SetString(PyExc_RuntimeError, "invalid slot offset");
+ goto fail;
+ }
+ *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc;
+
+ /* need to make a copy of the docstring slot, which usually
+ points to a static string literal */
+ if (slot->slot == Py_tp_doc) {
+ ssize_t len = strlen(slot->pfunc)+1;
+ char *tp_doc = PyObject_MALLOC(len);
+ if (tp_doc == NULL)
+ goto fail;
+ memcpy(tp_doc, slot->pfunc, len);
+ res->ht_type.tp_doc = tp_doc;
+ }
+ }
+
+ return (PyObject*)res;
+
+ fail:
+ Py_DECREF(res);
+ return NULL;
+}
+
+
/* Internal API to look for a name through the MRO.
This returns a borrowed reference, and doesn't set an exception! */
PyObject *
@@ -3309,23 +3376,32 @@ object_format(PyObject *self, PyObject *args)
PyObject *format_spec;
PyObject *self_as_str = NULL;
PyObject *result = NULL;
- PyObject *format_meth = NULL;
if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
return NULL;
self_as_str = PyObject_Str(self);
if (self_as_str != NULL) {
- /* find the format function */
- format_meth = PyObject_GetAttrString(self_as_str, "__format__");
- if (format_meth != NULL) {
- /* and call it */
- result = PyObject_CallFunctionObjArgs(format_meth, format_spec, NULL);
- }
- }
-
+ /* Issue 7994: If we're converting to a string, we
+ should reject format specifications */
+ if (PyUnicode_GET_SIZE(format_spec) > 0) {
+ if (PyErr_WarnEx(PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty format "
+ "string is deprecated", 1) < 0) {
+ goto done;
+ }
+ /* Eventually this will become an error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to object.__format__");
+ goto done;
+ */
+ }
+
+ result = PyObject_Format(self_as_str, format_spec);
+ }
+
+done:
Py_XDECREF(self_as_str);
- Py_XDECREF(format_meth);
return result;
}
@@ -3483,11 +3559,8 @@ add_getset(PyTypeObject *type, PyGetSetDef *gsp)
static void
inherit_special(PyTypeObject *type, PyTypeObject *base)
{
- Py_ssize_t oldsize, newsize;
/* Copying basicsize is connected to the GC flags */
- oldsize = base->tp_basicsize;
- newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(!type->tp_traverse && !type->tp_clear)) {
@@ -3514,7 +3587,8 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
type->tp_new = base->tp_new;
}
}
- type->tp_basicsize = newsize;
+ if (type->tp_basicsize == 0)
+ type->tp_basicsize = base->tp_basicsize;
/* Copy other non-function slots */
@@ -3901,13 +3975,10 @@ PyType_Ready(PyTypeObject *type)
tp_reserved) but not tp_richcompare. */
if (type->tp_reserved && !type->tp_richcompare) {
int error;
- char msg[240];
- PyOS_snprintf(msg, sizeof(msg),
- "Type %.100s defines tp_reserved (formerly "
- "tp_compare) but not tp_richcompare. "
- "Comparisons may not behave as intended.",
- type->tp_name);
- error = PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1);
+ error = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+ "Type %.100s defines tp_reserved (formerly tp_compare) "
+ "but not tp_richcompare. Comparisons may not behave as intended.",
+ type->tp_name);
if (error == -1)
goto error;
}
@@ -4306,14 +4377,14 @@ static PyObject *
wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
{
hashfunc func = (hashfunc)wrapped;
- long res;
+ Py_hash_t res;
if (!check_num_args(args, 0))
return NULL;
res = (*func)(self);
if (res == -1 && PyErr_Occurred())
return NULL;
- return PyLong_FromLong(res);
+ return PyLong_FromSsize_t(res);
}
static PyObject *
@@ -4910,12 +4981,12 @@ slot_tp_str(PyObject *self)
}
}
-static long
+static Py_hash_t
slot_tp_hash(PyObject *self)
{
PyObject *func, *res;
static PyObject *hash_str;
- long h;
+ Py_ssize_t h;
func = lookup_method(self, "__hash__", &hash_str);
@@ -4932,14 +5003,30 @@ slot_tp_hash(PyObject *self)
Py_DECREF(func);
if (res == NULL)
return -1;
- if (PyLong_Check(res))
+
+ if (!PyLong_Check(res)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__hash__ method should return an integer");
+ return -1;
+ }
+ /* Transform the PyLong `res` to a Py_hash_t `h`. For an existing
+ hashable Python object x, hash(x) will always lie within the range of
+ Py_hash_t. Therefore our transformation must preserve values that
+ already lie within this range, to ensure that if x.__hash__() returns
+ hash(y) then hash(x) == hash(y). */
+ h = PyLong_AsSsize_t(res);
+ if (h == -1 && PyErr_Occurred()) {
+ /* res was not within the range of a Py_hash_t, so we're free to
+ use any sufficiently bit-mixing transformation;
+ long.__hash__ will do nicely. */
+ PyErr_Clear();
h = PyLong_Type.tp_hash(res);
- else
- h = PyLong_AsLong(res);
+ }
+ /* -1 is reserved for errors. */
+ if (h == -1)
+ h = -2;
Py_DECREF(res);
- if (h == -1 && !PyErr_Occurred())
- h = -2;
- return h;
+ return h;
}
static PyObject *
@@ -5078,7 +5165,7 @@ static char *name_op[] = {
};
static PyObject *
-half_richcompare(PyObject *self, PyObject *other, int op)
+slot_tp_richcompare(PyObject *self, PyObject *other, int op)
{
PyObject *func, *args, *res;
static PyObject *op_str[6];
@@ -5101,28 +5188,6 @@ half_richcompare(PyObject *self, PyObject *other, int op)
}
static PyObject *
-slot_tp_richcompare(PyObject *self, PyObject *other, int op)
-{
- PyObject *res;
-
- if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {
- res = half_richcompare(self, other, op);
- if (res != Py_NotImplemented)
- return res;
- Py_DECREF(res);
- }
- if (Py_TYPE(other)->tp_richcompare == slot_tp_richcompare) {
- res = half_richcompare(other, self, _Py_SwappedOp[op]);
- if (res != Py_NotImplemented) {
- return res;
- }
- Py_DECREF(res);
- }
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
-}
-
-static PyObject *
slot_tp_iter(PyObject *self)
{
PyObject *func, *res;
@@ -5658,7 +5723,7 @@ update_one_slot(PyTypeObject *type, slotdef *p)
generic = p->function;
d = (PyWrapperDescrObject *)descr;
if (d->d_base->wrapper == p->wrapper &&
- PyType_IsSubtype(type, d->d_type))
+ PyType_IsSubtype(type, PyDescr_TYPE(d)))
{
if (specific == NULL ||
specific == d->d_wrapped)
@@ -6162,7 +6227,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
and first local variable on the stack. */
PyFrameObject *f = PyThreadState_GET()->frame;
PyCodeObject *co = f->f_code;
- int i, n;
+ Py_ssize_t i, n;
if (co == NULL) {
PyErr_SetString(PyExc_SystemError,
"super(): no code object");
diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc
new file mode 100644
index 0000000..5186dcf
--- /dev/null
+++ b/Objects/typeslots.inc
@@ -0,0 +1,75 @@
+/* Generated by typeslots.py $Revision$ */
+0,
+0,
+offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript),
+offsetof(PyHeapTypeObject, as_mapping.mp_length),
+offsetof(PyHeapTypeObject, as_mapping.mp_subscript),
+offsetof(PyHeapTypeObject, as_number.nb_absolute),
+offsetof(PyHeapTypeObject, as_number.nb_add),
+offsetof(PyHeapTypeObject, as_number.nb_and),
+offsetof(PyHeapTypeObject, as_number.nb_bool),
+offsetof(PyHeapTypeObject, as_number.nb_divmod),
+offsetof(PyHeapTypeObject, as_number.nb_float),
+offsetof(PyHeapTypeObject, as_number.nb_floor_divide),
+offsetof(PyHeapTypeObject, as_number.nb_index),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_add),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_and),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_or),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_power),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_xor),
+offsetof(PyHeapTypeObject, as_number.nb_int),
+offsetof(PyHeapTypeObject, as_number.nb_invert),
+offsetof(PyHeapTypeObject, as_number.nb_lshift),
+offsetof(PyHeapTypeObject, as_number.nb_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_negative),
+offsetof(PyHeapTypeObject, as_number.nb_or),
+offsetof(PyHeapTypeObject, as_number.nb_positive),
+offsetof(PyHeapTypeObject, as_number.nb_power),
+offsetof(PyHeapTypeObject, as_number.nb_remainder),
+offsetof(PyHeapTypeObject, as_number.nb_rshift),
+offsetof(PyHeapTypeObject, as_number.nb_subtract),
+offsetof(PyHeapTypeObject, as_number.nb_true_divide),
+offsetof(PyHeapTypeObject, as_number.nb_xor),
+offsetof(PyHeapTypeObject, as_sequence.sq_ass_item),
+offsetof(PyHeapTypeObject, as_sequence.sq_concat),
+offsetof(PyHeapTypeObject, as_sequence.sq_contains),
+offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat),
+offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat),
+offsetof(PyHeapTypeObject, as_sequence.sq_item),
+offsetof(PyHeapTypeObject, as_sequence.sq_length),
+offsetof(PyHeapTypeObject, as_sequence.sq_repeat),
+offsetof(PyHeapTypeObject, ht_type.tp_alloc),
+offsetof(PyHeapTypeObject, ht_type.tp_base),
+offsetof(PyHeapTypeObject, ht_type.tp_bases),
+offsetof(PyHeapTypeObject, ht_type.tp_call),
+offsetof(PyHeapTypeObject, ht_type.tp_clear),
+offsetof(PyHeapTypeObject, ht_type.tp_dealloc),
+offsetof(PyHeapTypeObject, ht_type.tp_del),
+offsetof(PyHeapTypeObject, ht_type.tp_descr_get),
+offsetof(PyHeapTypeObject, ht_type.tp_descr_set),
+offsetof(PyHeapTypeObject, ht_type.tp_doc),
+offsetof(PyHeapTypeObject, ht_type.tp_getattr),
+offsetof(PyHeapTypeObject, ht_type.tp_getattro),
+offsetof(PyHeapTypeObject, ht_type.tp_hash),
+offsetof(PyHeapTypeObject, ht_type.tp_init),
+offsetof(PyHeapTypeObject, ht_type.tp_is_gc),
+offsetof(PyHeapTypeObject, ht_type.tp_iter),
+offsetof(PyHeapTypeObject, ht_type.tp_iternext),
+offsetof(PyHeapTypeObject, ht_type.tp_methods),
+offsetof(PyHeapTypeObject, ht_type.tp_new),
+offsetof(PyHeapTypeObject, ht_type.tp_repr),
+offsetof(PyHeapTypeObject, ht_type.tp_richcompare),
+offsetof(PyHeapTypeObject, ht_type.tp_setattr),
+offsetof(PyHeapTypeObject, ht_type.tp_setattro),
+offsetof(PyHeapTypeObject, ht_type.tp_str),
+offsetof(PyHeapTypeObject, ht_type.tp_traverse),
+offsetof(PyHeapTypeObject, ht_type.tp_members),
+offsetof(PyHeapTypeObject, ht_type.tp_getset),
+offsetof(PyHeapTypeObject, ht_type.tp_free),
diff --git a/Objects/typeslots.py b/Objects/typeslots.py
new file mode 100644
index 0000000..2e00c80
--- /dev/null
+++ b/Objects/typeslots.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# Usage: typeslots.py < Include/typeslots.h > typeslots.inc
+
+import sys, re
+
+print("/* Generated by typeslots.py $Revision$ */")
+res = {}
+for line in sys.stdin:
+ m = re.match("#define Py_([a-z_]+) ([0-9]+)", line)
+ if not m:
+ continue
+ member = m.group(1)
+ if member.startswith("tp_"):
+ member = "ht_type."+member
+ elif member.startswith("nb_"):
+ member = "as_number."+member
+ elif member.startswith("mp_"):
+ member = "as_mapping."+member
+ elif member.startswith("sq_"):
+ member = "as_sequence."+member
+ elif member.startswith("bf_"):
+ member = "as_buffer."+member
+ res[int(m.group(2))] = member
+
+M = max(res.keys())+1
+for i in range(1,M):
+ if i in res:
+ print("offsetof(PyHeapTypeObject, %s)," % res[i])
+ else:
+ print("0,")
diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c
index 1597bbd..9f6ac89 100644
--- a/Objects/unicodectype.c
+++ b/Objects/unicodectype.c
@@ -9,7 +9,6 @@
*/
#include "Python.h"
-#include "unicodeobject.h"
#define ALPHA_MASK 0x01
#define DECIMAL_MASK 0x02
@@ -23,11 +22,12 @@
#define XID_CONTINUE_MASK 0x200
#define PRINTABLE_MASK 0x400
#define NODELTA_MASK 0x800
+#define NUMERIC_MASK 0x1000
typedef struct {
- const Py_UNICODE upper;
- const Py_UNICODE lower;
- const Py_UNICODE title;
+ const Py_UCS4 upper;
+ const Py_UCS4 lower;
+ const Py_UCS4 title;
const unsigned char decimal;
const unsigned char digit;
const unsigned short flags;
@@ -36,15 +36,13 @@ typedef struct {
#include "unicodetype_db.h"
static const _PyUnicode_TypeRecord *
-gettyperecord(Py_UNICODE code)
+gettyperecord(Py_UCS4 code)
{
int index;
-#ifdef Py_UNICODE_WIDE
if (code >= 0x110000)
index = 0;
else
-#endif
{
index = index1[(code>>SHIFT)];
index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
@@ -53,30 +51,10 @@ gettyperecord(Py_UNICODE code)
return &_PyUnicode_TypeRecords[index];
}
-/* Returns 1 for Unicode characters having the category 'Zl', 'Zp' or
- type 'B', 0 otherwise. */
-
-int _PyUnicode_IsLinebreak(register const Py_UNICODE ch)
-{
- switch (ch) {
- case 0x000A: /* LINE FEED */
- case 0x000D: /* CARRIAGE RETURN */
- case 0x001C: /* FILE SEPARATOR */
- case 0x001D: /* GROUP SEPARATOR */
- case 0x001E: /* RECORD SEPARATOR */
- case 0x0085: /* NEXT LINE */
- case 0x2028: /* LINE SEPARATOR */
- case 0x2029: /* PARAGRAPH SEPARATOR */
- return 1;
- default:
- return 0;
- }
-}
-
/* Returns the titlecase Unicode characters corresponding to ch or just
ch if no titlecase mapping is known. */
-Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
+Py_UCS4 _PyUnicode_ToTitlecase(register Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
int delta = ctype->title;
@@ -93,7 +71,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
/* Returns 1 for Unicode characters having the category 'Lt', 0
otherwise. */
-int _PyUnicode_IsTitlecase(Py_UNICODE ch)
+int _PyUnicode_IsTitlecase(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
@@ -103,7 +81,7 @@ int _PyUnicode_IsTitlecase(Py_UNICODE ch)
/* Returns 1 for Unicode characters having the XID_Start property, 0
otherwise. */
-int _PyUnicode_IsXidStart(Py_UNICODE ch)
+int _PyUnicode_IsXidStart(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
@@ -113,7 +91,7 @@ int _PyUnicode_IsXidStart(Py_UNICODE ch)
/* Returns 1 for Unicode characters having the XID_Continue property,
0 otherwise. */
-int _PyUnicode_IsXidContinue(Py_UNICODE ch)
+int _PyUnicode_IsXidContinue(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
@@ -123,14 +101,14 @@ int _PyUnicode_IsXidContinue(Py_UNICODE ch)
/* Returns the integer decimal (0-9) for Unicode characters having
this property, -1 otherwise. */
-int _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
+int _PyUnicode_ToDecimalDigit(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
}
-int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
+int _PyUnicode_IsDecimalDigit(Py_UCS4 ch)
{
if (_PyUnicode_ToDecimalDigit(ch) < 0)
return 0;
@@ -140,14 +118,14 @@ int _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
/* Returns the integer digit (0-9) for Unicode characters having
this property, -1 otherwise. */
-int _PyUnicode_ToDigit(Py_UNICODE ch)
+int _PyUnicode_ToDigit(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1;
}
-int _PyUnicode_IsDigit(Py_UNICODE ch)
+int _PyUnicode_IsDigit(Py_UCS4 ch)
{
if (_PyUnicode_ToDigit(ch) < 0)
return 0;
@@ -157,522 +135,11 @@ int _PyUnicode_IsDigit(Py_UNICODE ch)
/* Returns the numeric value as double for Unicode characters having
this property, -1.0 otherwise. */
-/* TODO: replace with unicodetype_db.h table */
-
-double _PyUnicode_ToNumeric(Py_UNICODE ch)
+int _PyUnicode_IsNumeric(Py_UCS4 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);
- }
-}
+ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
-int _PyUnicode_IsNumeric(Py_UNICODE ch)
-{
- return _PyUnicode_ToNumeric(ch) != -1.0;
+ return (ctype->flags & NUMERIC_MASK) != 0;
}
/* Returns 1 for Unicode characters to be hex-escaped when repr()ed,
@@ -688,61 +155,17 @@ int _PyUnicode_IsNumeric(Py_UNICODE ch)
* Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR)
* Zs (Separator, Space) other than ASCII space('\x20').
*/
-int _PyUnicode_IsPrintable(Py_UNICODE ch)
+int _PyUnicode_IsPrintable(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
return (ctype->flags & PRINTABLE_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. */
-int _PyUnicode_IsLowercase(Py_UNICODE ch)
+int _PyUnicode_IsLowercase(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
@@ -752,7 +175,7 @@ int _PyUnicode_IsLowercase(Py_UNICODE ch)
/* Returns 1 for Unicode characters having the category 'Lu', 0
otherwise. */
-int _PyUnicode_IsUppercase(Py_UNICODE ch)
+int _PyUnicode_IsUppercase(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
@@ -762,7 +185,7 @@ int _PyUnicode_IsUppercase(Py_UNICODE ch)
/* Returns the uppercase Unicode characters corresponding to ch or just
ch if no uppercase mapping is known. */
-Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
+Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
int delta = ctype->upper;
@@ -776,7 +199,7 @@ Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
/* Returns the lowercase Unicode characters corresponding to ch or just
ch if no lowercase mapping is known. */
-Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
+Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
int delta = ctype->lower;
@@ -790,46 +213,10 @@ Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt',
'Lo' or 'Lm', 0 otherwise. */
-int _PyUnicode_IsAlpha(Py_UNICODE ch)
+int _PyUnicode_IsAlpha(Py_UCS4 ch)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
return (ctype->flags & ALPHA_MASK) != 0;
}
-#else
-
-/* 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);
-}
-
-int _PyUnicode_IsUppercase(Py_UNICODE ch)
-{
- return iswupper(ch);
-}
-
-Py_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
-{
- return towlower(ch);
-}
-
-Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
-{
- return towupper(ch);
-}
-
-int _PyUnicode_IsAlpha(Py_UNICODE ch)
-{
- return iswalpha(ch);
-}
-
-#endif
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 2cdbc0e..7a70a5e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -41,9 +41,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define PY_SSIZE_T_CLEAN
#include "Python.h"
-#include "bytes_methods.h"
-
-#include "unicodeobject.h"
#include "ucnhash.h"
#ifdef MS_WINDOWS
@@ -114,21 +111,12 @@ static PyUnicodeObject *unicode_empty;
shared as well. */
static PyUnicodeObject *unicode_latin1[256];
-/* Default encoding to use and assume when NULL is passed as encoding
- parameter; it is fixed to "utf-8". Always use the
- PyUnicode_GetDefaultEncoding() API to access this global.
-
- Don't forget to alter Py_FileSystemDefaultEncoding if you change the
- hard coded default!
-*/
-static const char unicode_default_encoding[] = "utf-8";
-
/* Fast detection of the most frequent whitespace characters */
const unsigned char _Py_ascii_whitespace[] = {
0, 0, 0, 0, 0, 0, 0, 0,
-/* 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,
@@ -169,8 +157,10 @@ static void raise_encode_exception(PyObject **exceptionObject,
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 */
@@ -212,11 +202,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)] : \
@@ -226,12 +227,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;
}
@@ -651,7 +652,7 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
return NULL;
/* Copy the wchar_t data into the new object */
-#ifdef HAVE_USABLE_WCHAR_T
+#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
memcpy(unicode->str, w, size * sizeof(wchar_t));
#else
{
@@ -671,7 +672,8 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
#undef CONVERT_WCHAR_TO_SURROGATES
static void
-makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c)
+makefmt(char *fmt, int longflag, int longlongflag, int size_tflag,
+ int zeropad, int width, int precision, char c)
{
*fmt++ = '%';
if (width) {
@@ -683,6 +685,19 @@ makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int pre
fmt += sprintf(fmt, ".%d", precision);
if (longflag)
*fmt++ = 'l';
+ else if (longlongflag) {
+ /* longlongflag should only ever be nonzero on machines with
+ HAVE_LONG_LONG defined */
+#ifdef HAVE_LONG_LONG
+ char *f = PY_FORMAT_LONG_LONG;
+ while (*f)
+ *fmt++ = *f++;
+#else
+ /* we shouldn't ever get here */
+ assert(0);
+ *fmt++ = 'l';
+#endif
+ }
else if (size_tflag) {
char *f = PY_FORMAT_SIZE_T;
while (*f)
@@ -694,6 +709,16 @@ makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int pre
#define appendstring(string) {for (copy = string;*copy;) *s++ = *copy++;}
+/* size of fixed-size buffer for formatting single arguments */
+#define ITEM_BUFFER_LEN 21
+/* maximum number of characters required for output of %ld. 21 characters
+ allows for 64-bit integers (in decimal) and an optional sign. */
+#define MAX_LONG_CHARS 21
+/* maximum number of characters required for output of %lld.
+ We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+ plus 1 for the sign. 53/22 is an upper bound for log10(256). */
+#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22)
+
PyObject *
PyUnicode_FromFormatV(const char *format, va_list vargs)
{
@@ -709,24 +734,16 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
Py_UNICODE *s;
PyObject *string;
/* used by sprintf */
- char buffer[21];
+ char buffer[ITEM_BUFFER_LEN+1];
/* use abuffer instead of buffer, if we need more space
* (which can happen if there's a format specifier with width). */
char *abuffer = NULL;
char *realbuffer;
Py_ssize_t abuffersize = 0;
- char fmt[60]; /* should be enough for %0width.precisionld */
+ char fmt[61]; /* should be enough for %0width.precisionlld */
const char *copy;
-#ifdef VA_LIST_IS_ARRAY
- Py_MEMCPY(count, vargs, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(count, vargs);
-#else
- count = vargs;
-#endif
-#endif
+ Py_VA_COPY(count, vargs);
/* step 1: count the number of %S/%R/%A/%s format specifications
* (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII()/
* PyUnicode_DecodeUTF8() for these objects once during step 3 and put the
@@ -735,15 +752,22 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
if (*f == '%') {
if (*(f+1)=='%')
continue;
- if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A')
+ if (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A' || *(f+1) == 'V')
++callcount;
- while (ISDIGIT((unsigned)*f))
+ while (Py_ISDIGIT((unsigned)*f))
width = (width*10) + *f++ - '0';
- while (*++f && *f != '%' && !ISALPHA((unsigned)*f))
+ while (*++f && *f != '%' && !Py_ISALPHA((unsigned)*f))
;
if (*f == 's')
++callcount;
}
+ else if (128 <= (unsigned char)*f) {
+ PyErr_Format(PyExc_ValueError,
+ "PyUnicode_FromFormatV() expects an ASCII-encoded format "
+ "string, got a non-ASCII byte: 0x%02x",
+ (unsigned char)*f);
+ return NULL;
+ }
}
/* step 2: allocate memory for the results of
* PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() calls */
@@ -758,37 +782,70 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
/* step 3: figure out how large a buffer we need */
for (f = format; *f; f++) {
if (*f == '%') {
+#ifdef HAVE_LONG_LONG
+ int longlongflag = 0;
+#endif
const char* p = f;
width = 0;
- while (ISDIGIT((unsigned)*f))
+ while (Py_ISDIGIT((unsigned)*f))
width = (width*10) + *f++ - '0';
- while (*++f && *f != '%' && !ISALPHA((unsigned)*f))
+ while (*++f && *f != '%' && !Py_ISALPHA((unsigned)*f))
;
/* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
* 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':
+ {
+#ifndef Py_UNICODE_WIDE
+ int ordinal = va_arg(count, int);
+ if (ordinal > 0xffff)
+ n += 2;
+ else
+ n++;
+#else
(void)va_arg(count, int);
- /* fall through... */
+ n++;
+#endif
+ break;
+ }
case '%':
n++;
break;
case 'd': case 'u': case 'i': case 'x':
(void) va_arg(count, int);
- /* 20 bytes is enough to hold a 64-bit
- integer. Decimal takes the most space.
- This isn't enough for octal.
- If a width is specified we need more
- (which we allocate later). */
- if (width < 20)
- width = 20;
+#ifdef HAVE_LONG_LONG
+ if (longlongflag) {
+ if (width < MAX_LONG_LONG_CHARS)
+ width = MAX_LONG_LONG_CHARS;
+ }
+ else
+#endif
+ /* MAX_LONG_CHARS is enough to hold a 64-bit integer,
+ including sign. Decimal takes the most space. This
+ isn't enough for octal. If a width is specified we
+ need more (which we allocate later). */
+ if (width < MAX_LONG_CHARS)
+ width = MAX_LONG_CHARS;
n += width;
+ /* XXX should allow for large precision here too. */
if (abuffersize < width)
abuffersize = width;
break;
@@ -815,12 +872,20 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
{
PyObject *obj = va_arg(count, PyObject *);
const char *str = va_arg(count, const char *);
+ PyObject *str_obj;
assert(obj || str);
assert(!obj || PyUnicode_Check(obj));
- if (obj)
+ if (obj) {
n += PyUnicode_GET_SIZE(obj);
- else
- n += strlen(str);
+ *callresult++ = NULL;
+ }
+ else {
+ str_obj = PyUnicode_DecodeUTF8(str, strlen(str), "replace");
+ if (!str_obj)
+ goto fail;
+ n += PyUnicode_GET_SIZE(str_obj);
+ *callresult++ = str_obj;
+ }
break;
}
case 'S':
@@ -885,8 +950,9 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
n++;
}
expand:
- if (abuffersize > 20) {
- abuffer = PyObject_Malloc(abuffersize);
+ if (abuffersize > ITEM_BUFFER_LEN) {
+ /* add 1 for sprintf's trailing null byte */
+ abuffer = PyObject_Malloc(abuffersize + 1);
if (!abuffer) {
PyErr_NoMemory();
goto fail;
@@ -910,23 +976,32 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
if (*f == '%') {
const char* p = f++;
int longflag = 0;
+ int longlongflag = 0;
int size_tflag = 0;
zeropad = (*f == '0');
/* parse the width.precision part */
width = 0;
- while (ISDIGIT((unsigned)*f))
+ while (Py_ISDIGIT((unsigned)*f))
width = (width*10) + *f++ - '0';
precision = 0;
if (*f == '.') {
f++;
- while (ISDIGIT((unsigned)*f))
+ while (Py_ISDIGIT((unsigned)*f))
precision = (precision*10) + *f++ - '0';
}
- /* handle 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')) {
@@ -936,12 +1011,27 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
switch (*f) {
case 'c':
- *s++ = va_arg(vargs, int);
+ {
+ int ordinal = va_arg(vargs, int);
+#ifndef Py_UNICODE_WIDE
+ if (ordinal > 0xffff) {
+ ordinal -= 0x10000;
+ *s++ = 0xD800 | (ordinal >> 10);
+ *s++ = 0xDC00 | (ordinal & 0x3FF);
+ } else
+#endif
+ *s++ = ordinal;
break;
+ }
case 'd':
- makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'd');
+ makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
+ width, precision, 'd');
if (longflag)
sprintf(realbuffer, fmt, va_arg(vargs, long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(realbuffer, fmt, va_arg(vargs, PY_LONG_LONG));
+#endif
else if (size_tflag)
sprintf(realbuffer, fmt, va_arg(vargs, Py_ssize_t));
else
@@ -949,9 +1039,15 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
appendstring(realbuffer);
break;
case 'u':
- makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'u');
+ makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
+ width, precision, 'u');
if (longflag)
sprintf(realbuffer, fmt, va_arg(vargs, unsigned long));
+#ifdef HAVE_LONG_LONG
+ else if (longlongflag)
+ sprintf(realbuffer, fmt, va_arg(vargs,
+ unsigned PY_LONG_LONG));
+#endif
else if (size_tflag)
sprintf(realbuffer, fmt, va_arg(vargs, size_t));
else
@@ -959,12 +1055,12 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
appendstring(realbuffer);
break;
case 'i':
- makefmt(fmt, 0, 0, zeropad, width, precision, 'i');
+ makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'i');
sprintf(realbuffer, fmt, va_arg(vargs, int));
appendstring(realbuffer);
break;
case 'x':
- makefmt(fmt, 0, 0, zeropad, width, precision, 'x');
+ makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x');
sprintf(realbuffer, fmt, va_arg(vargs, int));
appendstring(realbuffer);
break;
@@ -992,18 +1088,23 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
case 'V':
{
PyObject *obj = va_arg(vargs, PyObject *);
- const char *str = va_arg(vargs, const char *);
+ va_arg(vargs, const char *);
if (obj) {
Py_ssize_t size = PyUnicode_GET_SIZE(obj);
Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(obj), size);
s += size;
} else {
- appendstring(str);
+ Py_UNICODE_COPY(s, PyUnicode_AS_UNICODE(*callresult),
+ PyUnicode_GET_SIZE(*callresult));
+ s += PyUnicode_GET_SIZE(*callresult);
+ Py_DECREF(*callresult);
}
+ ++callresult;
break;
}
case 'S':
case 'R':
+ case 'A':
{
Py_UNICODE *ucopy;
Py_ssize_t usize;
@@ -1039,7 +1140,8 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
appendstring(p);
goto end;
}
- } else
+ }
+ else
*s++ = *f;
}
@@ -1054,7 +1156,7 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
if (callresults) {
PyObject **callresult2 = callresults;
while (callresult2 < callresult) {
- Py_DECREF(*callresult2);
+ Py_XDECREF(*callresult2);
++callresult2;
}
PyObject_Free(callresults);
@@ -1082,35 +1184,154 @@ PyUnicode_FromFormat(const char *format, ...)
return ret;
}
-Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
- wchar_t *w,
- Py_ssize_t size)
+/* Helper function for PyUnicode_AsWideChar() and PyUnicode_AsWideCharString():
+ convert a Unicode object to a wide character string.
+
+ - If w is NULL: return the number of wide characters (including the nul
+ character) required to convert the unicode object. Ignore size argument.
+
+ - Otherwise: return the number of wide characters (excluding the nul
+ character) written into w. Write at most size wide characters (including
+ the nul character). */
+static Py_ssize_t
+unicode_aswidechar(PyUnicodeObject *unicode,
+ wchar_t *w,
+ Py_ssize_t size)
+{
+#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
+ Py_ssize_t res;
+ if (w != NULL) {
+ res = PyUnicode_GET_SIZE(unicode);
+ if (size > res)
+ size = res + 1;
+ else
+ res = size;
+ memcpy(w, unicode->str, size * sizeof(wchar_t));
+ return res;
+ }
+ else
+ return PyUnicode_GET_SIZE(unicode) + 1;
+#elif Py_UNICODE_SIZE == 2 && SIZEOF_WCHAR_T == 4
+ register const Py_UNICODE *u;
+ const Py_UNICODE *uend;
+ const wchar_t *worig, *wend;
+ Py_ssize_t nchar;
+
+ u = PyUnicode_AS_UNICODE(unicode);
+ uend = u + PyUnicode_GET_SIZE(unicode);
+ if (w != NULL) {
+ worig = w;
+ wend = w + size;
+ while (u != uend && w != wend) {
+ if (0xD800 <= u[0] && u[0] <= 0xDBFF
+ && 0xDC00 <= u[1] && u[1] <= 0xDFFF)
+ {
+ *w = (((u[0] & 0x3FF) << 10) | (u[1] & 0x3FF)) + 0x10000;
+ u += 2;
+ }
+ else {
+ *w = *u;
+ u++;
+ }
+ w++;
+ }
+ if (w != wend)
+ *w = L'\0';
+ return w - worig;
+ }
+ else {
+ nchar = 1; /* nul character at the end */
+ while (u != uend) {
+ if (0xD800 <= u[0] && u[0] <= 0xDBFF
+ && 0xDC00 <= u[1] && u[1] <= 0xDFFF)
+ u += 2;
+ else
+ u++;
+ nchar++;
+ }
+ }
+ return nchar;
+#elif Py_UNICODE_SIZE == 4 && SIZEOF_WCHAR_T == 2
+ register Py_UNICODE *u, *uend, ordinal;
+ register Py_ssize_t i;
+ wchar_t *worig, *wend;
+ Py_ssize_t nchar;
+
+ u = PyUnicode_AS_UNICODE(unicode);
+ uend = u + PyUnicode_GET_SIZE(u);
+ if (w != NULL) {
+ worig = w;
+ wend = w + size;
+ while (u != uend && w != wend) {
+ ordinal = *u;
+ if (ordinal > 0xffff) {
+ ordinal -= 0x10000;
+ *w++ = 0xD800 | (ordinal >> 10);
+ *w++ = 0xDC00 | (ordinal & 0x3FF);
+ }
+ else
+ *w++ = ordinal;
+ u++;
+ }
+ if (w != wend)
+ *w = 0;
+ return w - worig;
+ }
+ else {
+ nchar = 1; /* nul character */
+ while (u != uend) {
+ if (*u > 0xffff)
+ nchar += 2;
+ else
+ nchar++;
+ u++;
+ }
+ return nchar;
+ }
+#else
+# error "unsupported wchar_t and Py_UNICODE sizes, see issue #8670"
+#endif
+}
+
+Py_ssize_t
+PyUnicode_AsWideChar(PyObject *unicode,
+ wchar_t *w,
+ Py_ssize_t size)
{
if (unicode == NULL) {
PyErr_BadInternalCall();
return -1;
}
+ return unicode_aswidechar((PyUnicodeObject*)unicode, w, size);
+}
- /* If possible, try to copy the 0-termination as well */
- if (size > PyUnicode_GET_SIZE(unicode))
- size = PyUnicode_GET_SIZE(unicode) + 1;
+wchar_t*
+PyUnicode_AsWideCharString(PyObject *unicode,
+ Py_ssize_t *size)
+{
+ wchar_t* buffer;
+ Py_ssize_t buflen;
-#ifdef HAVE_USABLE_WCHAR_T
- memcpy(w, unicode->str, size * sizeof(wchar_t));
-#else
- {
- register Py_UNICODE *u;
- register Py_ssize_t i;
- u = PyUnicode_AS_UNICODE(unicode);
- for (i = size; i > 0; i--)
- *w++ = *u++;
+ if (unicode == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
}
-#endif
- if (size > PyUnicode_GET_SIZE(unicode))
- return PyUnicode_GET_SIZE(unicode);
- else
- return size;
+ buflen = unicode_aswidechar((PyUnicodeObject *)unicode, NULL, 0);
+ if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ buffer = PyMem_MALLOC(buflen * sizeof(wchar_t));
+ if (buffer == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ buflen = unicode_aswidechar((PyUnicodeObject *)unicode, buffer, buflen);
+ if (size != NULL)
+ *size = buflen;
+ return buffer;
}
#endif
@@ -1210,27 +1431,26 @@ PyObject *PyUnicode_FromEncodedObject(register PyObject *obj,
return v;
}
-PyObject *PyUnicode_Decode(const char *s,
- Py_ssize_t size,
- const char *encoding,
- const char *errors)
+/* Convert encoding to lower case and replace '_' with '-' in order to
+ catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1),
+ 1 on success. */
+static int
+normalize_encoding(const char *encoding,
+ char *lower,
+ size_t lower_len)
{
- PyObject *buffer = NULL, *unicode;
- Py_buffer info;
- char lower[20]; /* Enough for any encoding name we recognize */
- char *l;
const char *e;
+ char *l;
+ char *l_end;
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
-
- /* Convert encoding to lower case and replace '_' with '-' in order to
- catch e.g. UTF_8 */
e = encoding;
l = lower;
- while (*e && l < &lower[(sizeof lower) - 2]) {
- if (ISUPPER(*e)) {
- *l++ = TOLOWER(*e++);
+ l_end = &lower[lower_len - 1];
+ while (*e) {
+ if (l == l_end)
+ return 0;
+ if (Py_ISUPPER(*e)) {
+ *l++ = Py_TOLOWER(*e++);
}
else if (*e == '_') {
*l++ = '-';
@@ -1241,23 +1461,39 @@ PyObject *PyUnicode_Decode(const char *s,
}
}
*l = '\0';
+ return 1;
+}
+
+PyObject *PyUnicode_Decode(const char *s,
+ Py_ssize_t size,
+ const char *encoding,
+ const char *errors)
+{
+ PyObject *buffer = NULL, *unicode;
+ Py_buffer info;
+ char lower[11]; /* Enough for any encoding shortcut */
+
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
/* Shortcuts for common default encodings */
- if (strcmp(lower, "utf-8") == 0)
- return PyUnicode_DecodeUTF8(s, size, errors);
- else if ((strcmp(lower, "latin-1") == 0) ||
- (strcmp(lower, "iso-8859-1") == 0))
- return PyUnicode_DecodeLatin1(s, size, errors);
+ if (normalize_encoding(encoding, lower, sizeof(lower))) {
+ if (strcmp(lower, "utf-8") == 0)
+ return PyUnicode_DecodeUTF8(s, size, errors);
+ else if ((strcmp(lower, "latin-1") == 0) ||
+ (strcmp(lower, "iso-8859-1") == 0))
+ return PyUnicode_DecodeLatin1(s, size, errors);
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
- else if (strcmp(lower, "mbcs") == 0)
- return PyUnicode_DecodeMBCS(s, size, errors);
+ else if (strcmp(lower, "mbcs") == 0)
+ return PyUnicode_DecodeMBCS(s, size, errors);
#endif
- else if (strcmp(lower, "ascii") == 0)
- return PyUnicode_DecodeASCII(s, size, errors);
- else if (strcmp(lower, "utf-16") == 0)
- return PyUnicode_DecodeUTF16(s, size, errors, 0);
- else if (strcmp(lower, "utf-32") == 0)
- return PyUnicode_DecodeUTF32(s, size, errors, 0);
+ else if (strcmp(lower, "ascii") == 0)
+ return PyUnicode_DecodeASCII(s, size, errors);
+ else if (strcmp(lower, "utf-16") == 0)
+ return PyUnicode_DecodeUTF16(s, size, errors, 0);
+ else if (strcmp(lower, "utf-32") == 0)
+ return PyUnicode_DecodeUTF32(s, size, errors, 0);
+ }
/* Decode via the codec registry */
buffer = NULL;
@@ -1378,11 +1614,77 @@ PyObject *PyUnicode_AsEncodedObject(PyObject *unicode,
return NULL;
}
+PyObject *
+PyUnicode_EncodeFSDefault(PyObject *unicode)
+{
+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
+ return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ NULL);
+#elif defined(__APPLE__)
+ return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ "surrogateescape");
+#else
+ PyInterpreterState *interp = PyThreadState_GET()->interp;
+ /* Bootstrap check: if the filesystem codec is implemented in Python, we
+ cannot use it to encode and decode filenames before it is loaded. Load
+ the Python codec requires to encode at least its own filename. Use the C
+ version of the locale codec until the codec registry is initialized and
+ the Python codec is loaded.
+
+ Py_FileSystemDefaultEncoding is shared between all interpreters, we
+ cannot only rely on it: check also interp->fscodec_initialized for
+ subinterpreters. */
+ if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
+ return PyUnicode_AsEncodedString(unicode,
+ Py_FileSystemDefaultEncoding,
+ "surrogateescape");
+ }
+ else {
+ /* locale encoding with surrogateescape */
+ wchar_t *wchar;
+ char *bytes;
+ PyObject *bytes_obj;
+ size_t error_pos;
+
+ wchar = PyUnicode_AsWideCharString(unicode, NULL);
+ if (wchar == NULL)
+ return NULL;
+ bytes = _Py_wchar2char(wchar, &error_pos);
+ if (bytes == NULL) {
+ if (error_pos != (size_t)-1) {
+ char *errmsg = strerror(errno);
+ PyObject *exc = NULL;
+ if (errmsg == NULL)
+ errmsg = "Py_wchar2char() failed";
+ raise_encode_exception(&exc,
+ "filesystemencoding",
+ PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode),
+ error_pos, error_pos+1,
+ errmsg);
+ Py_XDECREF(exc);
+ }
+ else
+ PyErr_NoMemory();
+ PyMem_Free(wchar);
+ return NULL;
+ }
+ PyMem_Free(wchar);
+
+ bytes_obj = PyBytes_FromString(bytes);
+ PyMem_Free(bytes);
+ return bytes_obj;
+ }
+#endif
+}
+
PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
const char *encoding,
const char *errors)
{
PyObject *v;
+ char lower[11]; /* Enough for any encoding shortcut */
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
@@ -1393,31 +1695,42 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
encoding = PyUnicode_GetDefaultEncoding();
/* Shortcuts for common default encodings */
- if (errors == NULL) {
- if (strcmp(encoding, "utf-8") == 0)
- return PyUnicode_AsUTF8String(unicode);
- else if (strcmp(encoding, "latin-1") == 0)
- return PyUnicode_AsLatin1String(unicode);
+ if (normalize_encoding(encoding, lower, sizeof(lower))) {
+ if (strcmp(lower, "utf-8") == 0)
+ return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ errors);
+ else if ((strcmp(lower, "latin-1") == 0) ||
+ (strcmp(lower, "iso-8859-1") == 0))
+ return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ errors);
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
- else if (strcmp(encoding, "mbcs") == 0)
- return PyUnicode_AsMBCSString(unicode);
+ else if (strcmp(lower, "mbcs") == 0)
+ return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ errors);
#endif
- else if (strcmp(encoding, "ascii") == 0)
- return PyUnicode_AsASCIIString(unicode);
- /* During bootstrap, we may need to find the encodings
- package, to load the file system encoding, and require the
- file system encoding in order to load the encodings
- package.
-
- Break out of this dependency by assuming that the path to
- the encodings module is ASCII-only. XXX could try wcstombs
- instead, if the file system encoding is the locale's
- encoding. */
- else if (Py_FileSystemDefaultEncoding &&
- strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 &&
- !PyThreadState_GET()->interp->codecs_initialized)
- return PyUnicode_AsASCIIString(unicode);
- }
+ else if (strcmp(lower, "ascii") == 0)
+ return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ errors);
+ }
+ /* During bootstrap, we may need to find the encodings
+ package, to load the file system encoding, and require the
+ file system encoding in order to load the encodings
+ package.
+
+ Break out of this dependency by assuming that the path to
+ the encodings module is ASCII-only. XXX could try wcstombs
+ instead, if the file system encoding is the locale's
+ encoding. */
+ if (Py_FileSystemDefaultEncoding &&
+ strcmp(encoding, Py_FileSystemDefaultEncoding) == 0 &&
+ !PyThreadState_GET()->interp->codecs_initialized)
+ return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode),
+ PyUnicode_GET_SIZE(unicode),
+ errors);
/* Encode via the codec registry */
v = PyCodec_Encode(unicode, encoding, errors);
@@ -1430,12 +1743,13 @@ PyObject *PyUnicode_AsEncodedString(PyObject *unicode,
/* If the codec returns a buffer, raise a warning and convert to bytes */
if (PyByteArray_Check(v)) {
- char msg[100];
+ int error;
PyObject *b;
- PyOS_snprintf(msg, sizeof(msg),
- "encoder %s returned buffer instead of bytes",
- encoding);
- if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
+
+ error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
+ "encoder %s returned bytearray instead of bytes",
+ encoding);
+ if (error) {
Py_DECREF(v);
return NULL;
}
@@ -1509,32 +1823,48 @@ PyUnicode_DecodeFSDefault(const char *s) {
PyObject*
PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
{
- /* During the early bootstrapping process, Py_FileSystemDefaultEncoding
- can be undefined. If it is case, decode using UTF-8. The following assumes
- that Py_FileSystemDefaultEncoding is set to a built-in encoding during the
- bootstrapping process where the codecs aren't ready yet.
- */
- if (Py_FileSystemDefaultEncoding) {
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
- if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) {
- return PyUnicode_DecodeMBCS(s, size, "replace");
- }
+ return PyUnicode_DecodeMBCS(s, size, NULL);
#elif defined(__APPLE__)
- if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) {
- return PyUnicode_DecodeUTF8(s, size, "replace");
- }
-#endif
+ return PyUnicode_DecodeUTF8(s, size, "surrogateescape");
+#else
+ PyInterpreterState *interp = PyThreadState_GET()->interp;
+ /* Bootstrap check: if the filesystem codec is implemented in Python, we
+ cannot use it to encode and decode filenames before it is loaded. Load
+ the Python codec requires to encode at least its own filename. Use the C
+ version of the locale codec until the codec registry is initialized and
+ the Python codec is loaded.
+
+ Py_FileSystemDefaultEncoding is shared between all interpreters, we
+ cannot only rely on it: check also interp->fscodec_initialized for
+ subinterpreters. */
+ if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
return PyUnicode_Decode(s, size,
Py_FileSystemDefaultEncoding,
- "replace");
+ "surrogateescape");
}
else {
- return PyUnicode_DecodeUTF8(s, size, "replace");
+ /* locale encoding with surrogateescape */
+ wchar_t *wchar;
+ PyObject *unicode;
+ size_t len;
+
+ if (s[size] != '\0' || size != strlen(s)) {
+ PyErr_SetString(PyExc_TypeError, "embedded NUL character");
+ return NULL;
+ }
+
+ wchar = _Py_char2wchar(s, &len);
+ if (wchar == NULL)
+ return PyErr_NoMemory();
+
+ unicode = PyUnicode_FromWideChar(wchar, len);
+ PyMem_Free(wchar);
+ return unicode;
}
+#endif
}
-/* Convert the argument to a bytes object, according to the file
- system encoding */
int
PyUnicode_FSConverter(PyObject* arg, void* addr)
@@ -1546,7 +1876,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr)
Py_DECREF(*(PyObject**)addr);
return 1;
}
- if (PyBytes_Check(arg) || PyByteArray_Check(arg)) {
+ if (PyBytes_Check(arg)) {
output = arg;
Py_INCREF(output);
}
@@ -1554,9 +1884,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr)
arg = PyUnicode_FromObject(arg);
if (!arg)
return 0;
- output = PyUnicode_AsEncodedObject(arg,
- Py_FileSystemDefaultEncoding,
- "surrogateescape");
+ output = PyUnicode_EncodeFSDefault(arg);
Py_DECREF(arg);
if (!output)
return 0;
@@ -1566,15 +1894,50 @@ PyUnicode_FSConverter(PyObject* arg, void* addr)
return 0;
}
}
- if (PyBytes_Check(output)) {
- size = PyBytes_GET_SIZE(output);
- data = PyBytes_AS_STRING(output);
+ size = PyBytes_GET_SIZE(output);
+ data = PyBytes_AS_STRING(output);
+ if (size != strlen(data)) {
+ PyErr_SetString(PyExc_TypeError, "embedded NUL character");
+ Py_DECREF(output);
+ return 0;
+ }
+ *(PyObject**)addr = output;
+ return Py_CLEANUP_SUPPORTED;
+}
+
+
+int
+PyUnicode_FSDecoder(PyObject* arg, void* addr)
+{
+ PyObject *output = NULL;
+ Py_ssize_t size;
+ void *data;
+ if (arg == NULL) {
+ Py_DECREF(*(PyObject**)addr);
+ return 1;
+ }
+ if (PyUnicode_Check(arg)) {
+ output = arg;
+ Py_INCREF(output);
}
else {
- size = PyByteArray_GET_SIZE(output);
- data = PyByteArray_AS_STRING(output);
+ arg = PyBytes_FromObject(arg);
+ if (!arg)
+ return 0;
+ output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(arg),
+ PyBytes_GET_SIZE(arg));
+ Py_DECREF(arg);
+ if (!output)
+ return 0;
+ if (!PyUnicode_Check(output)) {
+ Py_DECREF(output);
+ PyErr_SetString(PyExc_TypeError, "decoder failed to return unicode");
+ return 0;
+ }
}
- if (size != strlen(data)) {
+ size = PyUnicode_GET_SIZE(output);
+ data = PyUnicode_AS_UNICODE(output);
+ if (size != Py_UNICODE_strlen(data)) {
PyErr_SetString(PyExc_TypeError, "embedded NUL character");
Py_DECREF(output);
return 0;
@@ -1632,18 +1995,34 @@ Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
const char *PyUnicode_GetDefaultEncoding(void)
{
- return unicode_default_encoding;
+ return "utf-8";
}
-int PyUnicode_SetDefaultEncoding(const char *encoding)
+/* create or adjust a UnicodeDecodeError */
+static void
+make_decode_exception(PyObject **exceptionObject,
+ const char *encoding,
+ const char *input, Py_ssize_t length,
+ Py_ssize_t startpos, Py_ssize_t endpos,
+ const char *reason)
{
- if (strcmp(encoding, unicode_default_encoding) != 0) {
- PyErr_Format(PyExc_ValueError,
- "Can only set default encoding to %s",
- unicode_default_encoding);
- return -1;
+ if (*exceptionObject == NULL) {
+ *exceptionObject = PyUnicodeDecodeError_Create(
+ encoding, input, length, startpos, endpos, reason);
}
- return 0;
+ else {
+ if (PyUnicodeDecodeError_SetStart(*exceptionObject, startpos))
+ goto onError;
+ if (PyUnicodeDecodeError_SetEnd(*exceptionObject, endpos))
+ goto onError;
+ if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
+ goto onError;
+ }
+ return;
+
+onError:
+ Py_DECREF(*exceptionObject);
+ *exceptionObject = NULL;
}
/* error handling callback helper:
@@ -1679,20 +2058,13 @@ int unicode_decode_call_errorhandler(const char *errors, PyObject **errorHandler
goto onError;
}
- if (*exceptionObject == NULL) {
- *exceptionObject = PyUnicodeDecodeError_Create(
- encoding, *input, *inend-*input, *startinpos, *endinpos, reason);
- if (*exceptionObject == NULL)
- goto onError;
- }
- else {
- if (PyUnicodeDecodeError_SetStart(*exceptionObject, *startinpos))
- goto onError;
- if (PyUnicodeDecodeError_SetEnd(*exceptionObject, *endinpos))
- goto onError;
- if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
- goto onError;
- }
+ make_decode_exception(exceptionObject,
+ encoding,
+ *input, *inend - *input,
+ *startinpos, *endinpos,
+ reason);
+ if (*exceptionObject == NULL)
+ goto onError;
restuple = PyObject_CallFunctionObjArgs(*errorHandler, *exceptionObject, NULL);
if (restuple == NULL)
@@ -2408,6 +2780,120 @@ PyObject *PyUnicode_DecodeUTF8Stateful(const char *s,
#undef ASCII_CHAR_MASK
+#ifdef __APPLE__
+
+/* Simplified UTF-8 decoder using surrogateescape error handler,
+ used to decode the command line arguments on Mac OS X. */
+
+wchar_t*
+_Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size)
+{
+ int n;
+ const char *e;
+ wchar_t *unicode, *p;
+
+ /* Note: size will always be longer than the resulting Unicode
+ character count */
+ if (PY_SSIZE_T_MAX / sizeof(wchar_t) < (size + 1)) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ unicode = PyMem_Malloc((size + 1) * sizeof(wchar_t));
+ if (!unicode)
+ return NULL;
+
+ /* Unpack UTF-8 encoded data */
+ p = unicode;
+ e = s + size;
+ while (s < e) {
+ Py_UCS4 ch = (unsigned char)*s;
+
+ if (ch < 0x80) {
+ *p++ = (wchar_t)ch;
+ s++;
+ continue;
+ }
+
+ n = utf8_code_length[ch];
+ if (s + n > e) {
+ goto surrogateescape;
+ }
+
+ switch (n) {
+ case 0:
+ case 1:
+ goto surrogateescape;
+
+ case 2:
+ if ((s[1] & 0xc0) != 0x80)
+ goto surrogateescape;
+ ch = ((s[0] & 0x1f) << 6) + (s[1] & 0x3f);
+ assert ((ch > 0x007F) && (ch <= 0x07FF));
+ *p++ = (wchar_t)ch;
+ break;
+
+ case 3:
+ /* Decoding UTF-8 sequences in range \xed\xa0\x80-\xed\xbf\xbf
+ will result in surrogates in range d800-dfff. Surrogates are
+ not valid UTF-8 so they are rejected.
+ See http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf
+ (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ ((unsigned char)s[0] == 0xE0 &&
+ (unsigned char)s[1] < 0xA0) ||
+ ((unsigned char)s[0] == 0xED &&
+ (unsigned char)s[1] > 0x9F)) {
+
+ goto surrogateescape;
+ }
+ ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f);
+ assert ((ch > 0x07FF) && (ch <= 0xFFFF));
+ *p++ = (Py_UNICODE)ch;
+ break;
+
+ case 4:
+ if ((s[1] & 0xc0) != 0x80 ||
+ (s[2] & 0xc0) != 0x80 ||
+ (s[3] & 0xc0) != 0x80 ||
+ ((unsigned char)s[0] == 0xF0 &&
+ (unsigned char)s[1] < 0x90) ||
+ ((unsigned char)s[0] == 0xF4 &&
+ (unsigned char)s[1] > 0x8F)) {
+ goto surrogateescape;
+ }
+ ch = ((s[0] & 0x7) << 18) + ((s[1] & 0x3f) << 12) +
+ ((s[2] & 0x3f) << 6) + (s[3] & 0x3f);
+ assert ((ch > 0xFFFF) && (ch <= 0x10ffff));
+
+#if SIZEOF_WCHAR_T == 4
+ *p++ = (wchar_t)ch;
+#else
+ /* compute and append the two surrogates: */
+
+ /* translate from 10000..10FFFF to 0..FFFF */
+ ch -= 0x10000;
+
+ /* high surrogate = top 10 bits added to D800 */
+ *p++ = (wchar_t)(0xD800 + (ch >> 10));
+
+ /* low surrogate = bottom 10 bits added to DC00 */
+ *p++ = (wchar_t)(0xDC00 + (ch & 0x03FF));
+#endif
+ break;
+ }
+ s += n;
+ continue;
+
+ surrogateescape:
+ *p++ = 0xDC00 + ch;
+ s++;
+ }
+ *p = L'\0';
+ return unicode;
+}
+
+#endif /* __APPLE__ */
/* Allocation strategy: if the string is short, convert into a stack buffer
and allocate exactly as much space needed at the end. Else allocate the
@@ -3366,7 +3852,7 @@ PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
}
for (i = 0; i < digits; ++i) {
c = (unsigned char) s[i];
- if (!ISXDIGIT(c)) {
+ if (!Py_ISXDIGIT(c)) {
endinpos = (s+i+1)-starts;
if (unicode_decode_call_errorhandler(
errors, &errorHandler,
@@ -3732,7 +4218,7 @@ PyObject *PyUnicode_DecodeRawUnicodeEscape(const char *s,
outpos = p-PyUnicode_AS_UNICODE(v);
for (x = 0, i = 0; i < count; ++i, ++s) {
c = (unsigned char)*s;
- if (!ISXDIGIT(c)) {
+ if (!Py_ISXDIGIT(c)) {
endinpos = s-starts;
if (unicode_decode_call_errorhandler(
errors, &errorHandler,
@@ -4431,32 +4917,46 @@ static int is_dbcs_lead_byte(const char *s, int offset)
static int decode_mbcs(PyUnicodeObject **v,
const char *s, /* MBCS string */
int size, /* sizeof MBCS string */
- int final)
+ int final,
+ const char *errors)
{
Py_UNICODE *p;
- Py_ssize_t n = 0;
- int usize = 0;
+ Py_ssize_t n;
+ DWORD usize;
+ DWORD flags;
assert(size >= 0);
+ /* check and handle 'errors' arg */
+ if (errors==NULL || strcmp(errors, "strict")==0)
+ flags = MB_ERR_INVALID_CHARS;
+ else if (strcmp(errors, "ignore")==0)
+ flags = 0;
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "mbcs encoding does not support errors='%s'",
+ errors);
+ return -1;
+ }
+
/* Skip trailing lead-byte unless 'final' is set */
if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1))
--size;
/* First get the size of the result */
if (size > 0) {
- usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0);
- if (usize == 0) {
- PyErr_SetFromWindowsErrWithFilename(0, NULL);
- return -1;
- }
- }
+ usize = MultiByteToWideChar(CP_ACP, flags, s, size, NULL, 0);
+ if (usize==0)
+ goto mbcs_decode_error;
+ } else
+ usize = 0;
if (*v == NULL) {
/* Create unicode object */
*v = _PyUnicode_New(usize);
if (*v == NULL)
return -1;
+ n = 0;
}
else {
/* Extend unicode object */
@@ -4466,15 +4966,35 @@ static int decode_mbcs(PyUnicodeObject **v,
}
/* Do the conversion */
- if (size > 0) {
+ if (usize > 0) {
p = PyUnicode_AS_UNICODE(*v) + n;
- if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) {
- PyErr_SetFromWindowsErrWithFilename(0, NULL);
- return -1;
+ if (0 == MultiByteToWideChar(CP_ACP, flags, s, size, p, usize)) {
+ goto mbcs_decode_error;
}
}
-
return size;
+
+mbcs_decode_error:
+ /* If the last error was ERROR_NO_UNICODE_TRANSLATION, then
+ we raise a UnicodeDecodeError - else it is a 'generic'
+ windows error
+ */
+ if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) {
+ /* Ideally, we should get reason from FormatMessage - this
+ is the Windows 2000 English version of the message
+ */
+ PyObject *exc = NULL;
+ const char *reason = "No mapping for the Unicode character exists "
+ "in the target multi-byte code page.";
+ make_decode_exception(&exc, "mbcs", s, size, 0, 0, reason);
+ if (exc != NULL) {
+ PyCodec_StrictErrors(exc);
+ Py_DECREF(exc);
+ }
+ } else {
+ PyErr_SetFromWindowsErrWithFilename(0, NULL);
+ }
+ return -1;
}
PyObject *PyUnicode_DecodeMBCSStateful(const char *s,
@@ -4491,10 +5011,10 @@ PyObject *PyUnicode_DecodeMBCSStateful(const char *s,
#ifdef NEED_RETRY
retry:
if (size > INT_MAX)
- done = decode_mbcs(&v, s, INT_MAX, 0);
+ done = decode_mbcs(&v, s, INT_MAX, 0, errors);
else
#endif
- done = decode_mbcs(&v, s, (int)size, !consumed);
+ done = decode_mbcs(&v, s, (int)size, !consumed, errors);
if (done < 0) {
Py_XDECREF(v);
@@ -4528,20 +5048,45 @@ PyObject *PyUnicode_DecodeMBCS(const char *s,
*/
static int encode_mbcs(PyObject **repr,
const Py_UNICODE *p, /* unicode */
- int size) /* size of unicode */
+ int size, /* size of unicode */
+ const char* errors)
{
- int mbcssize = 0;
- Py_ssize_t n = 0;
+ BOOL usedDefaultChar = FALSE;
+ BOOL *pusedDefaultChar;
+ int mbcssize;
+ Py_ssize_t n;
+ PyObject *exc = NULL;
+ DWORD flags;
assert(size >= 0);
+ /* check and handle 'errors' arg */
+ if (errors==NULL || strcmp(errors, "strict")==0) {
+ flags = WC_NO_BEST_FIT_CHARS;
+ pusedDefaultChar = &usedDefaultChar;
+ } else if (strcmp(errors, "replace")==0) {
+ flags = 0;
+ pusedDefaultChar = NULL;
+ } else {
+ PyErr_Format(PyExc_ValueError,
+ "mbcs encoding does not support errors='%s'",
+ errors);
+ return -1;
+ }
+
/* First get the size of the result */
if (size > 0) {
- mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL);
+ mbcssize = WideCharToMultiByte(CP_ACP, flags, p, size, NULL, 0,
+ NULL, pusedDefaultChar);
if (mbcssize == 0) {
PyErr_SetFromWindowsErrWithFilename(0, NULL);
return -1;
}
+ /* If we used a default char, then we failed! */
+ if (pusedDefaultChar && *pusedDefaultChar)
+ goto mbcs_encode_error;
+ } else {
+ mbcssize = 0;
}
if (*repr == NULL) {
@@ -4549,6 +5094,7 @@ static int encode_mbcs(PyObject **repr,
*repr = PyBytes_FromStringAndSize(NULL, mbcssize);
if (*repr == NULL)
return -1;
+ n = 0;
}
else {
/* Extend string object */
@@ -4560,13 +5106,20 @@ static int encode_mbcs(PyObject **repr,
/* Do the conversion */
if (size > 0) {
char *s = PyBytes_AS_STRING(*repr) + n;
- if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) {
+ if (0 == WideCharToMultiByte(CP_ACP, flags, p, size, s, mbcssize,
+ NULL, pusedDefaultChar)) {
PyErr_SetFromWindowsErrWithFilename(0, NULL);
return -1;
}
+ if (pusedDefaultChar && *pusedDefaultChar)
+ goto mbcs_encode_error;
}
-
return 0;
+
+mbcs_encode_error:
+ raise_encode_exception(&exc, "mbcs", p, size, 0, 0, "invalid character");
+ Py_XDECREF(exc);
+ return -1;
}
PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,
@@ -4579,10 +5132,10 @@ PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,
#ifdef NEED_RETRY
retry:
if (size > INT_MAX)
- ret = encode_mbcs(&repr, p, INT_MAX);
+ ret = encode_mbcs(&repr, p, INT_MAX, errors);
else
#endif
- ret = encode_mbcs(&repr, p, (int)size);
+ ret = encode_mbcs(&repr, p, (int)size, errors);
if (ret < 0) {
Py_XDECREF(repr);
@@ -5699,6 +6252,30 @@ PyObject *PyUnicode_Translate(PyObject *str,
return NULL;
}
+PyObject *
+PyUnicode_TransformDecimalToASCII(Py_UNICODE *s,
+ Py_ssize_t length)
+{
+ PyObject *result;
+ Py_UNICODE *p; /* write pointer into result */
+ Py_ssize_t i;
+ /* Copy to a new string */
+ result = (PyObject *)_PyUnicode_New(length);
+ Py_UNICODE_COPY(PyUnicode_AS_UNICODE(result), s, length);
+ if (result == NULL)
+ return result;
+ p = PyUnicode_AS_UNICODE(result);
+ /* Iterate over code points */
+ for (i = 0; i < length; i++) {
+ Py_UNICODE ch =s[i];
+ if (ch > 127) {
+ int decimal = Py_UNICODE_TODECIMAL(ch);
+ if (decimal >= 0)
+ p[i] = '0' + decimal;
+ }
+ }
+ return result;
+}
/* --- Decimal Encoder ---------------------------------------------------- */
int PyUnicode_EncodeDecimal(Py_UNICODE *s,
@@ -5840,28 +6417,30 @@ int PyUnicode_EncodeDecimal(Py_UNICODE *s,
#include "stringlib/unicodedefs.h"
#include "stringlib/fastsearch.h"
+
#include "stringlib/count.h"
-/* Include _ParseTupleFinds from find.h */
-#define FROM_UNICODE
#include "stringlib/find.h"
#include "stringlib/partition.h"
+#include "stringlib/split.h"
#define _Py_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping
#define _Py_InsertThousandsGroupingLocale _PyUnicode_InsertThousandsGroupingLocale
#include "stringlib/localeutil.h"
/* helper macro to fixup start/end slice values */
-#define FIX_START_END(obj) \
- if (start < 0) \
- start += (obj)->length; \
- if (start < 0) \
- start = 0; \
- if (end > (obj)->length) \
- end = (obj)->length; \
- if (end < 0) \
- end += (obj)->length; \
- if (end < 0) \
- end = 0;
+#define ADJUST_INDICES(start, end, len) \
+ if (end > len) \
+ end = len; \
+ else if (end < 0) { \
+ end += len; \
+ if (end < 0) \
+ end = 0; \
+ } \
+ if (start < 0) { \
+ start += len; \
+ if (start < 0) \
+ start = 0; \
+ }
Py_ssize_t PyUnicode_Count(PyObject *str,
PyObject *substr,
@@ -5881,10 +6460,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);
@@ -5939,8 +6518,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;
@@ -6281,305 +6859,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)
+PyObject *PyUnicode_Splitlines(PyObject *string, int keepends)
{
- 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)
-{
- 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;
+ list = stringlib_splitlines(
+ (PyObject*) string, PyUnicode_AS_UNICODE(string),
+ PyUnicode_GET_SIZE(string), keepends);
- /* 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;
-
- 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
@@ -6587,28 +6900,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
@@ -6621,10 +6925,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;
@@ -6643,8 +6951,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;
@@ -6652,14 +6960,20 @@ PyObject *replace(PyUnicodeObject *self,
if (!u)
return NULL;
Py_UNICODE_COPY(u->str, self->str, self->length);
- while (i <= self->length - str1->length)
- if (Py_UNICODE_MATCH(self, i, str1)) {
- if (--maxcount < 0)
- break;
- Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
- i += str1->length;
- } else
- i++;
+
+ /* change everything in-place, starting with this one */
+ Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+ i += str1->length;
+
+ while ( --maxcount > 0) {
+ i = stringlib_find(self->str+i, self->length-i,
+ str1->str, str1->length,
+ i);
+ if (i == -1)
+ break;
+ Py_UNICODE_COPY(u->str+i, str2->str, str2->length);
+ i += str1->length;
+ }
}
} else {
@@ -6668,9 +6982,8 @@ PyObject *replace(PyUnicodeObject *self,
Py_UNICODE *p;
/* replace strings */
- n = stringlib_count(self->str, self->length, str1->str, str1->length);
- if (n > maxcount)
- n = maxcount;
+ n = stringlib_count(self->str, self->length, str1->str, str1->length,
+ maxcount);
if (n == 0)
goto nothing;
/* new_size = self->length + n * (str2->length - str1->length)); */
@@ -6700,15 +7013,12 @@ PyObject *replace(PyUnicodeObject *self,
if (str1->length > 0) {
while (n-- > 0) {
/* look for next match */
- j = i;
- while (j <= e) {
- if (Py_UNICODE_MATCH(self, j, str1))
- break;
- j++;
- }
- if (j > i) {
- if (j > e)
- break;
+ j = stringlib_find(self->str+i, self->length-i,
+ str1->str, str1->length,
+ i);
+ if (j == -1)
+ break;
+ else if (j > i) {
/* copy unchanged part [i:j] */
Py_UNICODE_COPY(p, self->str+i, j-i);
p += j - i;
@@ -6970,10 +7280,7 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
return ((int)id[i] < (int)str[i]) ? -1 : 1;
/* This check keeps Python strings that end in '\0' from comparing equal
to C strings identical up to that point. */
- if (PyUnicode_GET_SIZE(uni) != i)
- /* We'll say the Python string is longer. */
- return 1;
- if (id[i])
+ if (PyUnicode_GET_SIZE(uni) != i || id[i])
return 1; /* uni is longer */
if (str[i])
return -1; /* str is longer */
@@ -7154,11 +7461,11 @@ unicode_count(PyUnicodeObject *self, PyObject *args)
&start, &end))
return NULL;
- FIX_START_END(self);
-
+ ADJUST_INDICES(start, end, self->length);
result = PyLong_FromSsize_t(
stringlib_count(self->str + start, end - start,
- substring->str, substring->length)
+ substring->str, substring->length,
+ PY_SSIZE_T_MAX)
);
Py_DECREF(substring);
@@ -7167,39 +7474,26 @@ unicode_count(PyUnicodeObject *self, PyObject *args)
}
PyDoc_STRVAR(encode__doc__,
- "S.encode([encoding[, errors]]) -> bytes\n\
+ "S.encode(encoding='utf-8', errors='strict') -> bytes\n\
\n\
-Encode S using the codec registered for encoding. encoding defaults\n\
-to the default encoding. errors may be given to set a different error\n\
+Encode S using the codec registered for encoding. Default encoding\n\
+is 'utf-8'. errors may be given to set a different error\n\
handling scheme. Default is 'strict' meaning that encoding errors raise\n\
a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and\n\
'xmlcharrefreplace' as well as any other name registered with\n\
codecs.register_error that can handle UnicodeEncodeErrors.");
static PyObject *
-unicode_encode(PyUnicodeObject *self, PyObject *args)
+unicode_encode(PyUnicodeObject *self, PyObject *args, PyObject *kwargs)
{
+ static char *kwlist[] = {"encoding", "errors", 0};
char *encoding = NULL;
char *errors = NULL;
- PyObject *v;
- if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:encode",
+ kwlist, &encoding, &errors))
return NULL;
- v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors);
- if (v == NULL)
- goto onError;
- if (!PyBytes_Check(v)) {
- PyErr_Format(PyExc_TypeError,
- "encoder did not return a bytes object "
- "(type=%.400s)",
- Py_TYPE(v)->tp_name);
- Py_DECREF(v);
- return NULL;
- }
- return v;
-
- onError:
- return NULL;
+ return PyUnicode_AsEncodedString((PyObject *)self, encoding, errors);
}
PyDoc_STRVAR(expandtabs__doc__,
@@ -7334,12 +7628,12 @@ unicode_getitem(PyUnicodeObject *self, Py_ssize_t index)
/* Believe it or not, this produces the same value for ASCII strings
as string_hash(). */
-static long
+static Py_hash_t
unicode_hash(PyUnicodeObject *self)
{
Py_ssize_t len;
Py_UNICODE *p;
- long x;
+ Py_hash_t x;
if (self->hash != -1)
return self->hash;
@@ -8704,6 +8998,13 @@ unicode_freelistsize(PyUnicodeObject *self)
{
return PyLong_FromLong(numfree);
}
+
+static PyObject *
+unicode__decimal2ascii(PyObject *self)
+{
+ return PyUnicode_TransformDecimalToASCII(PyUnicode_AS_UNICODE(self),
+ PyUnicode_GET_SIZE(self));
+}
#endif
PyDoc_STRVAR(startswith__doc__,
@@ -8810,6 +9111,12 @@ PyDoc_STRVAR(format__doc__,
Return a formatted version of S, using substitutions from args and kwargs.\n\
The substitutions are identified by braces ('{' and '}').");
+PyDoc_STRVAR(format_map__doc__,
+ "S.format_map(mapping) -> str\n\
+\n\
+Return a formatted version of S, using substitutions from mapping.\n\
+The substitutions are identified by braces ('{' and '}').");
+
static PyObject *
unicode__format__(PyObject* self, PyObject* args)
{
@@ -8844,13 +9151,12 @@ unicode_getnewargs(PyUnicodeObject *v)
return Py_BuildValue("(u#)", v->str, v->length);
}
-
static PyMethodDef unicode_methods[] = {
/* Order is according to common usage: often used methods should
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__},
@@ -8891,9 +9197,8 @@ static PyMethodDef unicode_methods[] = {
{"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__},
{"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
{"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
+ {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__},
{"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
- {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS},
- {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
{"maketrans", (PyCFunction) unicode_maketrans,
METH_VARARGS | METH_STATIC, maketrans__doc__},
{"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
@@ -8902,8 +9207,9 @@ static PyMethodDef unicode_methods[] = {
#endif
#if 0
- /* This one is just used for debugging the implementation. */
+ /* These methods are just used for debugging the implementation. */
{"freelistsize", (PyCFunction) unicode_freelistsize, METH_NOARGS},
+ {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS},
#endif
{"__getnewargs__", (PyCFunction)unicode_getnewargs, METH_NOARGS},
@@ -8954,7 +9260,7 @@ unicode_subscript(PyUnicodeObject* self, PyObject* item)
Py_UNICODE* result_buf;
PyObject* result;
- if (PySlice_GetIndicesEx((PySliceObject*)item, PyUnicode_GET_SIZE(self),
+ if (PySlice_GetIndicesEx(item, PyUnicode_GET_SIZE(self),
&start, &stop, &step, &slicelength) < 0) {
return NULL;
}
@@ -10008,6 +10314,15 @@ Py_UNICODE_strncpy(Py_UNICODE *s1, const Py_UNICODE *s2, size_t n)
return s1;
}
+Py_UNICODE*
+Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2)
+{
+ Py_UNICODE *u1 = s1;
+ u1 += Py_UNICODE_strlen(u1);
+ Py_UNICODE_strcpy(u1, s2);
+ return s1;
+}
+
int
Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2)
{
@@ -10022,6 +10337,23 @@ Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2)
return 0;
}
+int
+Py_UNICODE_strncmp(const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n)
+{
+ register Py_UNICODE u1, u2;
+ for (; n != 0; n--) {
+ u1 = *s1;
+ u2 = *s2;
+ if (u1 != u2)
+ return (u1 < u2) ? -1 : +1;
+ if (u1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
Py_UNICODE*
Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c)
{
@@ -10032,15 +10364,72 @@ Py_UNICODE_strchr(const Py_UNICODE *s, Py_UNICODE c)
return NULL;
}
+Py_UNICODE*
+Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c)
+{
+ const Py_UNICODE *p;
+ p = s + Py_UNICODE_strlen(s);
+ while (p != s) {
+ p--;
+ if (*p == c)
+ return (Py_UNICODE*)p;
+ }
+ return NULL;
+}
-#ifdef __cplusplus
+Py_UNICODE*
+PyUnicode_AsUnicodeCopy(PyObject *object)
+{
+ PyUnicodeObject *unicode = (PyUnicodeObject *)object;
+ Py_UNICODE *copy;
+ Py_ssize_t size;
+
+ /* Ensure we won't overflow the size. */
+ if (PyUnicode_GET_SIZE(unicode) > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ size = PyUnicode_GET_SIZE(unicode) + 1; /* copy the nul character */
+ size *= sizeof(Py_UNICODE);
+ copy = PyMem_Malloc(size);
+ if (copy == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memcpy(copy, PyUnicode_AS_UNICODE(unicode), size);
+ return copy;
}
-#endif
+/* A _string module, to export formatter_parser and formatter_field_name_split
+ to the string.Formatter class implemented in Python. */
-/*
- Local variables:
- c-basic-offset: 4
- indent-tabs-mode: nil
- End:
-*/
+static PyMethodDef _string_methods[] = {
+ {"formatter_field_name_split", (PyCFunction) formatter_field_name_split,
+ METH_O, PyDoc_STR("split the argument as a field name")},
+ {"formatter_parser", (PyCFunction) formatter_parser,
+ METH_O, PyDoc_STR("parse the argument as a format string")},
+ {NULL, NULL}
+};
+
+static struct PyModuleDef _string_module = {
+ PyModuleDef_HEAD_INIT,
+ "_string",
+ PyDoc_STR("string helper module"),
+ 0,
+ _string_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+PyMODINIT_FUNC
+PyInit__string(void)
+{
+ return PyModule_Create(&_string_module);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h
index f46f1fb..88a7912 100644
--- a/Objects/unicodetype_db.h
+++ b/Objects/unicodetype_db.h
@@ -1,4 +1,4 @@
-/* this file was generated by Tools/unicode/makeunicodedata.py 2.6 */
+/* this file was generated by Tools/unicode/makeunicodedata.py 3.2 */
/* a list of unique character type descriptors */
const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
@@ -8,24 +8,25 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 0, 0, 0, 0, 48},
{0, 0, 0, 0, 0, 1056},
{0, 0, 0, 0, 0, 1024},
- {0, 0, 0, 0, 0, 1542},
- {0, 0, 0, 1, 1, 1542},
- {0, 0, 0, 2, 2, 1542},
- {0, 0, 0, 3, 3, 1542},
- {0, 0, 0, 4, 4, 1542},
- {0, 0, 0, 5, 5, 1542},
- {0, 0, 0, 6, 6, 1542},
- {0, 0, 0, 7, 7, 1542},
- {0, 0, 0, 8, 8, 1542},
- {0, 0, 0, 9, 9, 1542},
+ {0, 0, 0, 0, 0, 5638},
+ {0, 0, 0, 1, 1, 5638},
+ {0, 0, 0, 2, 2, 5638},
+ {0, 0, 0, 3, 3, 5638},
+ {0, 0, 0, 4, 4, 5638},
+ {0, 0, 0, 5, 5, 5638},
+ {0, 0, 0, 6, 6, 5638},
+ {0, 0, 0, 7, 7, 5638},
+ {0, 0, 0, 8, 8, 5638},
+ {0, 0, 0, 9, 9, 5638},
{0, 32, 0, 0, 0, 1921},
{0, 0, 0, 0, 0, 1536},
{65504, 0, 65504, 0, 0, 1801},
{0, 0, 0, 0, 0, 1801},
- {0, 0, 0, 0, 2, 1028},
- {0, 0, 0, 0, 3, 1028},
+ {0, 0, 0, 0, 2, 5124},
+ {0, 0, 0, 0, 3, 5124},
{743, 0, 743, 0, 0, 1801},
- {0, 0, 0, 0, 1, 1028},
+ {0, 0, 0, 0, 1, 5124},
+ {0, 0, 0, 0, 0, 5120},
{121, 0, 121, 0, 0, 1801},
{0, 1, 0, 0, 0, 1921},
{65535, 0, 65535, 0, 0, 1801},
@@ -63,17 +64,20 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 10795, 0, 0, 0, 1921},
{0, 65373, 0, 0, 0, 1921},
{0, 10792, 0, 0, 0, 1921},
+ {10815, 0, 10815, 0, 0, 1801},
{0, 65341, 0, 0, 0, 1921},
{0, 69, 0, 0, 0, 1921},
{0, 71, 0, 0, 0, 1921},
{10783, 0, 10783, 0, 0, 1801},
{10780, 0, 10780, 0, 0, 1801},
+ {10782, 0, 10782, 0, 0, 1801},
{65326, 0, 65326, 0, 0, 1801},
{65330, 0, 65330, 0, 0, 1801},
{65331, 0, 65331, 0, 0, 1801},
{65334, 0, 65334, 0, 0, 1801},
{65333, 0, 65333, 0, 0, 1801},
{65329, 0, 65329, 0, 0, 1801},
+ {42893, 613, 42893, 0, 0, 3849},
{65327, 0, 65327, 0, 0, 1801},
{65325, 0, 65325, 0, 0, 1801},
{10743, 0, 10743, 0, 0, 1801},
@@ -117,16 +121,16 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{65488, 0, 65488, 0, 0, 1801},
{0, 0, 0, 0, 0, 1537},
{0, 7264, 0, 0, 0, 1921},
- {0, 0, 0, 0, 1, 1540},
- {0, 0, 0, 0, 2, 1540},
- {0, 0, 0, 0, 3, 1540},
- {0, 0, 0, 0, 4, 1540},
- {0, 0, 0, 0, 5, 1540},
- {0, 0, 0, 0, 6, 1540},
- {0, 0, 0, 0, 7, 1540},
- {0, 0, 0, 0, 8, 1540},
- {0, 0, 0, 0, 9, 1540},
- {0, 0, 0, 0, 0, 1792},
+ {0, 0, 0, 0, 1, 5636},
+ {0, 0, 0, 0, 2, 5636},
+ {0, 0, 0, 0, 3, 5636},
+ {0, 0, 0, 0, 4, 5636},
+ {0, 0, 0, 0, 5, 5636},
+ {0, 0, 0, 0, 6, 5636},
+ {0, 0, 0, 0, 7, 5636},
+ {0, 0, 0, 0, 8, 5636},
+ {0, 0, 0, 0, 9, 5636},
+ {0, 0, 0, 0, 0, 5888},
{42877, 7545, 42877, 0, 0, 3849},
{3814, 0, 3814, 0, 0, 1801},
{65477, 0, 65477, 0, 0, 1801},
@@ -149,20 +153,21 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 65424, 0, 0, 0, 1921},
{0, 65408, 0, 0, 0, 1921},
{0, 65410, 0, 0, 0, 1921},
- {0, 0, 0, 0, 0, 1028},
- {0, 0, 0, 0, 4, 1028},
- {0, 0, 0, 0, 5, 1028},
- {0, 0, 0, 0, 6, 1028},
- {0, 0, 0, 0, 7, 1028},
- {0, 0, 0, 0, 8, 1028},
- {0, 0, 0, 0, 9, 1028},
+ {0, 0, 0, 0, 0, 5124},
+ {0, 0, 0, 0, 4, 5124},
+ {0, 0, 0, 0, 5, 5124},
+ {0, 0, 0, 0, 6, 5124},
+ {0, 0, 0, 0, 7, 5124},
+ {0, 0, 0, 0, 8, 5124},
+ {0, 0, 0, 0, 9, 5124},
+ {0, 0, 0, 0, 0, 1792},
{0, 58019, 0, 0, 0, 1921},
{0, 57153, 0, 0, 0, 1921},
{0, 57274, 0, 0, 0, 1921},
{0, 28, 0, 0, 0, 1921},
{65508, 0, 65508, 0, 0, 1801},
- {0, 16, 0, 0, 0, 1792},
- {65520, 0, 65520, 0, 0, 1792},
+ {0, 16, 0, 0, 0, 5888},
+ {65520, 0, 65520, 0, 0, 5888},
{0, 26, 0, 0, 0, 1024},
{65510, 0, 65510, 0, 0, 1024},
{0, 54793, 0, 0, 0, 1921},
@@ -173,214 +178,525 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
{0, 54756, 0, 0, 0, 1921},
{0, 54787, 0, 0, 0, 1921},
{0, 54753, 0, 0, 0, 1921},
+ {0, 54754, 0, 0, 0, 1921},
+ {0, 54721, 0, 0, 0, 1921},
{58272, 0, 58272, 0, 0, 1801},
+ {0, 0, 0, 0, 0, 5889},
{42877, 7545, 42877, 0, 0, 3969},
+ {42893, 613, 42893, 0, 0, 3969},
{0, 40, 0, 0, 0, 1921},
{65496, 0, 65496, 0, 0, 1801},
};
/* type indexes */
-#define SHIFT 8
+#define SHIFT 7
static unsigned char index1[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 34, 37,
- 38, 34, 34, 34, 39, 40, 41, 42, 43, 44, 45, 46, 34, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 47, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 48, 21, 21, 21, 21, 49,
- 21, 50, 51, 52, 53, 54, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 55, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 21, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 8, 8, 8, 68, 69, 70, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 71, 72, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 73, 74,
- 75, 76, 77, 78, 79, 80, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 81, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 82, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 83, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 84, 85, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 86, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 86,
+ 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, 64, 68, 69, 64, 64, 64, 64, 64, 64, 70, 17, 71, 72, 73, 74, 75,
+ 76, 64, 77, 78, 79, 80, 81, 82, 83, 64, 64, 84, 85, 34, 34, 34, 34, 34,
+ 34, 86, 34, 34, 34, 34, 34, 87, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 88, 89, 90, 91, 34, 34, 34, 92, 34, 34,
+ 34, 93, 94, 34, 34, 34, 34, 34, 95, 34, 34, 34, 96, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 97, 98, 99, 34, 34, 34, 34, 34, 34, 100, 101, 34, 34,
+ 34, 34, 34, 34, 34, 34, 102, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 34, 34, 104, 34, 34, 34, 34,
+ 100, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 103, 34, 34, 34, 34, 34, 34, 105, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 106, 107, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 108, 109, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 110, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 111, 34, 34, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128,
+ 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+ 17, 143, 144, 145, 146, 147, 17, 17, 17, 17, 17, 17, 148, 17, 149, 17,
+ 150, 17, 151, 17, 152, 17, 17, 17, 153, 17, 17, 17, 154, 155, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 156, 17, 157,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 158, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 159, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 160, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 64, 161, 162, 163, 164, 17, 165, 17, 166, 167, 168, 169, 170, 171,
+ 172, 173, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 174, 175, 176,
+ 177, 178, 17, 179, 180, 181, 182, 183, 184, 185, 186, 65, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 187, 188, 189, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 86, 190, 34, 191,
+ 192, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 193, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 194, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 195, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 196, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 197, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 198, 34, 199, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 34, 193, 34, 34, 199, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 200, 17, 201, 202, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 203, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 203,
};
static unsigned char index2[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
@@ -388,455 +704,424 @@ static unsigned char index2[] = {
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5,
5, 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 19, 5, 5,
- 1, 5, 5, 5, 5, 20, 21, 5, 22, 5, 17, 5, 23, 19, 5, 5, 5, 5, 5, 16, 16,
+ 1, 5, 5, 5, 5, 20, 21, 5, 22, 5, 17, 5, 23, 19, 5, 24, 24, 24, 5, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 5, 16, 16, 16, 16, 16, 16, 16, 19, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5,
- 18, 18, 18, 18, 18, 18, 18, 24, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 27, 28, 25, 26, 25, 26, 25, 26, 19, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 29, 25, 26, 25, 26, 25, 26, 30, 31, 32, 25, 26, 25, 26, 33, 25,
- 26, 34, 34, 25, 26, 19, 35, 36, 37, 25, 26, 34, 38, 39, 40, 41, 25, 26,
- 42, 19, 40, 43, 44, 45, 25, 26, 25, 26, 25, 26, 46, 25, 26, 46, 19, 19,
- 25, 26, 46, 25, 26, 47, 47, 25, 26, 25, 26, 48, 25, 26, 19, 49, 25, 26,
- 19, 50, 49, 49, 49, 49, 51, 52, 53, 51, 52, 53, 51, 52, 53, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 54, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 51, 52, 53,
- 25, 26, 55, 56, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 57, 19, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 19, 19, 19, 19, 19, 19, 58, 25,
- 26, 59, 60, 19, 19, 25, 26, 61, 62, 63, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 64, 65, 19, 66, 67, 19, 68, 68, 19, 69, 19, 70, 19, 19, 19, 19,
- 68, 19, 19, 71, 19, 19, 19, 19, 72, 73, 19, 74, 19, 19, 19, 73, 19, 75,
- 76, 19, 19, 77, 19, 19, 19, 19, 19, 19, 19, 78, 19, 19, 79, 19, 19, 79,
- 19, 19, 19, 19, 79, 80, 81, 81, 82, 19, 19, 19, 19, 19, 83, 19, 49, 19,
+ 18, 18, 18, 18, 18, 18, 18, 25, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 28, 29, 26, 27, 26, 27, 26, 27, 19, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 30, 26, 27, 26, 27, 26, 27, 31, 32, 33, 26, 27, 26, 27, 34, 26,
+ 27, 35, 35, 26, 27, 19, 36, 37, 38, 26, 27, 35, 39, 40, 41, 42, 26, 27,
+ 43, 19, 41, 44, 45, 46, 26, 27, 26, 27, 26, 27, 47, 26, 27, 47, 19, 19,
+ 26, 27, 47, 26, 27, 48, 48, 26, 27, 26, 27, 49, 26, 27, 19, 50, 26, 27,
+ 19, 51, 50, 50, 50, 50, 52, 53, 54, 52, 53, 54, 52, 53, 54, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 55, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 52, 53, 54,
+ 26, 27, 56, 57, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 58, 19, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 19, 59, 26,
+ 27, 60, 61, 62, 62, 26, 27, 63, 64, 65, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 66, 67, 68, 69, 70, 19, 71, 71, 19, 72, 19, 73, 19, 19, 19, 19,
+ 71, 19, 19, 74, 19, 75, 19, 19, 76, 77, 19, 78, 19, 19, 19, 77, 19, 79,
+ 80, 19, 19, 81, 19, 19, 19, 19, 19, 19, 19, 82, 19, 19, 83, 19, 19, 83,
+ 19, 19, 19, 19, 83, 84, 85, 85, 86, 19, 19, 19, 19, 19, 87, 19, 50, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49,
- 49, 49, 5, 5, 5, 5, 5, 5, 5, 49, 5, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50,
+ 50, 50, 5, 5, 5, 5, 5, 5, 5, 50, 5, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 84, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 88, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 25, 26, 25, 26, 49, 5, 25, 26, 0, 0, 85,
- 44, 44, 44, 5, 0, 0, 0, 0, 0, 5, 5, 86, 17, 87, 87, 87, 0, 88, 0, 89, 89,
+ 17, 17, 17, 17, 17, 17, 17, 17, 26, 27, 26, 27, 50, 5, 26, 27, 0, 0, 89,
+ 45, 45, 45, 5, 0, 0, 0, 0, 0, 5, 5, 90, 17, 91, 91, 91, 0, 92, 0, 93, 93,
19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 90, 91, 91, 91, 19, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 92, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 93, 94, 94, 95, 96, 97, 98, 98, 98, 99, 100, 101,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 102, 103, 104, 19, 105, 106, 5, 25, 26, 107, 25,
- 26, 19, 57, 57, 57, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 94, 95, 95, 95, 19, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 96, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 97, 98, 98, 99, 100, 101, 102, 102, 102, 103,
+ 104, 105, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 106, 107, 108, 19, 109, 110, 5, 26, 27,
+ 111, 26, 27, 19, 58, 58, 58, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 103,
- 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
- 103, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 5,
- 17, 17, 17, 17, 17, 5, 5, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 109, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 110, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 0, 0, 49, 5, 5, 5, 5, 5, 5, 0, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0, 0,
- 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 5, 5,
+ 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 5, 17, 17, 17, 17, 17, 5, 5, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 113, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 114, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 0, 0, 50, 5, 5, 5, 5, 5, 5, 0, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 19, 0, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 5, 17, 5, 17, 17, 5, 17, 17, 5, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 0, 0, 5, 5, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5,
- 5, 5, 5, 49, 49, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 49, 17, 17,
- 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 49, 49, 17, 17, 5, 17,
- 17, 17, 17, 49, 49, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 5, 5,
- 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 49, 17, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 49, 49, 5, 5, 5, 5, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 49, 17, 17, 17, 17, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 5, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 5, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 0,
- 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 0, 0, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 0, 0, 0, 49, 49, 49,
- 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17,
- 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 49, 49, 0, 49, 49, 49,
- 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 0,
- 0, 0, 0, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0,
- 49, 49, 0, 49, 49, 0, 49, 49, 0, 0, 17, 0, 17, 17, 17, 17, 17, 0, 0, 0,
- 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 49, 49,
- 49, 49, 0, 49, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 17, 17, 49, 49, 49, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0,
- 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 49, 49, 49, 49, 49, 0, 0, 17,
- 49, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 0, 0,
- 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49,
- 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 49, 49,
- 49, 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0,
- 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 49, 49, 0, 49,
- 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 49, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 49, 0, 49, 49, 49, 49, 49, 49,
- 0, 0, 0, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 0, 49, 49, 0, 49, 0, 49,
- 49, 0, 0, 0, 49, 49, 0, 0, 0, 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 17, 17, 17, 17, 17, 0, 0, 0, 17,
- 17, 17, 0, 17, 17, 17, 17, 0, 0, 49, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, 0, 0, 49, 17, 17, 17,
+ 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 0, 0, 5, 5, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 5, 5, 5, 5, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 17,
+ 17, 17, 17, 17, 17, 17, 1, 5, 17, 17, 17, 17, 17, 17, 50, 50, 17, 17, 5,
+ 17, 17, 17, 17, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50,
+ 5, 5, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 1, 50, 17, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 50, 50, 5, 5, 5, 5, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17,
+ 17, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17, 50, 17,
+ 17, 17, 17, 17, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 17, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 50, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 17, 17,
+ 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 5, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 50, 50, 50, 50, 50, 50, 50, 0, 50,
+ 50, 50, 50, 50, 50, 50, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50,
+ 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50,
+ 0, 0, 0, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 0, 0,
+ 17, 17, 0, 0, 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 50,
+ 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50,
+ 50, 5, 5, 24, 24, 24, 24, 24, 24, 5, 5, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50,
+ 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50,
+ 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 0, 50, 50, 0, 0, 17, 0, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 17, 17, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50,
+ 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0,
+ 17, 17, 17, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50,
+ 50, 50, 0, 0, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50,
+ 50, 0, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17, 17, 17,
+ 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,
+ 0, 0, 0, 0, 50, 50, 0, 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 5, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 50, 0, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 0, 50, 50, 50,
+ 50, 0, 0, 0, 50, 50, 0, 50, 0, 50, 50, 0, 0, 0, 50, 50, 0, 0, 0, 50, 50,
+ 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 0, 0, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 50, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50,
+ 50, 50, 50, 0, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0,
+ 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 50, 50, 0, 0, 0, 0, 0, 0,
+ 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0,
+ 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 5, 0, 0, 17, 17, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 0, 17, 50, 17, 17, 17,
17, 17, 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0,
- 17, 17, 0, 49, 49, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5,
- 0, 0, 17, 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49,
- 49, 49, 0, 0, 17, 49, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17,
- 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 49, 0, 49,
- 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 5, 5, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 17, 17, 17, 17, 17,
- 17, 17, 0, 17, 17, 17, 0, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,
- 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 49, 49, 49, 49, 49, 49, 0, 0, 17,
- 17, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 17, 0, 0, 0, 0,
- 17, 17, 17, 17, 17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17,
- 49, 113, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 5, 49, 49, 49, 49, 49,
- 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 0, 49, 0, 0,
- 49, 49, 0, 49, 0, 0, 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 0, 49, 49, 49,
- 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 0, 49, 0, 0, 49, 49, 0, 49, 49, 49,
- 49, 17, 49, 113, 17, 17, 17, 17, 17, 17, 0, 17, 17, 49, 0, 0, 49, 49, 49,
- 49, 49, 0, 49, 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 0, 0, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5,
- 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 17, 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49,
- 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 5, 17, 17, 49, 49, 49, 49, 0, 0, 0, 0, 17, 17,
- 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5,
- 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17,
- 49, 49, 49, 49, 17, 17, 17, 49, 17, 17, 17, 49, 49, 17, 17, 17, 17, 17,
- 17, 17, 49, 49, 49, 17, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 5, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49,
- 49, 49, 49, 49, 0, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0,
- 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 0,
- 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 115, 116, 117, 118, 119, 120, 121, 122, 123, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 49, 49, 49, 49, 49, 49, 49, 49, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0, 0,
- 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 5, 5, 5, 124, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49,
- 49, 49, 49, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 5, 5,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 0, 17,
- 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 5, 5, 5, 49, 5, 5, 5, 5, 49, 17, 0, 0, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
- 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0,
- 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 49, 49, 49,
- 49, 49, 49, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17,
- 17, 17, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 0, 0, 0, 17, 17, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 49, 49, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 0, 0, 0, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 0, 0, 0, 49, 49, 49, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 17, 17, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 0, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 0, 50, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 0, 17,
+ 17, 17, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24,
+ 24, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17,
+ 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 50, 117, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17,
+ 17, 17, 17, 17, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 0,
+ 50, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 50, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 50, 50, 50, 17, 50, 117,
+ 17, 17, 17, 17, 17, 17, 0, 17, 17, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50,
+ 0, 17, 17, 17, 17, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
+ 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 17,
+ 5, 17, 5, 17, 5, 5, 5, 5, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0,
+ 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 5, 17, 17, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 0, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 50, 50,
+ 50, 50, 17, 17, 17, 50, 17, 17, 17, 50, 50, 17, 17, 17, 17, 17, 17, 17,
+ 50, 50, 50, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 17, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 17, 5, 5, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
+ 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 5, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50,
+ 50, 50, 50, 50, 50, 0, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50,
+ 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 119, 120, 121, 122, 123, 124, 125, 126, 127, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 5, 5, 5, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50,
+ 50, 50, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 5, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 0, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 5, 5, 5, 50, 5, 5, 5, 5, 50, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0,
+ 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 2, 0, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 17, 50, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 119, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 17, 17, 17, 17, 17, 0, 0, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
+ 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 50, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 17, 17, 17,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
+ 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 5, 5, 5, 5,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 50, 50, 50, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 5, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 17, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 125,
- 19, 19, 19, 126, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 17, 17, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 19, 19, 19, 19, 19, 127, 19, 19, 128, 19,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130,
- 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, 0, 0, 130,
- 130, 130, 130, 130, 130, 0, 0, 129, 129, 129, 129, 129, 129, 129, 129,
- 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129,
- 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129,
- 129, 129, 0, 0, 130, 130, 130, 130, 130, 130, 0, 0, 19, 129, 19, 129, 19,
- 129, 19, 129, 0, 130, 0, 130, 0, 130, 0, 130, 129, 129, 129, 129, 129,
- 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 132,
- 132, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 0, 0, 129, 129,
- 129, 129, 129, 129, 129, 129, 137, 137, 137, 137, 137, 137, 137, 137,
- 129, 129, 129, 129, 129, 129, 129, 129, 137, 137, 137, 137, 137, 137,
- 137, 137, 129, 129, 129, 129, 129, 129, 129, 129, 137, 137, 137, 137,
- 137, 137, 137, 137, 129, 129, 19, 138, 19, 0, 19, 19, 130, 130, 139, 139,
- 140, 5, 141, 5, 5, 5, 19, 138, 19, 0, 19, 19, 142, 142, 142, 142, 140, 5,
- 5, 5, 129, 129, 19, 19, 0, 0, 19, 19, 130, 130, 143, 143, 0, 5, 5, 5,
- 129, 129, 19, 19, 19, 104, 19, 19, 130, 130, 144, 144, 107, 5, 5, 5, 0,
- 0, 19, 138, 19, 0, 19, 19, 145, 145, 146, 146, 140, 5, 5, 0, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 147, 19, 0, 0, 148, 149, 150, 151,
- 152, 153, 5, 5, 5, 5, 5, 19, 147, 23, 20, 21, 148, 149, 150, 151, 152,
- 153, 5, 5, 5, 5, 5, 0, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 17, 5,
- 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 98, 5, 5, 5, 5, 98, 5, 5, 19, 98, 98,
- 98, 19, 19, 98, 98, 98, 19, 5, 98, 5, 5, 124, 98, 98, 98, 98, 98, 5, 5,
- 5, 5, 5, 5, 98, 5, 154, 5, 98, 5, 155, 156, 98, 98, 124, 19, 98, 98, 157,
- 98, 19, 49, 49, 49, 49, 19, 5, 5, 19, 19, 98, 98, 5, 5, 5, 5, 5, 98, 19,
- 19, 19, 19, 5, 5, 5, 5, 158, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
- 160, 160, 160, 160, 160, 124, 124, 124, 25, 26, 124, 124, 124, 124, 0, 0,
- 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 129,
+ 19, 19, 19, 130, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 19, 19, 19, 131, 19, 19, 132,
+ 19, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 133, 133, 133, 133, 133, 133, 133, 133, 134,
+ 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 0, 0,
+ 134, 134, 134, 134, 134, 134, 0, 0, 133, 133, 133, 133, 133, 133, 133,
+ 133, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133,
+ 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133,
+ 133, 133, 133, 0, 0, 134, 134, 134, 134, 134, 134, 0, 0, 19, 133, 19,
+ 133, 19, 133, 19, 133, 0, 134, 0, 134, 0, 134, 0, 134, 133, 133, 133,
+ 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135, 136, 136, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 0, 0,
+ 133, 133, 133, 133, 133, 133, 133, 133, 141, 141, 141, 141, 141, 141,
+ 141, 141, 133, 133, 133, 133, 133, 133, 133, 133, 141, 141, 141, 141,
+ 141, 141, 141, 141, 133, 133, 133, 133, 133, 133, 133, 133, 141, 141,
+ 141, 141, 141, 141, 141, 141, 133, 133, 19, 142, 19, 0, 19, 19, 134, 134,
+ 143, 143, 144, 5, 145, 5, 5, 5, 19, 142, 19, 0, 19, 19, 146, 146, 146,
+ 146, 144, 5, 5, 5, 133, 133, 19, 19, 0, 0, 19, 19, 134, 134, 147, 147, 0,
+ 5, 5, 5, 133, 133, 19, 19, 19, 108, 19, 19, 134, 134, 148, 148, 111, 5,
+ 5, 5, 0, 0, 19, 142, 19, 0, 19, 19, 149, 149, 150, 150, 144, 5, 5, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 1, 1, 1, 1, 1, 2, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 151, 50, 0, 0, 152, 153,
+ 154, 155, 156, 157, 5, 5, 5, 5, 5, 50, 151, 23, 20, 21, 152, 153, 154,
+ 155, 156, 157, 5, 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 5, 5, 5, 5, 17, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 102, 5, 5, 5, 5, 102,
+ 5, 5, 19, 102, 102, 102, 19, 19, 102, 102, 102, 19, 5, 102, 5, 5, 158,
+ 102, 102, 102, 102, 102, 5, 5, 5, 5, 5, 5, 102, 5, 159, 5, 102, 5, 160,
+ 161, 102, 102, 158, 19, 102, 102, 162, 102, 19, 50, 50, 50, 50, 19, 5, 5,
+ 19, 19, 102, 102, 5, 5, 5, 5, 5, 102, 19, 19, 19, 19, 5, 5, 5, 5, 163, 5,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+ 165, 165, 128, 128, 128, 26, 27, 128, 128, 128, 128, 24, 0, 0, 0, 0, 0,
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -850,86 +1135,70 @@ static unsigned char index2[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 152, 153, 154, 155,
+ 156, 157, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 20, 21, 152,
+ 153, 154, 155, 156, 157, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 161, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 147, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 20, 21, 148, 149, 150,
- 151, 152, 153, 5, 147, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+ 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 167, 167,
+ 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+ 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 151, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24,
+ 151, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23,
+ 20, 21, 152, 153, 154, 155, 156, 157, 24, 23, 20, 21, 152, 153, 154, 155,
+ 156, 157, 24, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5,
+ 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 0, 5, 0, 5, 5, 5, 5, 0, 0, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 20,
- 21, 148, 149, 150, 151, 152, 153, 5, 23, 20, 21, 148, 149, 150, 151, 152,
- 153, 5, 23, 20, 21, 148, 149, 150, 151, 152, 153, 5, 5, 0, 0, 0, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 0, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 0, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 112, 112, 0, 25, 26, 163, 164, 165, 166,
- 167, 25, 26, 25, 26, 25, 26, 168, 169, 170, 0, 19, 25, 26, 19, 25, 26,
- 19, 19, 19, 19, 19, 19, 49, 0, 0, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 19, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,
- 5, 5, 5, 5, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,
- 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49,
- 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49,
- 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49,
- 49, 49, 49, 49, 49, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
+ 116, 116, 116, 116, 116, 0, 26, 27, 168, 169, 170, 171, 172, 26, 27, 26,
+ 27, 26, 27, 173, 174, 175, 176, 19, 26, 27, 19, 26, 27, 19, 19, 19, 19,
+ 19, 19, 50, 177, 177, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 5, 5, 5,
+ 5, 5, 5, 26, 27, 26, 27, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 24,
+ 5, 5, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+ 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+ 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50,
+ 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50,
+ 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50,
+ 50, 50, 50, 50, 50, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 85, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 89, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -941,524 +1210,818 @@ static unsigned char index2[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
+ 0, 0, 2, 5, 5, 5, 5, 50, 50, 128, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 17, 17, 17, 17, 17, 17, 5, 50, 50, 50, 50, 50, 5, 5, 128, 128,
+ 128, 50, 50, 5, 5, 5, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 0, 0, 17, 17, 5, 5, 50, 50, 50, 5, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 5, 24, 24, 24, 24,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0,
+ 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 0, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 179, 50, 50, 179,
+ 50, 50, 50, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50,
+ 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 179, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 179, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 179,
+ 179, 179, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 179, 179, 179, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 179, 179, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 49, 49, 124, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, 17, 5, 49, 49, 49,
- 49, 49, 5, 5, 124, 124, 124, 49, 49, 5, 5, 5, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 17, 17, 5, 5, 49, 49, 49, 5, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5,
- 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 49, 17, 5, 5, 5, 5, 0, 0,
- 0, 0, 0, 0, 0, 0, 17, 17, 5, 49, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26,
- 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 19, 19, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 25, 26, 49,
- 19, 19, 19, 19, 19, 19, 19, 19, 25, 26, 25, 26, 172, 25, 26, 25, 26, 25,
- 26, 25, 26, 25, 26, 49, 5, 5, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 49, 49, 49, 49, 49, 49, 49, 17, 49, 49, 49, 17, 49, 49, 49, 49, 17,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17,
- 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 17, 49, 49, 49, 49, 49, 49,
- 49, 49, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5, 5,
- 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 50, 17, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 5, 50, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26,
+ 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 17, 17, 5, 5, 5, 5, 5, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 19, 19, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 50, 19, 19, 19, 19, 19, 19, 19, 19, 26, 27, 26, 27, 180, 26, 27,
+ 26, 27, 26, 27, 26, 27, 26, 27, 50, 5, 5, 26, 27, 181, 19, 0, 26, 27, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 26, 27, 26, 27, 26, 27,
+ 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 50, 50, 50, 50, 50, 50, 50, 17, 50, 50,
+ 50, 17, 50, 50, 50, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 5, 5,
+ 5, 5, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 5,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 0, 0, 0,
+ 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 17, 17, 17, 17,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 50,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 17, 50, 50, 50, 50, 50,
+ 50, 50, 50, 17, 17, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 5, 5,
+ 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 5, 5, 5, 50, 17, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 17, 50, 17, 17, 17, 50, 50, 17, 17, 50, 50,
+ 50, 50, 50, 17, 17, 50, 17, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50,
+ 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 5, 17, 17, 0, 0,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19,
- 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19,
- 19, 0, 0, 0, 0, 0, 49, 17, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0,
- 49, 0, 49, 49, 0, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 85, 85, 85, 85, 85, 85, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 5, 5, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 85, 85, 5, 5, 0, 0, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 5, 5, 5, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 17, 17, 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 85, 49, 85, 49, 85, 0,
- 85, 49, 85, 49, 85, 49, 85, 49, 85, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 1, 0, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5,
- 5, 5, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 5, 5, 5, 5, 17, 5, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 113, 113, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 0, 0, 49,
- 49, 49, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 5, 5, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0,
- 0, 0, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 5, 5, 5, 5, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 124, 49, 49, 49, 49, 49, 49, 49, 49, 124, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 5, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0,
- 49, 49, 49, 49, 49, 49, 49, 49, 5, 124, 124, 124, 124, 124, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
- 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 174, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49,
- 49, 0, 0, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 0, 0, 0, 49,
- 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 179, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0,
+ 0, 50, 17, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 0, 50, 0, 50, 50,
+ 0, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 89, 89, 89, 89, 89, 89, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 89, 89, 5, 5, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 17, 17, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17,
+ 17, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 5, 5, 5, 5, 0, 0, 0, 0, 89, 50, 89, 50, 89, 0, 89, 50, 89, 50, 89, 50,
+ 89, 50, 89, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 0, 0, 1, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 5, 5, 5, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 117, 117, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50,
+ 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 5,
+ 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 5, 5, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0,
+ 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 24, 24, 24, 24, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 0, 0, 0, 0, 0, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 0, 0, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 24, 24, 24, 24, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 128, 50, 50, 50, 50, 50, 50, 50, 50, 128, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 5, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0,
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 5, 128, 128, 128, 128, 128, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, 183, 183,
+ 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
+ 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
+ 183, 183, 183, 183, 183, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50,
+ 50, 50, 0, 0, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 0, 0, 0,
+ 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 5, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 24, 24, 24, 24, 0, 0, 0, 5, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0,
- 17, 17, 17, 17, 49, 49, 49, 49, 0, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 148, 5,
- 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 50, 17, 17, 17, 0, 17, 17, 0, 0, 0, 0, 0, 17, 17,
+ 17, 17, 50, 50, 50, 50, 0, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 17, 23, 20, 21, 152, 24, 24, 24,
+ 24, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0,
+ 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 24, 24, 5, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 5,
+ 5, 5, 5, 5, 5, 5, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0,
+ 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 17, 17, 17,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5,
+ 5, 0, 0, 0, 0, 23, 20, 21, 152, 153, 154, 155, 156, 157, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 1, 5,
+ 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 158, 158, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 158, 158, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5,
+ 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17,
+ 5, 5, 5, 17, 17, 17, 17, 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17,
+ 17, 17, 17, 17, 5, 5, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17,
+ 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 5, 5, 5, 17, 17, 17, 17,
- 17, 17, 1, 1, 1, 1, 1, 1, 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 17,
- 17, 17, 17, 17, 17, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 5, 5, 5, 5, 5,
+ 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 17,
- 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 5, 5, 5, 5, 5, 17, 17, 17, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19,
- 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 0,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 98, 0, 98, 98, 0, 0, 98, 0, 0, 98, 98, 0, 0, 98, 98, 98,
- 98, 0, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 0, 19, 0, 19, 19,
- 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 0,
- 98, 98, 98, 98, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 0, 98, 98, 98, 98,
- 98, 98, 98, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 0, 98, 98, 98,
- 98, 0, 98, 98, 98, 98, 98, 0, 98, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 0,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19,
+ 19, 19, 19, 19, 19, 102, 0, 102, 102, 0, 0, 102, 0, 0, 102, 102, 0, 0,
+ 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19,
+ 19, 19, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 0, 102, 102, 102, 102,
+ 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102,
+ 102, 102, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 0, 102, 102, 102,
+ 102, 0, 102, 102, 102, 102, 102, 0, 102, 0, 0, 0, 102, 102, 102, 102,
+ 102, 102, 102, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19,
+ 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19,
+ 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19,
- 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19,
+ 19, 19, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 5, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 5, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 98, 98, 98,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19,
- 19, 98, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5, 5, 5, 5, 5, 5,
+ 19, 19, 19, 19, 19, 5, 19, 19, 19, 19, 19, 19, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+ 102, 102, 102, 102, 102, 102, 5, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 19, 19,
+ 19, 19, 19, 19, 102, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, 151, 23, 20, 21, 152, 153,
+ 154, 155, 156, 157, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 0, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 0, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 0, 5, 0, 5, 0, 5, 0, 5,
+ 5, 5, 0, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 5, 0, 0, 5, 5, 5, 5, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179,
+ 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 179, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 179, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17,
+ 1, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
@@ -1471,18 +2034,1376 @@ static unsigned char index2[] = {
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 17, 17, 17, 17, 17, 17, 17, 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, 0, 0,
+ 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_UCS4 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:
+ case 0x1018A:
+ case 0x104A0:
+ case 0x11066:
+ case 0x1D7CE:
+ case 0x1D7D8:
+ case 0x1D7E2:
+ case 0x1D7EC:
+ case 0x1D7F6:
+ case 0x1F100:
+ case 0x1F101:
+ 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:
+ 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 0x11052:
+ case 0x11067:
+ 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:
+ return (double) 1.0;
+ case 0x2152:
+ return (double) 1.0/10.0;
+ case 0x09F4:
+ case 0x0B75:
+ case 0xA833:
+ return (double) 1.0/16.0;
+ case 0x00BD:
+ case 0x0B73:
+ case 0x0D74:
+ case 0x0F2A:
+ case 0x2CFD:
+ case 0xA831:
+ case 0x10141:
+ case 0x10175:
+ case 0x10176:
+ case 0x10E7B:
+ return (double) 1.0/2.0;
+ case 0x2153:
+ case 0x10E7D:
+ case 0x1245A:
+ case 0x1245D:
+ return (double) 1.0/3.0;
+ case 0x00BC:
+ case 0x09F7:
+ case 0x0B72:
+ case 0x0D73:
+ case 0xA830:
+ case 0x10140:
+ case 0x10E7C:
+ case 0x12460:
+ case 0x12462:
+ return (double) 1.0/4.0;
+ case 0x2155:
+ return (double) 1.0/5.0;
+ case 0x2159:
+ case 0x12461:
+ return (double) 1.0/6.0;
+ case 0x2150:
+ return (double) 1.0/7.0;
+ case 0x09F5:
+ case 0x0B76:
+ case 0x215B:
+ case 0xA834:
+ case 0x1245F:
+ 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:
+ 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 0x1105B:
+ case 0x1D369:
+ return (double) 10.0;
+ case 0x0BF1:
+ case 0x0D71:
+ case 0x137B:
+ case 0x216D:
+ case 0x217D:
+ case 0x4F70:
+ case 0x767E:
+ case 0x964C:
+ case 0x10119:
+ case 0x1014B:
+ case 0x10152:
+ case 0x1016A:
+ case 0x103D5:
+ case 0x1085D:
+ case 0x10919:
+ case 0x10A46:
+ case 0x10B5E:
+ case 0x10B7E:
+ case 0x10E72:
+ case 0x11064:
+ return (double) 100.0;
+ case 0x0BF2:
+ case 0x0D72:
+ case 0x216F:
+ case 0x217F:
+ case 0x2180:
+ case 0x4EDF:
+ case 0x5343:
+ case 0x9621:
+ case 0x10122:
+ case 0x1014D:
+ case 0x10154:
+ case 0x10171:
+ case 0x1085E:
+ case 0x10A47:
+ case 0x10B5F:
+ case 0x10B7F:
+ case 0x11065:
+ return (double) 1000.0;
+ case 0x137C:
+ case 0x2182:
+ case 0x4E07:
+ case 0x842C:
+ case 0x1012B:
+ case 0x10155:
+ case 0x1085F:
+ 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:
+ 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 0x11053:
+ case 0x11068:
+ 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:
+ return (double) 2.0;
+ case 0x2154:
+ case 0x10177:
+ case 0x10E7E:
+ case 0x1245B:
+ case 0x1245E:
+ 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:
+ case 0x10111:
+ case 0x103D4:
+ case 0x1085C:
+ case 0x10918:
+ case 0x10A45:
+ case 0x10B5D:
+ case 0x10B7D:
+ case 0x10E6A:
+ case 0x1105C:
+ case 0x1D36A:
+ return (double) 20.0;
+ case 0x1011A:
+ case 0x10E73:
+ return (double) 200.0;
+ case 0x10123:
+ return (double) 2000.0;
+ case 0x1012C:
+ return (double) 20000.0;
+ 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:
+ case 0x10109:
+ case 0x104A3:
+ case 0x1085A:
+ case 0x1091B:
+ case 0x10A42:
+ case 0x10B5A:
+ case 0x10B7A:
+ case 0x10E62:
+ case 0x11054:
+ case 0x11069:
+ 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:
+ return (double) 3.0;
+ case 0x09F6:
+ case 0x0B77:
+ case 0xA835:
+ return (double) 3.0/16.0;
+ case 0x0F2B:
+ return (double) 3.0/2.0;
+ case 0x00BE:
+ case 0x09F8:
+ case 0x0B74:
+ case 0x0D75:
+ case 0xA832:
+ case 0x10178:
+ 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:
+ case 0x10112:
+ case 0x10165:
+ case 0x10E6B:
+ case 0x1105D:
+ case 0x1D36B:
+ case 0x20983:
+ return (double) 30.0;
+ case 0x1011B:
+ case 0x1016B:
+ case 0x10E74:
+ return (double) 300.0;
+ case 0x10124:
+ return (double) 3000.0;
+ case 0x1012D:
+ return (double) 30000.0;
+ 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:
+ case 0x1010A:
+ case 0x104A4:
+ case 0x10A43:
+ case 0x10B5B:
+ case 0x10B7B:
+ case 0x10E63:
+ case 0x11055:
+ case 0x1106A:
+ 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:
+ return (double) 4.0;
+ case 0x2158:
+ return (double) 4.0/5.0;
+ case 0x1375:
+ case 0x32B5:
+ case 0x534C:
+ case 0x10113:
+ case 0x10E6C:
+ case 0x1105E:
+ case 0x1D36C:
+ case 0x2098C:
+ case 0x2099C:
+ return (double) 40.0;
+ case 0x1011C:
+ case 0x10E75:
+ return (double) 400.0;
+ case 0x10125:
+ return (double) 4000.0;
+ case 0x1012E:
+ return (double) 40000.0;
+ 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:
+ case 0x1010B:
+ case 0x10143:
+ case 0x10148:
+ case 0x1014F:
+ case 0x1015F:
+ case 0x10173:
+ case 0x10321:
+ case 0x104A5:
+ case 0x10E64:
+ case 0x11056:
+ case 0x1106B:
+ 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:
+ return (double) 5.0;
+ case 0x0F2C:
+ return (double) 5.0/2.0;
+ case 0x215A:
+ case 0x1245C:
+ return (double) 5.0/6.0;
+ case 0x215D:
+ return (double) 5.0/8.0;
+ case 0x1376:
+ case 0x216C:
+ case 0x217C:
+ case 0x2186:
+ case 0x32BF:
+ 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 0x1105F:
+ case 0x1D36D:
+ return (double) 50.0;
+ case 0x216E:
+ case 0x217E:
+ case 0x1011D:
+ case 0x10145:
+ case 0x1014C:
+ case 0x10153:
+ case 0x1016C:
+ case 0x1016D:
+ case 0x1016E:
+ case 0x1016F:
+ case 0x10170:
+ case 0x10E76:
+ return (double) 500.0;
+ case 0x2181:
+ case 0x10126:
+ case 0x10146:
+ case 0x1014E:
+ case 0x10172:
+ return (double) 5000.0;
+ case 0x2187:
+ case 0x1012F:
+ case 0x10147:
+ case 0x10156:
+ 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:
+ case 0x1010C:
+ case 0x104A6:
+ case 0x10E65:
+ case 0x11057:
+ case 0x1106C:
+ 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:
+ return (double) 6.0;
+ case 0x1377:
+ case 0x10115:
+ case 0x10E6E:
+ case 0x11060:
+ case 0x1D36E:
+ return (double) 60.0;
+ case 0x1011E:
+ case 0x10E77:
+ return (double) 600.0;
+ case 0x10127:
+ return (double) 6000.0;
+ case 0x10130:
+ return (double) 60000.0;
+ 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:
+ case 0x1010D:
+ case 0x104A7:
+ case 0x10E66:
+ case 0x11058:
+ case 0x1106D:
+ 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:
+ return (double) 7.0;
+ case 0x0F2D:
+ return (double) 7.0/2.0;
+ case 0x215E:
+ return (double) 7.0/8.0;
+ case 0x1378:
+ case 0x10116:
+ case 0x10E6F:
+ case 0x11061:
+ case 0x1D36F:
+ return (double) 70.0;
+ case 0x1011F:
+ case 0x10E78:
+ return (double) 700.0;
+ case 0x10128:
+ return (double) 7000.0;
+ case 0x10131:
+ return (double) 70000.0;
+ 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:
+ case 0x1010E:
+ case 0x104A8:
+ case 0x10E67:
+ case 0x11059:
+ case 0x1106E:
+ 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:
+ return (double) 8.0;
+ case 0x1379:
+ case 0x10117:
+ case 0x10E70:
+ case 0x11062:
+ case 0x1D370:
+ return (double) 80.0;
+ case 0x10120:
+ case 0x10E79:
+ return (double) 800.0;
+ case 0x10129:
+ return (double) 8000.0;
+ case 0x10132:
+ return (double) 80000.0;
+ 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:
+ case 0x1010F:
+ case 0x104A9:
+ case 0x10E68:
+ case 0x1105A:
+ case 0x1106F:
+ 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:
+ return (double) 9.0;
+ case 0x0F2E:
+ return (double) 9.0/2.0;
+ case 0x137A:
+ case 0x10118:
+ case 0x10341:
+ case 0x10E71:
+ case 0x11063:
+ case 0x1D371:
+ return (double) 90.0;
+ case 0x10121:
+ case 0x1034A:
+ case 0x10E7A:
+ return (double) 900.0;
+ case 0x1012A:
+ return (double) 9000.0;
+ case 0x10133:
+ return (double) 90000.0;
+ }
+ 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_UCS4 ch)
+{
+ 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;
+}
+
+/* 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_UCS4 ch)
+{
+ switch (ch) {
+ case 0x000A:
+ case 0x000B:
+ case 0x000C:
+ case 0x000D:
+ case 0x001C:
+ case 0x001D:
+ case 0x001E:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index f43b68d..13323cf 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -139,7 +139,7 @@ weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
}
-static long
+static Py_hash_t
weakref_hash(PyWeakReference *self)
{
if (self->hash != -1)
@@ -583,7 +583,7 @@ proxy_iternext(PyWeakReference *proxy)
}
-WRAP_METHOD(proxy_bytes, "__bytes__");
+WRAP_METHOD(proxy_bytes, "__bytes__")
static PyMethodDef proxy_methods[] = {